Anonymous avatar Anonymous committed 979cda5

Simplify update function to use keyreplace.

Comments (0)

Files changed (2)

 
 (riaktest@127.0.0.1)8> %% find out what else is in the groceries bucket
 (riaktest@127.0.0.1)8> C:list_keys(groceries).
-{ok,["mine"]}
+{ok,[<<"mine">>]}
 -author('Andy Gross <andy@basho.com>').
 
 -export([fresh/2,update/3,lookup/2,members/1,size/1,nodes/1,
-	 successors/2,successors/3,
-	 predecessors/2,predecessors/3,
-	 contains_name/2,key_of/1,
-	 merge_rings/2]).
+     successors/2,successors/3,
+     predecessors/2,predecessors/3,
+     contains_name/2,key_of/1,
+     merge_rings/2]).
+    
+-export ([update_test/0]).
 
 -define(RINGTOP, trunc(math:pow(2,160)-1)).  % SHA-1 space
+-include_lib("eunit/include/eunit.hrl").
 
 % @type chash() = {NumPartitions, [NodeEntry]}
 %  NumPartitions = integer()
 fresh(NumPartitions, SeedNode) ->
     Inc = ?RINGTOP div NumPartitions,
     {NumPartitions, [{IndexAsInt, SeedNode} ||
-		   IndexAsInt <- lists:seq(0,(?RINGTOP-1),Inc)]}.
+           IndexAsInt <- lists:seq(0,(?RINGTOP-1),Inc)]}.
 
 % @doc Find the Node that owns the partition identified by IndexAsInt.
 % @spec lookup(IndexAsInt :: integer(), CHash :: chash()) -> node()
 contains_name(Name, CHash) ->
     {_NumPartitions, Nodes} = CHash,
     case [X || {_,X} <- Nodes, X == Name] of
-	[] ->
-	    false;
-	_ ->
-	    true
+    [] ->
+        false;
+    _ ->
+        true
     end.
 
 % @doc Make the partition beginning at IndexAsInt owned by Name'd node.
 %                -> chash()
 update(IndexAsInt, Name, CHash) ->
     {NumPartitions, Nodes} = CHash,
-    GapList = [{I,N} || {I,N} <- Nodes, I /= IndexAsInt],
-    {A, B} = lists:partition(fun({K1,_}) -> K1 < IndexAsInt end, GapList),
-    {NumPartitions, A ++ [{IndexAsInt,Name}] ++ B}.
+    NewNodes = lists:keyreplace(IndexAsInt, 1, Nodes, {IndexAsInt, Name}),
+    {NumPartitions, NewNodes}.
 
 % @doc Given an object key, return all NodeEntries in order starting at Index.
 % @spec successors(Index :: index(), CHash :: chash()) -> [NodeEntry]
 % @spec max_n(N :: integer(), CHash :: chash()) -> integer()
 max_n(N, {NumPartitions, _Nodes}) ->
     if
-	N > NumPartitions ->
-	    NumPartitions;
-	true ->
-	    N
+    N > NumPartitions ->
+        NumPartitions;
+    true ->
+        N
     end.    
 
 % @doc Given an object key, return all NodeEntries in order starting at Index.
     {NumPartitions, NodesA} = CHashA,
     {NumPartitions, NodesB} = CHashB,
     {NumPartitions, [{I,randomnode(A,B)} || 
-		   {{I,A},{I,B}} <- lists:zip(NodesA,NodesB)]}.
+           {{I,A},{I,B}} <- lists:zip(NodesA,NodesB)]}.
 
 % @spec randomnode(NodeA :: node(), NodeB :: node()) -> node()
 randomnode(NodeA,NodeA) -> NodeA;
     NumPartitions.
 
 
+update_test() ->
+    Node = 'old@host', NewNode = 'new@host',
+    
+    % Create a fresh ring...
+    CHash = chash:fresh(5, Node),
+    GetNthIndex = fun(N, {_, Nodes}) -> {Index, _} = lists:nth(N, Nodes), Index end,
+    
+    % Test update...
+    FirstIndex = GetNthIndex(1, CHash),
+    ThirdIndex = GetNthIndex(3, CHash),
+    {5, [{_, NewNode}, {_, Node}, {_, Node}, {_, Node}, {_, Node}, {_, Node}]} = update(FirstIndex, NewNode, CHash),
+    {5, [{_, Node}, {_, Node}, {_, NewNode}, {_, Node}, {_, Node}, {_, Node}]} = update(ThirdIndex, NewNode, CHash).
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.