You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2014/08/01 11:11:23 UTC

[37/48] mem3 commit: updated refs/heads/windsor-merge to ff02b9a

Stop donating once the target level is achieved

Also switched to a record accumulator for clarity.

BugzID: 24466


Project: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/commit/5ec7d044
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/tree/5ec7d044
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/diff/5ec7d044

Branch: refs/heads/windsor-merge
Commit: 5ec7d0440ea9b4c63e7b35e365380109a108b0c8
Parents: 51838ca
Author: Adam Kocoloski <ad...@cloudant.com>
Authored: Wed Oct 30 11:53:22 2013 -0400
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 23 18:46:27 2014 +0100

----------------------------------------------------------------------
 src/mem3_rebalance.erl | 48 +++++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/5ec7d044/src/mem3_rebalance.erl
----------------------------------------------------------------------
diff --git a/src/mem3_rebalance.erl b/src/mem3_rebalance.erl
index af050f6..234cad2 100644
--- a/src/mem3_rebalance.erl
+++ b/src/mem3_rebalance.erl
@@ -35,6 +35,14 @@
 
 -include("mem3.hrl").
 
+-record (gacc, {
+    node,
+    targets,
+    moves,
+    limit,
+    target_level
+}).
+
 %% @equiv expand(1000)
 -spec expand() -> [{atom(), #shard{}, node()}].
 expand() ->
@@ -137,11 +145,15 @@ global_expand(TargetNodes0, LocalOps, Limit) ->
             Acc;
         ({Node0, Count}, Acc) ->
             Node = list_to_existing_atom(binary_to_list(Node0)),
-            % Compute the max number of shards to donate.
-            DC0 = erlang:min(Count - TargetLevel, Limit - length(Acc)),
-            InternalAcc0 = {Node, TargetNodes0, Acc, DC0},
+            InternalAcc0 = #gacc{
+                node = Node,
+                targets = TargetNodes0,
+                moves = Acc,
+                limit = erlang:min(Count - TargetLevel, Limit - length(Acc)),
+                target_level = TargetLevel
+            },
             try mem3_shards:fold(fun donate_fold/2, InternalAcc0) of
-                {_, _, Moves, _} ->
+                #gacc{moves = Moves} ->
                     Moves
             catch
                 {complete, Moves} ->
@@ -150,9 +162,15 @@ global_expand(TargetNodes0, LocalOps, Limit) ->
     end,
     lists:foldl(FoldFun, LocalOps, CountByNode).
 
-donate_fold(_Shard, {_, _, Moves, 0}) ->
+donate_fold(_Shard, #gacc{limit = 0, moves = Moves}) ->
     throw({complete, Moves});
-donate_fold(#shard{node = Node} = Shard, {Node, Nodes, Moves, DC}) ->
+donate_fold(#shard{node = Node} = Shard, #gacc{node = Node} = Acc0) ->
+     #gacc{
+        targets = Nodes,
+        moves = Moves,
+        limit = DC,
+        target_level = TargetLevel
+    } = Acc0,
     Zone = mem3:node_info(Node, <<"zone">>),
     Shards = apply_shard_moves(mem3:shards(Shard#shard.dbname), Moves),
     InZone = filter_map_by_zone(shards_by_node(Shards, Nodes), Zone),
@@ -162,21 +180,27 @@ donate_fold(#shard{node = Node} = Shard, {Node, Nodes, Moves, DC}) ->
     end, SortedByCount),
     case {lists:member(Shard, Shards), Candidates} of
         {false, _} ->
-            {Node, Nodes, Moves, DC};
+            Acc0;
         {true, []} ->
-            {Node, Nodes, Moves, DC};
+            Acc0;
         {true, [{Node, _} | _]} ->
-            {Node, Nodes, Moves, DC};
+            Acc0;
         {true, [{Target, _} | _]} ->
             % Execute the move only if the target has fewer shards for this DB
             % than the source. Otherwise we'd generate a local imbalance.
             SourceCount = get_shard_count(Node, SortedByCount),
             TargetCount = get_shard_count(Target, SortedByCount),
-            if TargetCount < SourceCount ->
+            % Execute the move only if the target needs shards.
+            NodeKey = couch_util:to_binary(Target),
+            Total = couch_util:get_value(NodeKey, shard_count_by_node(Moves)),
+            if (TargetCount < SourceCount), (Total < TargetLevel) ->
                 print({move, Shard, Target}),
-                {Node, Nodes, [{move, Shard, Target} | Moves], DC - 1};
+                Acc0#gacc{
+                    moves = [{move, Shard, Target} | Moves],
+                    limit = DC - 1
+                };
             true ->
-                {Node, Nodes, Moves, DC}
+                Acc0
             end
     end;
 donate_fold(_Shard, Acc) ->