summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2013-11-15 12:13:17 -0600
committerRobert Newson <rnewson@apache.org>2014-08-06 19:29:59 +0100
commit5b1f7cea04b08fea12364acae72a9898d45212d6 (patch)
tree213cfc878406ee5c9c2b359bd78a2f96b31cbe1a
parent699ad9c143fee85ca3cc97518f6bccda304b7310 (diff)
downloadcouchdb-5b1f7cea04b08fea12364acae72a9898d45212d6.tar.gz
Be more specific on the merge result
We have three results that can happen when merging a path into a revision tree: * We can extend a branch which replaces a leaf * We can create a new branch which results in a new leaf * We can land on an existing internal node The first result (new_leaf) means that there is no conflict in the update operation. The second (new_branch) means we branched a revision path which means the operation introduces a conflict. The third (internal_node) means that the merge was the result of an edit that has already been applied to this document. For the third case we have a subtle special case in that if we have deleted the document and want to recreate it into the same initial state we need to give the new state a different revision. The current code follows the edit path and extends the first deleted leaf it finds. BugzID: 25150 Conflicts: apps/couch/src/couch_key_tree.erl
-rwxr-xr-xtest/etap/060-kt-merging.t53
1 files changed, 26 insertions, 27 deletions
diff --git a/test/etap/060-kt-merging.t b/test/etap/060-kt-merging.t
index efbdbf695..e0b1a9c36 100755
--- a/test/etap/060-kt-merging.t
+++ b/test/etap/060-kt-merging.t
@@ -29,12 +29,12 @@ test() ->
One = {1, {"1","foo",[]}},
etap:is(
- {[One], no_conflicts},
+ {[One], new_leaf},
couch_key_tree:merge([], One, 10),
"The empty tree is the identity for merge."
),
etap:is(
- {[One], no_conflicts},
+ {[One], internal_node},
couch_key_tree:merge([One], One, 10),
"Merging is reflexive."
),
@@ -43,7 +43,7 @@ test() ->
{1, {"2","foo",[]}}],
etap:is(
- {TwoSibs, no_conflicts},
+ {TwoSibs, internal_node},
couch_key_tree:merge(TwoSibs, One, 10),
"Merging a prefix of a tree with the tree yields the tree."
),
@@ -54,7 +54,7 @@ test() ->
{1, {"3","foo",[]}}],
etap:is(
- {ThreeSibs, conflicts},
+ {ThreeSibs, new_branch},
couch_key_tree:merge(TwoSibs, Three, 10),
"Merging a third unrelated branch leads to a conflict."
),
@@ -63,30 +63,17 @@ test() ->
TwoChild = {1, {"1","foo", [{"1a", "bar", [{"1aa", "bar", []}]}]}},
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], internal_node},
couch_key_tree:merge([TwoChild], TwoChild, 10),
"Merging two children is still reflexive."
),
TwoChildSibs = {1, {"1","foo", [{"1a", "bar", []},
{"1b", "bar", []}]}},
- etap:is(
- {[TwoChildSibs], no_conflicts},
- couch_key_tree:merge([TwoChildSibs], TwoChildSibs, 10),
- "Merging a tree to itself is itself."),
-
- TwoChildPlusSibs =
- {1, {"1","foo", [{"1a", "bar", [{"1aa", "bar", []}]},
- {"1b", "bar", []}]}},
-
- etap:is(
- {[TwoChildPlusSibs], no_conflicts},
- couch_key_tree:merge([TwoChild], TwoChildSibs, 10),
- "Merging tree of uneven length at node 2."),
Stemmed1b = {2, {"1a", "bar", []}},
etap:is(
- {[TwoChildSibs], no_conflicts},
+ {[TwoChildSibs], internal_node},
couch_key_tree:merge([TwoChildSibs], Stemmed1b, 10),
"Merging a tree with a stem."
),
@@ -95,7 +82,7 @@ test() ->
{"1b", "bar", [{"1bb", "boo", []}]}]}},
Stemmed1bb = {3, {"1bb", "boo", []}},
etap:is(
- {[TwoChildSibs2], no_conflicts},
+ {[TwoChildSibs2], internal_node},
couch_key_tree:merge([TwoChildSibs2], Stemmed1bb, 10),
"Merging a stem at a deeper level."
),
@@ -104,27 +91,27 @@ test() ->
{2,{"1b", "bar", [{"1bb", "boo", []}]}}],
etap:is(
- {StemmedTwoChildSibs2, no_conflicts},
+ {StemmedTwoChildSibs2, internal_node},
couch_key_tree:merge(StemmedTwoChildSibs2, Stemmed1bb, 10),
"Merging a stem at a deeper level against paths at deeper levels."
),
Stemmed1aa = {3, {"1aa", "bar", []}},
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], internal_node},
couch_key_tree:merge([TwoChild], Stemmed1aa, 10),
"Merging a single tree with a deeper stem."
),
Stemmed1a = {2, {"1a", "bar", [{"1aa", "bar", []}]}},
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], internal_node},
couch_key_tree:merge([TwoChild], Stemmed1a, 10),
"Merging a larger stem."
),
etap:is(
- {[Stemmed1a], no_conflicts},
+ {[Stemmed1a], internal_node},
couch_key_tree:merge([Stemmed1a], Stemmed1aa, 10),
"More merging."
),
@@ -132,13 +119,13 @@ test() ->
OneChild = {1, {"1","foo",[{"1a", "bar", []}]}},
Expect1 = [OneChild, Stemmed1aa],
etap:is(
- {Expect1, conflicts},
+ {Expect1, new_branch},
couch_key_tree:merge([OneChild], Stemmed1aa, 10),
"Merging should create conflicts."
),
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], new_leaf},
couch_key_tree:merge(Expect1, TwoChild, 10),
"Merge should have no conflicts."
),
@@ -168,9 +155,21 @@ test() ->
]}},
etap:is(
- {[FooBar], no_conflicts},
+ {[FooBar], new_leaf},
couch_key_tree:merge([Foo],Bar,10),
"Merging trees with conflicts ought to behave."
),
+ etap:is(
+ {[TwoChild], internal_node},
+ couch_key_tree:merge([TwoChild],One,10),
+ "Merging tree with already-existing path."
+ ),
+
+ etap:is(
+ {[TwoChildSibs], internal_node},
+ couch_key_tree:merge([TwoChildSibs],One,10),
+ "Merging tree with already-existing path with siblings."
+ ),
+
ok.