You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2019/06/12 17:46:06 UTC

[couchdb] 01/01: Make mem3_rep:go work when target shards are not yet present in shard map

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch missing-target-in-mem3-rep
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 3483662e865c8470e1e429a8ade7a609ef3ec0ba
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Wed Jun 12 13:41:19 2019 -0400

    Make mem3_rep:go work when target shards are not yet present in shard map
    
    Before shard splitting it was possible to replicate shards even if there were
    in the shard map. This commit brings back that behavior.
---
 src/mem3/src/mem3_rep.erl | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/mem3/src/mem3_rep.erl b/src/mem3/src/mem3_rep.erl
index d2edd6c..fd7c680 100644
--- a/src/mem3/src/mem3_rep.erl
+++ b/src/mem3/src/mem3_rep.erl
@@ -743,13 +743,24 @@ sync_security(#shard{} = Source, #{} = Targets) ->
 
 
 targets_map(#shard{name = <<"shards/", _/binary>> = SrcName} = Src,
-        #shard{name = <<"shards/", _/binary>>, node = TgtNode}) ->
+        #shard{name = <<"shards/", _/binary>>, node = TgtNode} = Tgt) ->
     % Parse range from name in case the passed shard is built with a name only
     SrcRange = mem3:range(SrcName),
     Shards0 = mem3:shards(mem3:dbname(SrcName)),
     Shards1 = [S || S <- Shards0, not shard_eq(S, Src)],
     Shards2 = [S || S <- Shards1, check_overlap(SrcRange, TgtNode, S)],
-    maps:from_list([{R, S} || #shard{range = R} = S <- Shards2]);
+    TMap = maps:from_list([{R, S} || #shard{range = R} = S <- Shards2]),
+    case [{R, S} || #shard{range = R} = S <- Shards2] of
+        [] ->
+            % If target map is empty, create a target map with just
+            % that one target. This is to support tooling which may be
+            % moving / copying shards using mem3:go/2,3 before the
+            % shards are present in the shard map
+            #{mem3:range(SrcName) => Tgt};
+        [_ | _] = TMapList->
+            maps:from_list(TMapList)
+    end;
+
 
 targets_map(_Src, Tgt) ->
     #{[0, ?RING_END] => Tgt}.
@@ -876,7 +887,8 @@ targets_map_test_() ->
             target_not_a_shard(),
             source_contained_in_target(),
             multiple_targets(),
-            uneven_overlap()
+            uneven_overlap(),
+            target_not_in_shard_map()
         ]
     }.
 
@@ -968,4 +980,20 @@ uneven_overlap() ->
     end).
 
 
+target_not_in_shard_map() ->
+    ?_test(begin
+        R0f = [16#00000000, 16#ffffffff],
+        Name = <<"shards/00000000-ffffffff/d.1551893552">>,
+        Shards = [
+            #shard{name = Name, node = 'n1', range = R0f},
+            #shard{name = Name, node = 'n2', range = R0f}
+        ],
+        meck:expect(mem3, shards, 1, Shards),
+        Src = #shard{name = Name, node = 'n1'},
+        Tgt = #shard{name = Name, node = 'n3'},
+        Map = targets_map(Src, Tgt),
+        ?assertEqual(1, map_size(Map)),
+        ?assertMatch(#{R0f := #shard{name = Name, node = 'n3'}}, Map)
+    end).
+
 -endif.