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:12:27 UTC

[39/50] fabric commit: updated refs/heads/windsor-merge-121 to 79e6e2f

Add utility function to find shard replacements

Streaming RPC coordinators can use this function to generate a list of
shard replacements that is suitable to be passed to
fabric_util:stream_start/4.

BugzId: 20423


Project: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/commit/4f639cea
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/tree/4f639cea
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fabric/diff/4f639cea

Branch: refs/heads/windsor-merge-121
Commit: 4f639cead248356f24f1d9f1d95f1fb2dec7630d
Parents: 3523efd
Author: Paul J. Davis <pa...@gmail.com>
Authored: Thu Sep 12 13:30:40 2013 -0500
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Jul 31 16:14:20 2014 +0100

----------------------------------------------------------------------
 src/fabric_view.erl | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fabric/blob/4f639cea/src/fabric_view.erl
----------------------------------------------------------------------
diff --git a/src/fabric_view.erl b/src/fabric_view.erl
index 690625b..7cd5321 100644
--- a/src/fabric_view.erl
+++ b/src/fabric_view.erl
@@ -14,7 +14,8 @@
 
 -export([is_progress_possible/1, remove_overlapping_shards/2, maybe_send_row/1,
     transform_row/1, keydict/1, extract_view/4, get_shards/2,
-    check_down_shards/2, handle_worker_exit/3]).
+    check_down_shards/2, handle_worker_exit/3,
+    get_shard_replacements/2]).
 
 -include_lib("fabric/include/fabric.hrl").
 -include_lib("mem3/include/mem3.hrl").
@@ -305,6 +306,34 @@ get_shards(DbName, #mrargs{stale=Stale})
 get_shards(DbName, #mrargs{stale=false}) ->
     mem3:shards(DbName).
 
+get_shard_replacements(DbName, UsedShards) ->
+    % We only want to generate a replacements list from shards
+    % that aren't already used.
+    AllLiveShards = mem3:live_shards(DbName, [node() | nodes()]),
+    UnusedShards = AllLiveShards -- UsedShards,
+
+    % If we have more than one copy of a range then we don't
+    % want to try and add a replacement to any copy.
+    RangeCounts = lists:foldl(fun(#shard{range=R}, Acc) ->
+        dict:update_counter(R, 1, Acc)
+    end, dict:new(), UsedShards),
+
+    % For each seq shard range with a count of 1, find any
+    % possible replacements from the unused shards. The
+    % replacement list is keyed by range.
+    lists:foldl(fun(#shard{range=Range}, Acc) ->
+        case dict:find(Range, RangeCounts) of
+            {ok, 1} ->
+                Repls = [S || S <- UnusedShards, S#shard.range =:= Range],
+                % Only keep non-empty lists of replacements
+                if Repls == [] -> Acc; true ->
+                    [{Range, Repls} | Acc]
+                end;
+            _ ->
+                Acc
+        end
+    end, [], UsedShards).
+
 % unit test
 is_progress_possible_test() ->
     EndPoint = 2 bsl 31,