couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rnew...@apache.org
Subject [44/50] mem3 commit: updated refs/heads/master to 64c0c74
Date Thu, 28 Aug 2014 12:23:04 GMT
Fast forward internal repl. between file copies

In the case where two files have the same UUID we can analyze epoch
information to determine the safe start sequence.

BugzID: 27753


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

Branch: refs/heads/master
Commit: 866520183220a90f29c74319c7bc548fc9f39d48
Parents: fd3c7b5
Author: Adam Kocoloski <adam@cloudant.com>
Authored: Tue Feb 4 15:44:14 2014 -0500
Committer: Robert Newson <rnewson@apache.org>
Committed: Wed Jul 23 18:51:40 2014 +0100

----------------------------------------------------------------------
 src/mem3_rep.erl | 11 ++++++++++-
 src/mem3_rpc.erl | 45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/86652018/src/mem3_rep.erl
----------------------------------------------------------------------
diff --git a/src/mem3_rep.erl b/src/mem3_rep.erl
index 2186fa3..339bd66 100644
--- a/src/mem3_rep.erl
+++ b/src/mem3_rep.erl
@@ -216,9 +216,18 @@ calculate_start_seq(Acc) ->
             end,
             Acc1#acc{seq = Seq, history = History};
         {not_found, _} ->
-            Acc1
+            compare_epochs(Acc1)
     end.
 
+compare_epochs(Acc) ->
+    #acc{
+        source = Db,
+        target = #shard{node=Node, name=Name}
+    } = Acc,
+    UUID = couch_db:get_uuid(Db),
+    Epochs = couch_db:get_epochs(Db),
+    Seq = mem3_rpc:find_common_seq(Node, Name, UUID, Epochs),
+    Acc#acc{seq = Seq, history = {[]}}.
 
 changes_enumerator(#doc_info{id=DocId}, Reds, #acc{db=Db}=Acc) ->
     {ok, FDI} = couch_db:get_full_doc_info(Db, DocId),

http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/86652018/src/mem3_rpc.erl
----------------------------------------------------------------------
diff --git a/src/mem3_rpc.erl b/src/mem3_rpc.erl
index 10294a7..9507f5b 100644
--- a/src/mem3_rpc.erl
+++ b/src/mem3_rpc.erl
@@ -16,6 +16,7 @@
 
 
 -export([
+    find_common_seq/4,
     get_missing_revs/4,
     update_docs/4,
     load_checkpoint/4,
@@ -24,6 +25,7 @@
 
 % Private RPC callbacks
 -export([
+    find_common_seq_rpc/3,
     load_checkpoint_rpc/3,
     save_checkpoint_rpc/5
 ]).
@@ -54,6 +56,11 @@ save_checkpoint(Node, DbName, DocId, Seq, Entry, History) ->
     rexi_call(Node, {mem3_rpc, save_checkpoint_rpc, Args}).
 
 
+find_common_seq(Node, DbName, SourceUUID, SourceEpochs) ->
+    Args = [DbName, SourceUUID, SourceEpochs],
+    rexi_call(Node, {mem3_rpc, find_common_seq_rpc, Args}).
+
+
 load_checkpoint_rpc(DbName, SourceNode, SourceUUID) ->
     erlang:put(io_priority, {internal_repl, DbName}),
     case couch_db:open_int(DbName, [{user_ctx, ?CTX}]) of
@@ -107,6 +114,44 @@ save_checkpoint_rpc(DbName, Id, SourceSeq, NewEntry0, History0) ->
             rexi:reply(Error)
     end.
 
+find_common_seq_rpc(DbName, SourceUUID, SourceEpochs) ->
+    erlang:put(io_priority, {internal_repl, DbName}),
+    case couch_db:open_int(DbName, [{user_ctx, ?CTX}]) of
+    {ok, Db} ->
+        case couch_db:get_uuid(Db) of
+        SourceUUID ->
+            TargetEpochs = couch_db:get_epochs(Db),
+            Seq = compare_epochs(SourceEpochs, TargetEpochs),
+            rexi:reply({ok, Seq});
+        _Else ->
+            rexi:reply({ok, 0})
+        end;
+    Error ->
+        rexi:reply(Error)
+    end.
+
+
+%% @doc Return the sequence where two files with the same UUID diverged.
+compare_epochs(SourceEpochs, TargetEpochs) ->
+    compare_rev_epochs(
+        lists:reverse(SourceEpochs),
+        lists:reverse(TargetEpochs)
+    ).
+
+
+compare_rev_epochs([{Node, Seq} | SourceRest], [{Node, Seq} | TargetRest]) ->
+    % Common history, fast-forward
+    compare_epochs(SourceRest, TargetRest);
+compare_rev_epochs([], [{_, TargetSeq} | _]) ->
+    % Source has not moved, start from seq just before the target took over
+    TargetSeq - 1;
+compare_rev_epochs([{_, SourceSeq} | _], []) ->
+    % Target has not moved, start from seq where source diverged
+    SourceSeq;
+compare_rev_epochs([{_, SourceSeq} | _], [{_, TargetSeq} | _]) ->
+    % The source was moved to a new location independently, take the minimum
+    erlang:min(SourceSeq, TargetSeq) - 1.
+
 
 %% @doc This adds a new update sequence checkpoint to the replication
 %%      history. Checkpoints are keyed by the source node so that we


Mime
View raw message