Allow target_uuid prefixes in find_source_seq Since sequence values only contain UUID prefixes so we need to account for that when locating the replication checkpoints.
BugId: 21973 Project: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/commit/c63fc057 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/tree/c63fc057 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/diff/c63fc057 Branch: refs/heads/windsor-merge Commit: c63fc057078544290825172790b3c5c871f75037 Parents: bf07a7c Author: Paul J. Davis <paul.joseph.da...@gmail.com> Authored: Fri Dec 6 13:52:28 2013 -0600 Committer: Robert Newson <rnew...@apache.org> Committed: Wed Jul 23 18:50:53 2014 +0100 ---------------------------------------------------------------------- src/mem3_rep.erl | 46 ++++++++++++++++++++++++++++++++++++++++------ src/mem3_rpc.erl | 1 + 2 files changed, 41 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/c63fc057/src/mem3_rep.erl ---------------------------------------------------------------------- diff --git a/src/mem3_rep.erl b/src/mem3_rep.erl index bdc6fa4..2186fa3 100644 --- a/src/mem3_rep.erl +++ b/src/mem3_rep.erl @@ -135,12 +135,10 @@ make_local_id(SourceThing, TargetThing, Filter) -> %% as they've seen updates on this node. We can detect that by %% looking for our push replication history and choosing the %% largest source_seq that has a target_seq =< TgtSeq. -find_source_seq(SrcDb, TgtNode, TgtUUID, TgtSeq) -> - SrcNode = atom_to_binary(node(), utf8), - SrcUUID = couch_db:get_uuid(SrcDb), - DocId = make_local_id(SrcUUID, TgtUUID), - case couch_db:open_doc(SrcDb, DocId, []) of - {ok, Doc} -> +find_source_seq(SrcDb, TgtNode, TgtUUIDPrefix, TgtSeq) -> + case find_repl_doc(SrcDb, TgtUUIDPrefix) of + {ok, TgtUUID, Doc} -> + SrcNode = atom_to_binary(node(), utf8), find_source_seq_int(Doc, SrcNode, TgtNode, TgtUUID, TgtSeq); {not_found, _} -> 0 @@ -302,6 +300,42 @@ update_locals(Acc) -> {ok, _} = couch_db:update_doc(Db, #doc{id = Id, body = NewBody}, []). +find_repl_doc(SrcDb, TgtUUIDPrefix) -> + SrcUUID = couch_db:get_uuid(SrcDb), + S = couch_util:encodeBase64Url(couch_util:md5(term_to_binary(SrcUUID))), + DocIdPrefix = <<"_local/shard-sync-", S/binary, "-">>, + FoldFun = fun({DocId, {Rev0, {BodyProps}}}, _, _) -> + TgtUUID = couch_util:get_value(<<"target_uuid">>, BodyProps, <<>>), + case is_prefix(DocIdPrefix, DocId) of + true -> + case is_prefix(TgtUUIDPrefix, TgtUUID) of + true -> + Rev = list_to_binary(integer_to_list(Rev0)), + Doc = #doc{id=DocId, revs={0, [Rev]}, body={BodyProps}}, + {stop, {TgtUUID, Doc}}; + false -> + {ok, not_found} + end; + _ -> + {stop, not_found} + end + end, + Options = [{start_key, DocIdPrefix}], + case couch_btree:fold(SrcDb#db.local_tree, FoldFun, not_found, Options) of + {ok, _, {TgtUUID, Doc}} -> + {ok, TgtUUID, Doc}; + {ok, _, not_found} -> + {not_found, missing}; + Else -> + twig:log(err, "Error finding replication doc: ~w", [Else]), + {not_found, missing} + end. + + +is_prefix(Prefix, Subject) -> + binary:longest_common_prefix([Prefix, Subject]) == size(Prefix). + + filter_doc(Filter, FullDocInfo) when is_function(Filter) -> try Filter(FullDocInfo) of discard -> discard; http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/c63fc057/src/mem3_rpc.erl ---------------------------------------------------------------------- diff --git a/src/mem3_rpc.erl b/src/mem3_rpc.erl index 1e77b57..8d8c832 100644 --- a/src/mem3_rpc.erl +++ b/src/mem3_rpc.erl @@ -88,6 +88,7 @@ save_checkpoint_rpc(DbName, Id, SourceSeq, NewEntry0, History0) -> ] ++ NewEntry0}, Body = {[ {<<"seq">>, SourceSeq}, + {<<"target_uuid">>, couch_db:get_uuid(Db)}, {<<"history">>, add_checkpoint(NewEntry, History0)} ]}, Doc = #doc{id = Id, body = Body},