You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2014/02/05 00:06:19 UTC

[06/50] couch commit: updated refs/heads/import to c3116d7

Assume success when we replicate an existing leaf

The logic in couch_db:prep_and_validate_replicated_updates/5 was broken
if we attempt to replicate a leaf that exists. The function has
explicitly commented logic that if we attempt to replicate an internal
node of the revision tree that we just ignore it and assume success.
While the logic matched the comment, what the comment should say is that
if we replicate an existing revision then we should treat is as a
successful no-op.

The way that the error manifests with the old logic is that we would try
and run make_first_doc_on_disk which reads through all previous
revisions on the edit path to find the first available revision.
Although if we had compacted then none would exist so that the
make_first_doc_on_disk function would return nil and attempt to use that
where we wanted a #doc{} in couch_doc:merge_stubs/2.

BugzId: 15562


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

Branch: refs/heads/import
Commit: 4cc61f1ba02d87b7190f5c014b93dd21cf5a5503
Parents: 5718463
Author: Paul J. Davis <pa...@gmail.com>
Authored: Tue Nov 13 16:43:32 2012 -0600
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Tue Feb 4 17:03:23 2014 -0600

----------------------------------------------------------------------
 src/couch_db.erl | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/4cc61f1b/src/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_db.erl b/src/couch_db.erl
index 2253e62..67c8a49 100644
--- a/src/couch_db.erl
+++ b/src/couch_db.erl
@@ -682,6 +682,8 @@ prep_and_validate_replicated_updates(Db, [Bucket|RestBuckets], [OldInfo|RestOldI
             {[], AccErrors}, Bucket),
         prep_and_validate_replicated_updates(Db, RestBuckets, RestOldInfo, [ValidatedBucket | AccPrepped], AccErrors3);
     {ok, #full_doc_info{rev_tree=OldTree}} ->
+        OldLeafs = couch_key_tree:get_all_leafs_full(OldTree),
+        OldLeafsLU = [{Start, RevId} || {Start, [{RevId, _}|_]} <- OldLeafs],
         NewRevTree = lists:foldl(
             fun({NewDoc, _Ref}, AccTree) ->
                 {NewTree, _} = couch_key_tree:merge(AccTree,
@@ -694,8 +696,9 @@ prep_and_validate_replicated_updates(Db, [Bucket|RestBuckets], [OldInfo|RestOldI
         {ValidatedBucket, AccErrors3} =
         lists:foldl(
             fun({#doc{id=Id,revs={Pos, [RevId|_]}}=Doc, Ref}, {AccValidated, AccErrors2}) ->
+                IsOldLeaf = lists:member({Pos, RevId}, OldLeafsLU),
                 case dict:find({Pos, RevId}, LeafRevsFullDict) of
-                {ok, {Start, Path}} ->
+                {ok, {Start, Path}} when not IsOldLeaf ->
                     % our unflushed doc is a leaf node. Go back on the path
                     % to find the previous rev that's on disk.