You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ko...@apache.org on 2010/12/29 03:42:30 UTC
svn commit: r1053508 - in /couchdb/trunk: src/couchdb/couch_db.erl
src/couchdb/couch_db_updater.erl src/couchdb/couch_key_tree.erl
test/etap/060-kt-merging.t
Author: kocolosk
Date: Wed Dec 29 02:42:29 2010
New Revision: 1053508
URL: http://svn.apache.org/viewvc?rev=1053508&view=rev
Log:
Stem revision trees after merging a path, COUCHDB-968
Modified:
couchdb/trunk/src/couchdb/couch_db.erl
couchdb/trunk/src/couchdb/couch_db_updater.erl
couchdb/trunk/src/couchdb/couch_key_tree.erl
couchdb/trunk/test/etap/060-kt-merging.t
Modified: couchdb/trunk/src/couchdb/couch_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db.erl?rev=1053508&r1=1053507&r2=1053508&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_db.erl Wed Dec 29 02:42:29 2010
@@ -558,7 +558,8 @@ prep_and_validate_replicated_updates(Db,
{ok, #full_doc_info{rev_tree=OldTree}} ->
NewRevTree = lists:foldl(
fun(NewDoc, AccTree) ->
- {NewTree, _} = couch_key_tree:merge(AccTree, couch_doc:to_path(NewDoc)),
+ {NewTree, _} = couch_key_tree:merge(AccTree,
+ couch_doc:to_path(NewDoc), Db#db.revs_limit),
NewTree
end,
OldTree, Bucket),
Modified: couchdb/trunk/src/couchdb/couch_db_updater.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db_updater.erl?rev=1053508&r1=1053507&r2=1053508&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_db_updater.erl (original)
+++ couchdb/trunk/src/couchdb/couch_db_updater.erl Wed Dec 29 02:42:29 2010
@@ -490,10 +490,11 @@ merge_rev_trees(Limit, MergeConflicts, [
[OldDocInfo|RestOldInfo], AccNewInfos, AccRemoveSeqs, AccSeq) ->
#full_doc_info{id=Id,rev_tree=OldTree,deleted=OldDeleted,update_seq=OldSeq}
= OldDocInfo,
- NewRevTree0 = lists:foldl(
+ NewRevTree = lists:foldl(
fun({Client, #doc{revs={Pos,[_Rev|PrevRevs]}}=NewDoc}, AccTree) ->
if not MergeConflicts ->
- case couch_key_tree:merge(AccTree, couch_doc:to_path(NewDoc)) of
+ case couch_key_tree:merge(AccTree, couch_doc:to_path(NewDoc),
+ Limit) of
{_NewTree, conflicts} when (not OldDeleted) ->
send_result(Client, Id, {Pos-1,PrevRevs}, conflict),
AccTree;
@@ -524,7 +525,7 @@ merge_rev_trees(Limit, MergeConflicts, [
NewDoc#doc{revs={OldPos, [OldRev]}}),
NewDoc2 = NewDoc#doc{revs={OldPos + 1, [NewRevId, OldRev]}},
{NewTree2, _} = couch_key_tree:merge(AccTree,
- couch_doc:to_path(NewDoc2)),
+ couch_doc:to_path(NewDoc2), Limit),
% we changed the rev id, this tells the caller we did
send_result(Client, Id, {Pos-1,PrevRevs},
{ok, {OldPos + 1, NewRevId}}),
@@ -538,12 +539,11 @@ merge_rev_trees(Limit, MergeConflicts, [
end;
true ->
{NewTree, _} = couch_key_tree:merge(AccTree,
- couch_doc:to_path(NewDoc)),
+ couch_doc:to_path(NewDoc), Limit),
NewTree
end
end,
OldTree, NewDocs),
- NewRevTree = couch_key_tree:stem(NewRevTree0, Limit),
if NewRevTree == OldTree ->
% nothing changed
merge_rev_trees(Limit, MergeConflicts, RestDocsList, RestOldInfo,
Modified: couchdb/trunk/src/couchdb/couch_key_tree.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_key_tree.erl?rev=1053508&r1=1053507&r2=1053508&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_key_tree.erl (original)
+++ couchdb/trunk/src/couchdb/couch_key_tree.erl Wed Dec 29 02:42:29 2010
@@ -12,12 +12,18 @@
-module(couch_key_tree).
--export([merge/2, find_missing/2, get_key_leafs/2, get_full_key_paths/2, get/2]).
+-export([merge/3, find_missing/2, get_key_leafs/2, get_full_key_paths/2, get/2]).
-export([map/2, get_all_leafs/1, count_leafs/1, remove_leafs/2,
get_all_leafs_full/1,stem/2,map_leafs/2]).
-include("couch_db.hrl").
+-spec merge([path()], path(), pos_integer()) -> {[path()],
+ conflicts | no_conflicts}.
+merge(Paths, Path, Depth) ->
+ {Merged, Conflicts} = merge(Paths, Path),
+ {stem(Merged, Depth), Conflicts}.
+
-spec merge([path()], path()) -> {[path()], conflicts | no_conflicts}.
merge(Paths, Path) ->
{ok, Merged, HasConflicts} = merge_one(Paths, Path, [], false),
Modified: couchdb/trunk/test/etap/060-kt-merging.t
URL: http://svn.apache.org/viewvc/couchdb/trunk/test/etap/060-kt-merging.t?rev=1053508&r1=1053507&r2=1053508&view=diff
==============================================================================
--- couchdb/trunk/test/etap/060-kt-merging.t (original)
+++ couchdb/trunk/test/etap/060-kt-merging.t Wed Dec 29 02:42:29 2010
@@ -15,7 +15,7 @@
main(_) ->
test_util:init_code_path(),
- etap:plan(14),
+ etap:plan(12),
case (catch test()) of
ok ->
etap:end_tests();
@@ -42,77 +42,74 @@ test() ->
etap:is(
{[One], no_conflicts},
- couch_key_tree:merge([], One),
+ couch_key_tree:merge([], One, 10),
"The empty tree is the identity for merge."
),
etap:is(
{TwoSibs, no_conflicts},
- couch_key_tree:merge(TwoSibs, One),
+ couch_key_tree:merge(TwoSibs, One, 10),
"Merging a prefix of a tree with the tree yields the tree."
),
etap:is(
{[One], no_conflicts},
- couch_key_tree:merge([One], One),
+ couch_key_tree:merge([One], One, 10),
"Merging is reflexive."
),
etap:is(
{[TwoChild], no_conflicts},
- couch_key_tree:merge([TwoChild], TwoChild),
+ couch_key_tree:merge([TwoChild], TwoChild, 10),
"Merging two children is still reflexive."
),
etap:is(
{[TwoChildSibs], no_conflicts},
- couch_key_tree:merge([TwoChildSibs], TwoChildSibs),
+ couch_key_tree:merge([TwoChildSibs], TwoChildSibs, 10),
"Merging a tree to itself is itself."),
etap:is(
{[TwoChildSibs], no_conflicts},
- couch_key_tree:merge([TwoChildSibs], Stemmed1b),
+ couch_key_tree:merge([TwoChildSibs], Stemmed1b, 10),
"Merging a tree with a stem."
),
etap:is(
{[TwoChildSibs2], no_conflicts},
- couch_key_tree:merge([TwoChildSibs2], Stemmed1bb),
+ couch_key_tree:merge([TwoChildSibs2], Stemmed1bb, 10),
"Merging a stem at a deeper level."
),
etap:is(
{[TwoChild], no_conflicts},
- couch_key_tree:merge([TwoChild], Stemmed1aa),
+ couch_key_tree:merge([TwoChild], Stemmed1aa, 10),
"Merging a single tree with a deeper stem."
),
etap:is(
{[TwoChild], no_conflicts},
- couch_key_tree:merge([TwoChild], Stemmed1a),
+ couch_key_tree:merge([TwoChild], Stemmed1a, 10),
"Merging a larger stem."
),
etap:is(
{[Stemmed1a], no_conflicts},
- couch_key_tree:merge([Stemmed1a], Stemmed1aa),
+ couch_key_tree:merge([Stemmed1a], Stemmed1aa, 10),
"More merging."
),
Expect1 = [OneChild, Stemmed1aa],
etap:is(
{Expect1, conflicts},
- couch_key_tree:merge([OneChild], Stemmed1aa),
+ couch_key_tree:merge([OneChild], Stemmed1aa, 10),
"Merging should create conflicts."
),
- {MultiPaths, NoConflicts} = couch_key_tree:merge(Expect1, TwoChild),
- etap:is(NoConflicts, no_conflicts, "Merge should have no conflicts."),
- etap:is(length(MultiPaths), 2, "Should have two paths before stemming."),
- etap:is(
- couch_key_tree:stem(MultiPaths, 10),
- [TwoChild],
- "Stemming should collapse the paths."
+ etap:is(
+ {[TwoChild], no_conflicts},
+ couch_key_tree:merge(Expect1, TwoChild, 10),
+ "Merge should have no conflicts."
),
ok.