You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2016/01/07 13:46:36 UTC

svn commit: r1723532 [5/5] - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/d...

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/OrphanedBranchTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/OrphanedBranchTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/OrphanedBranchTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/OrphanedBranchTest.java Thu Jan  7 12:46:35 2016
@@ -58,7 +58,7 @@ public class OrphanedBranchTest {
         this.fixture = fixture;
     }
 
-    @Parameterized.Parameters
+    @Parameterized.Parameters(name="{0}")
     public static java.util.Collection<Object[]> fixtures() throws IOException {
         List<Object[]> fixtures = Lists.newArrayList();
         fixtures.add(new Object[] {new DocumentStoreFixture.MemoryFixture()});
@@ -185,7 +185,7 @@ public class OrphanedBranchTest {
         assertFalse(valueMap.isEmpty());
         UnmergedBranches branches = store.getBranches();
         Revision branchRev = doc.getLocalMap("prop").firstKey();
-        Branch b = branches.getBranch(branchRev);
+        Branch b = branches.getBranch(new RevisionVector(branchRev.asBranchRevision()));
         assertNotNull(b);
         branches.remove(b);
         

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionTest.java Thu Jan  7 12:46:35 2016
@@ -20,7 +20,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CountDownLatch;
@@ -34,11 +33,10 @@ import static org.junit.Assert.assertTru
 import static org.junit.Assert.fail;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Queues;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.Uninterruptibles;
-import org.apache.jackrabbit.oak.plugins.document.Revision.RevisionComparator;
+
 import org.junit.Test;
 
 /**
@@ -129,246 +127,6 @@ public class RevisionTest {
     }
 
     @Test
-    public void compare2() {
-        RevisionComparator comp = new RevisionComparator(1);
-
-        Revision r2 = new Revision(7, 0, 2);
-        Revision r3 = new Revision(5, 0, 3);
-
-        Revision seenAt = new Revision(8, 0, 0);
-        comp.add(r2, seenAt);
-        comp.add(r3, seenAt);
-
-        // both revisions have same seenAt revision, must use
-        // revision timestamp for comparison
-        assertTrue(comp.compare(r2, r3) > 0);
-    }
-
-    @Test
-    public void revisionComparatorSimple() {
-        RevisionComparator comp = new RevisionComparator(0);
-        Revision r1 = Revision.newRevision(0);
-        Revision r2 = Revision.newRevision(0);
-        assertEquals(r1.compareRevisionTime(r2), comp.compare(r1, r2));
-        assertEquals(r2.compareRevisionTime(r1), comp.compare(r2, r1));
-        assertEquals(r1.compareRevisionTime(r1), comp.compare(r1, r1));
-    }
-
-    @Test
-    public void revisionComparatorCluster() {
-
-        RevisionComparator comp = new RevisionComparator(0);
-
-        Revision r0c1 = new Revision(0x010, 0, 1);
-        Revision r0c2 = new Revision(0x010, 0, 2);
-
-        Revision r1c1 = new Revision(0x110, 0, 1);
-        Revision r2c1 = new Revision(0x120, 0, 1);
-        Revision r3c1 = new Revision(0x130, 0, 1);
-        Revision r1c2 = new Revision(0x100, 0, 2);
-        Revision r2c2 = new Revision(0x200, 0, 2);
-        Revision r3c2 = new Revision(0x300, 0, 2);
-
-        // first, only timestamps are compared
-        assertEquals(1, comp.compare(r1c1, r1c2));
-        assertEquals(-1, comp.compare(r2c1, r2c2));
-        assertEquals(-1, comp.compare(r3c1, r3c2));
-
-        // now we declare r2+r3 of c1 to be after r2+r3 of c2
-        comp.add(r2c1, new Revision(0x20, 0, 0));
-        comp.add(r2c2, new Revision(0x10, 0, 0));
-
-        assertEquals(
-                "1:\n r120-0-1:r20-0-0\n" +
-                "2:\n r200-0-2:r10-0-0\n", comp.toString());
-
-        // r0c2 happens before r0c1 because r2c2 is declared before r2c1
-        assertEquals(1, comp.compare(r0c1, r0c2));
-
-        assertEquals(1, comp.compare(r1c1, r1c2));
-        assertEquals(1, comp.compare(r2c1, r2c2));
-        // both r3cx are still "in the future"
-        assertEquals(-1, comp.compare(r3c1, r3c2));
-
-        // now we declare r3 of c1 to be before r3 of c2
-        // (with the same range timestamp,
-        // the revision timestamps are compared)
-        comp.add(r3c1, new Revision(0x30, 0, 0));
-        comp.add(r3c2, new Revision(0x30, 0, 0));
-
-        assertEquals(
-                "1:\n r120-0-1:r20-0-0 r130-0-1:r30-0-0\n" +
-                "2:\n r200-0-2:r10-0-0 r300-0-2:r30-0-0\n", comp.toString());
-
-        assertEquals(1, comp.compare(r1c1, r1c2));
-        assertEquals(1, comp.compare(r2c1, r2c2));
-        assertEquals(-1, comp.compare(r3c1, r3c2));
-        // reverse
-        assertEquals(-1, comp.compare(r1c2, r1c1));
-        assertEquals(-1, comp.compare(r2c2, r2c1));
-        assertEquals(1, comp.compare(r3c2, r3c1));
-
-        // get rid of old timestamps
-        comp.purge(0x10);
-        assertEquals(
-                "1:\n r120-0-1:r20-0-0 r130-0-1:r30-0-0\n" +
-                "2:\n r300-0-2:r30-0-0\n", comp.toString());
-        comp.purge(0x20);
-        assertEquals(
-                "1:\n r130-0-1:r30-0-0\n" +
-                "2:\n r300-0-2:r30-0-0\n", comp.toString());
-
-        // update an entry
-        comp.add(new Revision(0x301, 1, 2), new Revision(0x30, 0, 0));
-        assertEquals(
-                "1:\n r130-0-1:r30-0-0\n" +
-                "2:\n r301-1-2:r30-0-0\n", comp.toString());
-
-        comp.purge(0x30);
-        assertEquals("", comp.toString());
-
-    }
-
-    @Test
-    public void clusterCompare() {
-        RevisionComparator comp = new RevisionComparator(1);
-
-        // sequence of revisions as added to comparator later
-        Revision r1c1 = new Revision(0x10, 0, 1);
-        Revision r1c2 = new Revision(0x20, 0, 2);
-        Revision r2c1 = new Revision(0x30, 0, 1);
-        Revision r2c2 = new Revision(0x40, 0, 2);
-
-        comp.add(r1c1, new Revision(0x10, 0, 0));
-        comp.add(r2c1, new Revision(0x30, 0, 0));
-
-        // there's no range for c2, and therefore this
-        // revision must be considered to be in the future
-        assertTrue(comp.compare(r1c2, r2c1) > 0);
-
-        // add a range for r2r2
-        comp.add(r2c2, new Revision(0x40, 0, 0));
-        comp.purge(0x20);
-
-        // now there is a range for c2, but the revision is old (before purge
-        // time, so it must be considered to be in the past
-        assertTrue(comp.compare(r1c2, r2c1) < 0);
-    }
-
-    // OAK-1727
-    @Test
-    public void clusterCompare2() {
-        RevisionComparator comp = new RevisionComparator(1);
-
-        comp.add(Revision.fromString("r3-0-1"), Revision.fromString("r1-1-0"));
-
-        Revision r1 = Revision.fromString("r1-0-2");
-        Revision r2 = Revision.fromString("r4-0-2");
-
-        // cluster sync
-        Revision c1sync = Revision.fromString("r5-0-1");
-        comp.add(c1sync,  Revision.fromString("r2-0-0"));
-        Revision c2sync = Revision.fromString("r4-1-2");
-        comp.add(c2sync,  Revision.fromString("r2-1-0"));
-        Revision c3sync = Revision.fromString("r5-0-3");
-        comp.add(c3sync, Revision.fromString("r2-1-0"));
-
-        assertTrue(comp.compare(r1, r2) < 0);
-        assertTrue(comp.compare(r2, c2sync) < 0);
-        // same seen-at revision, but rev timestamp c2sync < c3sync
-        assertTrue(comp.compare(c2sync, c3sync) < 0);
-
-        // this means, c3sync must be after r1 and r2
-        // because: r1 < r2 < c2sync < c3sync
-        assertTrue(comp.compare(r1, c3sync) < 0);
-        assertTrue(comp.compare(r2, c3sync) < 0);
-    }
-
-    @Test
-    public void revisionSeen() {
-        RevisionComparator comp = new RevisionComparator(1);
-        comp.purge(0);
-
-        Revision r0 = new Revision(0x01, 0, 1);
-        Revision r1 = new Revision(0x10, 0, 1);
-        Revision r2 = new Revision(0x20, 0, 1);
-        Revision r21 = new Revision(0x21, 0, 1);
-        Revision r3 = new Revision(0x30, 0, 1);
-        Revision r4 = new Revision(0x40, 0, 1);
-        Revision r5 = new Revision(0x50, 0, 1);
-
-        comp.add(r1, new Revision(0x10, 0, 0));
-        comp.add(r2, new Revision(0x20, 0, 0));
-        comp.add(r3, new Revision(0x30, 0, 0));
-        comp.add(r4, new Revision(0x40, 0, 0));
-
-        // older than first range, but after purge timestamp
-        // -> must return seen-at of first range
-        assertEquals(new Revision(0x10, 0, 0), comp.getRevisionSeen(r0));
-
-        // exact range start matches
-        assertEquals(new Revision(0x10, 0, 0), comp.getRevisionSeen(r1));
-        assertEquals(new Revision(0x20, 0, 0), comp.getRevisionSeen(r2));
-        assertEquals(new Revision(0x30, 0, 0), comp.getRevisionSeen(r3));
-        assertEquals(new Revision(0x40, 0, 0), comp.getRevisionSeen(r4));
-
-        // revision newer than most recent range -> NEWEST
-        assertEquals(RevisionComparator.NEWEST, comp.getRevisionSeen(r5));
-
-        // within a range -> must return lower bound of next higher range
-        assertEquals(new Revision(0x30, 0, 0), comp.getRevisionSeen(r21));
-    }
-
-    // OAK-1814
-    @Test
-    public void seenAtAfterPurge() throws Exception {
-        RevisionComparator comp = new RevisionComparator(1);
-
-        // some revisions from another cluster node
-        Revision r1 = new Revision(0x01, 0, 2);
-        Revision r2 = new Revision(0x02, 0, 2);
-
-        // make them visible
-        comp.add(r1, new Revision(0x01, 0, 0));
-        comp.add(r2, new Revision(0x02, 0, 0));
-
-        comp.purge(0x01);
-
-        // null indicates older than earliest range
-        assertNull(comp.getRevisionSeen(r1));
-        // r2 is still seen at 0x02
-        assertEquals(new Revision(0x02, 0, 0), comp.getRevisionSeen(r2));
-
-        comp.purge(0x02);
-
-        // now also r2 is considered old
-        assertNull(comp.getRevisionSeen(r2));
-    }
-
-    // OAK-1822
-    @Test
-    public void seenAtBeforeFirstRangeAfterPurge() {
-        RevisionComparator comp = new RevisionComparator(1);
-        comp.purge(0);
-
-        Revision r1 = new Revision(1, 0, 1);
-        Revision r2 = new Revision(2, 0, 1);
-        Revision r3 = new Revision(3, 0, 1);
-
-        Revision r3seen = new Revision(3, 0, 0);
-
-        comp.add(r3, r3seen);
-
-        assertEquals(r3seen, comp.getRevisionSeen(r1));
-        assertEquals(r3seen, comp.getRevisionSeen(r2));
-
-        comp.purge(1);
-
-        assertEquals(null, comp.getRevisionSeen(r1));
-        assertEquals(r3seen, comp.getRevisionSeen(r2));
-    }
-
-    @Test
     public void uniqueRevision2() throws Exception {
         List<Thread> threads = new ArrayList<Thread>();
         final AtomicBoolean stop = new AtomicBoolean();
@@ -472,59 +230,4 @@ public class RevisionTest {
         }
         assertTrue(String.format("Duplicate rev seen %s %n Seen %s", duplicates, seenRevs), duplicates.isEmpty());
     }
-
-    @Test
-    public void getMinimumTimestamp() {
-        Map<Integer, Long> inactive = Maps.newHashMap();
-        RevisionComparator comp = new RevisionComparator(1);
-
-        Revision r11 = new Revision(1, 0, 1);
-        comp.add(r11, new Revision(1, 0, 0));
-
-        assertEquals(1, comp.getMinimumTimestamp(r11, inactive));
-
-        Revision r21 = new Revision(1, 0, 2);
-        comp.add(r21, new Revision(2, 0, 0));
-
-        assertEquals(1, comp.getMinimumTimestamp(r21, inactive));
-
-        Revision r13 = new Revision(3, 0, 1);
-        comp.add(r13, new Revision(3, 0, 0));
-
-        assertEquals(1, comp.getMinimumTimestamp(r13, inactive));
-
-        Revision r24 = new Revision(4, 0, 2);
-        comp.add(r24, new Revision(4, 0, 0));
-
-        assertEquals(3, comp.getMinimumTimestamp(r24, inactive));
-
-        Revision r15 = new Revision(5, 0, 1);
-        comp.add(r15, new Revision(5, 0, 0));
-
-        assertEquals(4, comp.getMinimumTimestamp(r15, inactive));
-
-        // simulate cluster node 2 is stopped
-        inactive.put(2, 6L);
-
-        Revision r17 = new Revision(7, 0, 1);
-        comp.add(r17, new Revision(7, 0, 0));
-
-        assertEquals(7, comp.getMinimumTimestamp(r17, inactive));
-    }
-
-    // OAK-2318
-    @Test
-    public void getMinimumTimestampSingleClusterId() {
-        Map<Integer, Long> inactive = Maps.newHashMap();
-        RevisionComparator comp = new RevisionComparator(1);
-
-        Revision r1 = new Revision(1, 0, 1);
-        comp.add(r1, new Revision(1, 0, 0));
-
-        assertEquals(1, comp.getMinimumTimestamp(r1, inactive));
-
-        Revision r2 = new Revision(2, 0, 1);
-        assertEquals(2, comp.getMinimumTimestamp(r2, inactive));
-    }
-
 }

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java?rev=1723532&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java Thu Jan  7 12:46:35 2016
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import org.junit.Test;
+
+import static com.google.common.collect.Sets.newHashSet;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class RevisionVectorTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void illegalArgument() {
+        Revision rev1 = new Revision(1, 0, 1);
+        new RevisionVector(rev1, rev1);
+    }
+
+    @Test
+    public void construct() {
+        RevisionVector rv = new RevisionVector();
+        assertEquals(newHashSet(), newHashSet(rv));
+
+        Revision rev1 = new Revision(1, 0, 1);
+        Revision rev2 = new Revision(1, 0, 2);
+        rv = new RevisionVector(newHashSet(rev1, rev2));
+        assertEquals(newHashSet(rev1, rev2), newHashSet(rv));
+
+        rv = new RevisionVector(Lists.newArrayList(rev1, rev2));
+        assertEquals(newHashSet(rev1, rev2), newHashSet(rv));
+    }
+
+    @Test
+    public void update() {
+        Revision rev1 = new Revision(1, 0, 1);
+        RevisionVector rv = new RevisionVector(rev1);
+        assertEquals(1, Iterables.size(rv));
+        assertSame(rv, rv.update(rev1));
+
+        Revision rev2 = new Revision(2, 0, 1);
+        rv = rv.update(rev2);
+        assertEquals(newHashSet(rev2), newHashSet(rv));
+
+        Revision rev3 = new Revision(3, 0, 2);
+        rv = rv.update(rev3);
+        assertEquals(newHashSet(rev2, rev3), newHashSet(rv));
+
+        rev3 = rev3.asBranchRevision();
+        rv = rv.update(rev3);
+        assertEquals(newHashSet(rev2, rev3), newHashSet(rv));
+    }
+
+    @Test
+    public void remove() {
+        RevisionVector rv = new RevisionVector();
+        assertSame(rv, rv.remove(1));
+
+        Revision rev1 = new Revision(1, 0, 1);
+        Revision rev2 = new Revision(1, 0, 2);
+        Revision rev3 = new Revision(1, 0, 3);
+        rv = new RevisionVector(rev1);
+        assertSame(rv, rv.remove(2));
+        assertEquals(new RevisionVector(), rv.remove(rev1.getClusterId()));
+        rv = new RevisionVector(rev1, rev2, rev3);
+        assertEquals(new RevisionVector(rev2, rev3), rv.remove(rev1.getClusterId()));
+        assertEquals(new RevisionVector(rev1, rev3), rv.remove(rev2.getClusterId()));
+        assertEquals(new RevisionVector(rev1, rev2), rv.remove(rev3.getClusterId()));
+    }
+
+    @Test
+    public void isNewer() {
+        Revision rev1 = new Revision(1, 0, 1);
+        Revision rev2 = new Revision(1, 0, 2);
+        Revision rev3 = new Revision(1, 0, 3);
+        RevisionVector rv = new RevisionVector(rev1, rev2);
+
+        assertFalse(rv.isRevisionNewer(rev1));
+        assertFalse(rv.isRevisionNewer(rev2));
+        assertTrue(rv.isRevisionNewer(rev3));
+
+        assertTrue(rv.isRevisionNewer(new Revision(2, 0, 1)));
+        assertTrue(rv.isRevisionNewer(new Revision(2, 0, 2)));
+        assertFalse(rv.isRevisionNewer(new Revision(0, 0, 1)));
+        assertFalse(rv.isRevisionNewer(new Revision(0, 0, 2)));
+    }
+
+    @Test
+    public void pmin() {
+        RevisionVector rv1 = new RevisionVector();
+        RevisionVector rv2 = new RevisionVector();
+        assertEquals(newHashSet(), newHashSet(rv1.pmin(rv2)));
+
+        Revision rev11 = new Revision(1, 0, 1);
+        Revision rev21 = new Revision(2, 0, 1);
+        Revision rev12 = new Revision(1, 0, 2);
+        Revision rev22 = new Revision(2, 0, 2);
+
+        rv1 = rv1.update(rev11);
+        // rv1: [r1-0-1], rv2: []
+        assertEquals(newHashSet(), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(), newHashSet(rv2.pmin(rv1)));
+
+        rv2 = rv2.update(rev12);
+        // rv1: [r1-0-1], rv2: [r1-0-2]
+        assertEquals(newHashSet(), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(), newHashSet(rv2.pmin(rv1)));
+
+        rv1 = rv1.update(rev12);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r1-0-2]
+        assertEquals(newHashSet(rev12), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(rev12), newHashSet(rv2.pmin(rv1)));
+
+        rv2 = rv2.update(rev22);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r2-0-2]
+        assertEquals(newHashSet(rev12), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(rev12), newHashSet(rv2.pmin(rv1)));
+
+        rv2 = rv2.update(rev11);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv2.pmin(rv1)));
+
+        rv1 = rv1.update(rev21);
+        // rv1: [r2-0-1, r1-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv2.pmin(rv1)));
+
+        rv1 = rv1.update(rev22);
+        // rv1: [r2-0-1, r2-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(newHashSet(rev11, rev22), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(rev11, rev22), newHashSet(rv2.pmin(rv1)));
+
+        rv2 = rv2.update(rev21);
+        // rv1: [r2-0-1, r2-0-2], rv2: [r2-0-1, r2-0-2]
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv1.pmin(rv2)));
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv2.pmin(rv1)));
+    }
+
+    @Test
+    public void pmax() {
+        RevisionVector rv1 = new RevisionVector();
+        RevisionVector rv2 = new RevisionVector();
+        assertEquals(newHashSet(), newHashSet(rv1.pmax(rv2)));
+
+        Revision rev11 = new Revision(1, 0, 1);
+        Revision rev21 = new Revision(2, 0, 1);
+        Revision rev12 = new Revision(1, 0, 2);
+        Revision rev22 = new Revision(2, 0, 2);
+
+        rv1 = rv1.update(rev11);
+        // rv1: [r1-0-1], rv2: []
+        assertEquals(newHashSet(rev11), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev11), newHashSet(rv2.pmax(rv1)));
+
+        rv2 = rv2.update(rev12);
+        // rv1: [r1-0-1], rv2: [r1-0-2]
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv2.pmax(rv1)));
+
+        rv1 = rv1.update(rev12);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r1-0-2]
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev11, rev12), newHashSet(rv2.pmax(rv1)));
+
+        rv2 = rv2.update(rev22);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r2-0-2]
+        assertEquals(newHashSet(rev11, rev22), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev11, rev22), newHashSet(rv2.pmax(rv1)));
+
+        rv2 = rv2.update(rev11);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(newHashSet(rev11, rev22), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev11, rev22), newHashSet(rv2.pmax(rv1)));
+
+        rv1 = rv1.update(rev21);
+        // rv1: [r2-0-1, r1-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv2.pmax(rv1)));
+
+        rv1 = rv1.update(rev22);
+        // rv1: [r2-0-1, r2-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv2.pmax(rv1)));
+
+        rv2 = rv2.update(rev21);
+        // rv1: [r2-0-1, r2-0-2], rv2: [r2-0-1, r2-0-2]
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv1.pmax(rv2)));
+        assertEquals(newHashSet(rev21, rev22), newHashSet(rv2.pmax(rv1)));
+    }
+
+    @Test
+    public void difference() {
+        RevisionVector rv1 = new RevisionVector();
+        RevisionVector rv2 = new RevisionVector();
+        assertEquals(new RevisionVector(), rv1.difference(rv2));
+
+        Revision r11 = new Revision(1, 0, 1);
+        rv1 = rv1.update(r11);
+        // rv1: [r1-0-1]
+        assertEquals(new RevisionVector(r11), rv1.difference(rv2));
+        assertEquals(new RevisionVector(), rv2.difference(rv1));
+
+        rv2 = rv2.update(r11);
+        // rv1: [r1-0-1], rv2: [r1-0-1]
+        assertEquals(new RevisionVector(), rv1.difference(rv2));
+        assertEquals(new RevisionVector(), rv2.difference(rv1));
+
+        Revision r12 = new Revision(1, 0, 2);
+        rv1 = rv1.update(r12);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r1-0-1]
+        assertEquals(new RevisionVector(r12), rv1.difference(rv2));
+        assertEquals(new RevisionVector(), rv2.difference(rv1));
+
+        Revision r22 = new Revision(2, 0, 2);
+        rv2 = rv2.update(r22);
+        // rv1: [r1-0-1, r1-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(new RevisionVector(r12), rv1.difference(rv2));
+        assertEquals(new RevisionVector(r22), rv2.difference(rv1));
+
+        Revision r21 = new Revision(2, 0, 1);
+        rv1 = rv1.update(r21);
+        // rv1: [r2-0-1, r1-0-2], rv2: [r1-0-1, r2-0-2]
+        assertEquals(new RevisionVector(r21, r12), rv1.difference(rv2));
+        assertEquals(new RevisionVector(r11, r22), rv2.difference(rv1));
+    }
+
+    @Test
+    public void isBranch() {
+        RevisionVector rv = new RevisionVector();
+        assertFalse(rv.isBranch());
+        Revision r1 = new Revision(1, 0, 1);
+        rv = rv.update(r1);
+        assertFalse(rv.isBranch());
+        Revision r2 = new Revision(1, 0, 2, true);
+        rv = rv.update(r2);
+        assertTrue(rv.isBranch());
+    }
+
+    @Test
+    public void getBranchRevision() {
+        Revision r1 = new Revision(1, 0, 1);
+        Revision r2 = new Revision(1, 0, 2, true);
+        RevisionVector rv = new RevisionVector(r1, r2);
+        assertEquals(r2, rv.getBranchRevision());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void exceptionOnGetBranchRevision() {
+        RevisionVector rv = new RevisionVector();
+        rv.getBranchRevision();
+    }
+
+    @Test
+    public void compareTo() {
+        RevisionVector rv1 = new RevisionVector();
+        RevisionVector rv2 = new RevisionVector();
+        assertEquals(0, rv1.compareTo(rv2));
+
+        Revision r11 = new Revision(1, 0, 1);
+        rv1 = rv1.update(r11); // [r1-0-1]
+        assertTrue(rv1.compareTo(rv2) > 0);
+        assertTrue(rv2.compareTo(rv1) < 0);
+
+        Revision r12 = new Revision(1, 0, 2);
+        rv2 = rv2.update(r12); // [r1-0-2]
+        assertTrue(rv1.compareTo(rv2) > 0);
+        assertTrue(rv2.compareTo(rv1) < 0);
+
+        rv2 = rv2.update(r11); // [r1-0-1, r1-0-2]
+        assertTrue(rv1.compareTo(rv2) < 0);
+        assertTrue(rv2.compareTo(rv1) > 0);
+
+        rv1 = rv1.update(r12); // [r1-0-1, r1-0-2]
+        assertEquals(0, rv1.compareTo(rv2));
+        assertEquals(0, rv2.compareTo(rv1));
+
+        Revision r22 = new Revision(2, 0, 2);
+        rv2 = rv2.update(r22); // [r1-0-1, r2-0-2]
+        assertTrue(rv1.compareTo(rv2) < 0);
+        assertTrue(rv2.compareTo(rv1) > 0);
+
+        Revision rb22 = r22.asBranchRevision();
+        rv1 = rv1.update(rb22);
+        assertTrue(rv1.compareTo(rv2) < 0);
+        assertTrue(rv2.compareTo(rv1) > 0);
+    }
+
+    @Test
+    public void equals() {
+        RevisionVector rv1 = new RevisionVector();
+        RevisionVector rv2 = new RevisionVector();
+        assertEquals(rv1, rv2);
+        Revision r11 = new Revision(1, 0, 1);
+        rv1 = rv1.update(r11);
+        assertNotEquals(rv1, rv2);
+        rv2 = rv2.update(r11);
+        assertEquals(rv1, rv2);
+        Revision r12 = new Revision(1, 0, 2);
+        rv1 = rv1.update(r12);
+        assertNotEquals(rv1, rv2);
+        rv2 = rv2.update(r12);
+        assertEquals(rv1, rv2);
+    }
+
+    @Test
+    public void hashCodeTest() {
+        RevisionVector rv1 = new RevisionVector();
+        RevisionVector rv2 = new RevisionVector();
+        assertEquals(rv1.hashCode(), rv2.hashCode());
+        Revision r11 = new Revision(1, 0, 1);
+        rv1 = rv1.update(r11);
+        rv2 = rv2.update(r11);
+        assertEquals(rv1.hashCode(), rv2.hashCode());
+        Revision r12 = new Revision(1, 0, 2);
+        rv1 = rv1.update(r12);
+        rv2 = rv2.update(r12);
+        assertEquals(rv1.hashCode(), rv2.hashCode());
+    }
+
+    @Test
+    public void getRevision() {
+        RevisionVector rv = new RevisionVector();
+        assertNull(rv.getRevision(1));
+        Revision r11 = new Revision(1, 0, 1);
+        rv = rv.update(r11);
+        assertEquals(r11, rv.getRevision(1));
+        assertNull(rv.getRevision(2));
+        Revision r13 = new Revision(1, 0, 3);
+        rv = rv.update(r13);
+        assertEquals(r13, rv.getRevision(3));
+        assertNull(rv.getRevision(2));
+    }
+
+    @Test
+    public void asTrunkRevision() {
+        RevisionVector rv = new RevisionVector();
+        assertFalse(rv.asTrunkRevision().isBranch());
+        rv = rv.update(new Revision(1, 0, 1, true));
+        assertTrue(rv.isBranch());
+        assertFalse(rv.asTrunkRevision().isBranch());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void asBranchRevision1() {
+        new RevisionVector().asBranchRevision(1);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void asBranchRevision2() {
+        new RevisionVector(new Revision(1, 0, 1)).asBranchRevision(2);
+    }
+
+    @Test
+    public void asBranchRevision3() {
+        Revision r11 = new Revision(1, 0, 1);
+        Revision br11 = r11.asBranchRevision();
+        RevisionVector rv = new RevisionVector(r11);
+        assertEquals(new RevisionVector(br11), rv.asBranchRevision(1));
+        rv = rv.asTrunkRevision();
+        Revision r12 = new Revision(1, 0, 2);
+        rv = rv.update(r12);
+        assertEquals(new RevisionVector(br11, r12), rv.asBranchRevision(1));
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/SimpleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/SimpleTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/SimpleTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/SimpleTest.java Thu Jan  7 12:46:35 2016
@@ -75,12 +75,12 @@ public class SimpleTest {
         DocumentMK mk = builderProvider.newBuilder().open();
         DocumentStore s = mk.getDocumentStore();
         DocumentNodeStore ns = mk.getNodeStore();
-        Revision rev = Revision.fromString(mk.getHeadRevision());
+        RevisionVector rev = RevisionVector.fromString(mk.getHeadRevision());
         DocumentNodeState n = new DocumentNodeState(ns, "/test", rev);
         n.setProperty("name", "\"Hello\"");
-        UpdateOp op = n.asOperation(true);
+        UpdateOp op = n.asOperation(rev.getRevision(ns.getClusterId()));
         // mark as commit root
-        NodeDocument.setRevision(op, rev, "c");
+        NodeDocument.setRevision(op, rev.getRevision(ns.getClusterId()), "c");
         assertTrue(s.create(Collection.NODES, Lists.newArrayList(op)));
         DocumentNodeState n2 = ns.getNode("/test", rev);
         assertNotNull(n2);
@@ -245,11 +245,11 @@ public class SimpleTest {
         String r0 = mk.commit("/test", "+\"a\":{\"name\": \"World\"}", null, null);
         String r1 = mk.commit("/test", "+\"b\":{\"name\": \"!\"}", null, null);
         test = mk.getNodes("/test", r0, 0, 0, Integer.MAX_VALUE, null);
-        DocumentNodeState n = ns.getNode("/", Revision.fromString(r0));
+        DocumentNodeState n = ns.getNode("/", RevisionVector.fromString(r0));
         assertNotNull(n);
         Children c = ns.getChildren(n, null, Integer.MAX_VALUE);
         assertEquals("[test]", c.toString());
-        n = ns.getNode("/test", Revision.fromString(r1));
+        n = ns.getNode("/test", RevisionVector.fromString(r1));
         assertNotNull(n);
         c = ns.getChildren(n, null, Integer.MAX_VALUE);
         assertEquals("[a, b]", c.toString());
@@ -271,19 +271,19 @@ public class SimpleTest {
         mk.commit("/testDel", "+\"b\":{\"name\": \"!\"}", null, null);
         String r1 = mk.commit("/testDel", "+\"c\":{\"name\": \"!\"}", null, null);
 
-        DocumentNodeState n = ns.getNode("/testDel", Revision.fromString(r1));
+        DocumentNodeState n = ns.getNode("/testDel", RevisionVector.fromString(r1));
         assertNotNull(n);
         Children c = ns.getChildren(n, null, Integer.MAX_VALUE);
         assertEquals(3, c.children.size());
 
         String r2 = mk.commit("/testDel", "-\"c\"", null, null);
-        n = ns.getNode("/testDel", Revision.fromString(r2));
+        n = ns.getNode("/testDel", RevisionVector.fromString(r2));
         assertNotNull(n);
         c = ns.getChildren(n, null, Integer.MAX_VALUE);
         assertEquals(2, c.children.size());
 
         String r3 = mk.commit("/", "-\"testDel\"", null, null);
-        n = ns.getNode("/testDel", Revision.fromString(r3));
+        n = ns.getNode("/testDel", RevisionVector.fromString(r3));
         assertNull(n);
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/UnmergedBranchTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/UnmergedBranchTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/UnmergedBranchTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/UnmergedBranchTest.java Thu Jan  7 12:46:35 2016
@@ -40,7 +40,9 @@ public class UnmergedBranchTest {
     public void purgeUnmergedBranch() throws Exception {
         DocumentStore testStore = new MemoryDocumentStore();
         DocumentMK mk1 = create(testStore, 1);
+        int cId1 = mk1.getNodeStore().getClusterId();
         DocumentMK mk2 = create(testStore, 2);
+        int cId2 = mk2.getNodeStore().getClusterId();
 
         //1. Create branch commits on both cluster nodes
         String rev1 = mk1.commit("", "+\"/child1\":{}", null, "");
@@ -51,12 +53,12 @@ public class UnmergedBranchTest {
         String branchRev2 = mk2.branch(rev2);
         String brev2 = mk2.commit("/child2", "^\"foo\":1", branchRev2, "");
 
-        Map<Revision, Revision> revs1 = getUncommittedRevisions(mk1);
-        Map<Revision, Revision> revs2 = getUncommittedRevisions(mk2);
+        Map<Revision, RevisionVector> revs1 = getUncommittedRevisions(mk1);
+        Map<Revision, RevisionVector> revs2 = getUncommittedRevisions(mk2);
 
         //2. Assert that branch rev are uncommited
-        assertTrue(revs1.containsKey(Revision.fromString(brev1).asTrunkRevision()));
-        assertTrue(revs2.containsKey(Revision.fromString(brev2).asTrunkRevision()));
+        assertTrue(revs1.containsKey(RevisionVector.fromString(brev1).asTrunkRevision().getRevision(cId1)));
+        assertTrue(revs2.containsKey(RevisionVector.fromString(brev2).asTrunkRevision().getRevision(cId2)));
 
         //3. Restart cluster 1 so that purge happens but only for cluster 1
         mk1.dispose();
@@ -65,23 +67,23 @@ public class UnmergedBranchTest {
         revs2 = getUncommittedRevisions(mk2);
 
         //4. Assert that post restart unmerged branch rev for c1 are purged
-        assertFalse(revs1.containsKey(Revision.fromString(brev1).asTrunkRevision()));
-        assertTrue(revs2.containsKey(Revision.fromString(brev2).asTrunkRevision()));
+        assertFalse(revs1.containsKey(RevisionVector.fromString(brev1).asTrunkRevision().getRevision(cId1)));
+        assertTrue(revs2.containsKey(RevisionVector.fromString(brev2).asTrunkRevision().getRevision(cId2)));
 
     }
 
-    public SortedMap<Revision, Revision> getUncommittedRevisions(DocumentMK mk) {
+    public SortedMap<Revision, RevisionVector> getUncommittedRevisions(DocumentMK mk) {
         // only look at revisions in this document.
         // uncommitted revisions are not split off
         NodeDocument doc = getRootDoc(mk);
         Map<Revision, String> valueMap = doc.getLocalMap(NodeDocument.REVISIONS);
-        SortedMap<Revision, Revision> revisions =
-                new TreeMap<Revision, Revision>(mk.getNodeStore().getRevisionComparator());
+        SortedMap<Revision, RevisionVector> revisions =
+                new TreeMap<Revision, RevisionVector>(StableRevisionComparator.INSTANCE);
         for (Map.Entry<Revision, String> commit : valueMap.entrySet()) {
             if (!Utils.isCommitted(commit.getValue())) {
                 Revision r = commit.getKey();
                 if (r.getClusterId() == mk.getNodeStore().getClusterId()) {
-                    Revision b = Revision.fromString(commit.getValue());
+                    RevisionVector b = RevisionVector.fromString(commit.getValue());
                     revisions.put(r, b);
                 }
             }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/CollisionMarkerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/CollisionMarkerTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/CollisionMarkerTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/CollisionMarkerTest.java Thu Jan  7 12:46:35 2016
@@ -75,7 +75,7 @@ public class CollisionMarkerTest extends
         b1.child("node").child("foo");
         b1.child("test").setProperty("p", 1);
         merge(ns1, b1);
-        Revision head = ns1.getHeadRevision();
+        Revision head = ns1.getHeadRevision().getRevision(ns1.getClusterId());
 
         NodeBuilder b2 = ns2.getRoot().builder();
         b2.child("node").child("bar");

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/BroadcastTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/BroadcastTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/BroadcastTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/BroadcastTest.java Thu Jan  7 12:46:35 2016
@@ -32,6 +32,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.cache.CacheLIRS;
 import org.apache.jackrabbit.oak.plugins.document.PathRev;
 import org.apache.jackrabbit.oak.plugins.document.Revision;
+import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
 import org.apache.jackrabbit.oak.plugins.document.persistentCache.broadcast.Broadcaster;
 import org.apache.jackrabbit.oak.plugins.document.persistentCache.broadcast.TCPBroadcaster;
 import org.apache.jackrabbit.oak.plugins.document.util.StringValue;
@@ -64,7 +65,7 @@ public class BroadcastTest {
             PersistentCache pc = new PersistentCache("target/broadcastTest/p" + nodes + ",broadcast=" + type);
             Cache<PathRev, StringValue> cache = openCache(pc);
             String key = "/test" + Math.random();
-            PathRev k = new PathRev(key, new Revision(0, 0, 0));
+            PathRev k = new PathRev(key, new RevisionVector(new Revision(0, 0, 0)));
             long time = System.currentTimeMillis();
             for (int i = 0; i < 2000; i++) {
                 cache.put(k, new StringValue("Hello World " + i));
@@ -196,7 +197,7 @@ public class BroadcastTest {
         Cache<PathRev, StringValue> c1 = openCache(p1);
         Cache<PathRev, StringValue> c2 = openCache(p2);
         String key = "/test" + Math.random();
-        PathRev k = new PathRev(key, new Revision(0, 0, 0));
+        PathRev k = new PathRev(key, new RevisionVector(new Revision(0, 0, 0)));
         int correct = 0;
         for (int i = 0; i < 50; i++) {
             c1.put(k, new StringValue("Hello World " + i));

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheTest.java Thu Jan  7 12:46:35 2016
@@ -32,6 +32,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.cache.CacheLIRS;
 import org.apache.jackrabbit.oak.plugins.document.PathRev;
 import org.apache.jackrabbit.oak.plugins.document.Revision;
+import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
 import org.apache.jackrabbit.oak.plugins.document.util.StringValue;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore;
@@ -57,7 +58,7 @@ public class CacheTest {
                 Thread.yield();
             }
             for (int i = 0; i < 100; i++) {
-                PathRev k = new PathRev("/" + counter, new Revision(0, 0, i));
+                PathRev k = new PathRev("/" + counter, new RevisionVector(new Revision(0, 0, i)));
                 map.getIfPresent(k);
                 map.put(k, new StringValue(largeString));
             }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/RevisionsKeyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/RevisionsKeyTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/RevisionsKeyTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/RevisionsKeyTest.java Thu Jan  7 12:46:35 2016
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.oak.plugins.document.util;
 
 import org.apache.jackrabbit.oak.plugins.document.Revision;
+import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -29,7 +30,8 @@ public class RevisionsKeyTest {
     @Test
     public void fromAsString() {
         RevisionsKey k1 = new RevisionsKey(
-                new Revision(1, 0, 1), new Revision(2, 1, 2));
+                new RevisionVector(new Revision(1, 0, 1)),
+                new RevisionVector(new Revision(2, 1, 2)));
         RevisionsKey k2 = RevisionsKey.fromString(k1.asString());
         assertEquals(k1, k2);
     }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java Thu Jan  7 12:46:35 2016
@@ -27,6 +27,7 @@ import org.apache.jackrabbit.oak.commons
 import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
 import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
 import org.apache.jackrabbit.oak.plugins.document.Revision;
+import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
@@ -126,6 +127,20 @@ public class UtilsTest {
     }
 
     @Test
+    public void min() {
+        Revision a = new Revision(42, 1, 1);
+        Revision b = new Revision(43, 0, 1);
+        assertSame(a, Utils.min(a, b));
+
+        Revision a1 = new Revision(42, 0, 1);
+        assertSame(a1, Utils.min(a, a1));
+
+        assertSame(a, Utils.min(a, null));
+        assertSame(a, Utils.min(null, a));
+        assertNull(Utils.max(null, null));
+    }
+
+    @Test
     public void getAllDocuments() throws CommitFailedException {
         DocumentNodeStore store = new DocumentMK.Builder().getNodeStore();
         try {
@@ -179,4 +194,24 @@ public class UtilsTest {
         revTime = Utils.getMaxExternalTimestamp(revs, localClusterId);
         assertEquals(3, revTime);
     }
+
+    @Test
+    public void getMinTimestampForDiff() {
+        RevisionVector from = new RevisionVector(new Revision(17, 0, 1));
+        RevisionVector to = new RevisionVector(new Revision(19, 0, 1));
+        assertEquals(17, Utils.getMinTimestampForDiff(from, to, new RevisionVector()));
+        assertEquals(17, Utils.getMinTimestampForDiff(to, from, new RevisionVector()));
+
+        RevisionVector minRevs = new RevisionVector(
+                new Revision(7, 0, 1),
+                new Revision(4, 0, 2));
+        assertEquals(17, Utils.getMinTimestampForDiff(from, to, minRevs));
+        assertEquals(17, Utils.getMinTimestampForDiff(to, from, minRevs));
+
+        to = to.update(new Revision(15, 0, 2));
+        // must return min revision of clusterId 2
+        assertEquals(4, Utils.getMinTimestampForDiff(from, to, minRevs));
+        assertEquals(4, Utils.getMinTimestampForDiff(to, from, minRevs));
+
+    }
 }

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java Thu Jan  7 12:46:35 2016
@@ -102,7 +102,7 @@ public class DocumentNodeStoreHelper {
         int numBlobs = 0;
 
         List<Blob> blobs = Lists.newArrayList();
-        Revision head = ns.getHeadRevision();
+        RevisionVector head = ns.getHeadRevision();
         boolean exists = doc.getNodeAtRevision(ns, head, null) != null;
         for (String key : doc.keySet()) {
             if (!Utils.isPropertyName(key)) {