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 2017/02/14 08:01:35 UTC

svn commit: r1782924 - in /jackrabbit/oak/branches/1.6: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeDocumentTest.java

Author: mreutegg
Date: Tue Feb 14 08:01:35 2017
New Revision: 1782924

URL: http://svn.apache.org/viewvc?rev=1782924&view=rev
Log:
OAK-5559: Reduce reads with overlapping previous documents

Merged revisions 1781248,1782029 from trunk

Modified:
    jackrabbit/oak/branches/1.6/   (props changed)
    jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
    jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeDocumentTest.java

Propchange: jackrabbit/oak/branches/1.6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Feb 14 08:01:35 2017
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1781068,1781075,1781386,1781846,1781907,1782000,1782196,1782447,1782770
+/jackrabbit/oak/trunk:1781068,1781075,1781248,1781386,1781846,1781907,1782000,1782029,1782196,1782447,1782770
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java?rev=1782924&r1=1782923&r2=1782924&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java (original)
+++ jackrabbit/oak/branches/1.6/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java Tue Feb 14 08:01:35 2017
@@ -52,6 +52,7 @@ import org.apache.jackrabbit.oak.commons
 import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
 import org.apache.jackrabbit.oak.commons.json.JsopWriter;
 import org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore;
+import org.apache.jackrabbit.oak.plugins.document.util.MergeSortedIterators;
 import org.apache.jackrabbit.oak.plugins.document.util.Utils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -1643,8 +1644,34 @@ public final class NodeDocument extends
                 }
             };
         } else {
-            changes = mergeSorted(transform(copyOf(ranges), rangeToChanges),
-                    ValueComparator.REVERSE);
+            changes = new Iterable<Entry<Revision, String>>() {
+                private List<Range> rangeList = copyOf(ranges);
+                private Iterable<Iterable<Entry<Revision, String>>> changesPerRange
+                        = transform(rangeList, rangeToChanges);
+                @Override
+                public Iterator<Entry<Revision, String>> iterator() {
+                    final Iterator<Iterable<Entry<Revision, String>>> it
+                            = checkNotNull(changesPerRange.iterator());
+                    return new MergeSortedIterators<Entry<Revision, String>>(ValueComparator.REVERSE) {
+                        @Override
+                        public Iterator<Entry<Revision, String>> nextIterator() {
+                            while (it.hasNext()) {
+                                Iterator<Entry<Revision, String>> next = it.next().iterator();
+                                // check if this even has elements
+                                if (next.hasNext()) {
+                                    return next;
+                                }
+                            }
+                            return null;
+                        }
+
+                        @Override
+                        public String description() {
+                            return "Ranges to merge sort: " + rangeList;
+                        }
+                    };
+                }
+            };
         }
         return filter(changes, new Predicate<Entry<Revision, String>>() {
             @Override

Modified: jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeDocumentTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeDocumentTest.java?rev=1782924&r1=1782923&r2=1782924&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeDocumentTest.java (original)
+++ jackrabbit/oak/branches/1.6/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeDocumentTest.java Tue Feb 14 08:01:35 2017
@@ -46,10 +46,13 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.COLLISIONS;
 import static org.apache.jackrabbit.oak.plugins.document.TestUtils.NO_BINARY;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.getRootDocument;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.Matchers.lessThan;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -757,6 +760,65 @@ public class NodeDocumentTest {
     }
 
     @Test
+    public void readsWithOverlappingPreviousDocuments() throws Exception {
+        final Map<String, Document> prevDocCalls = newLinkedHashMap();
+        MemoryDocumentStore store = new MemoryDocumentStore() {
+            @Override
+            public <T extends Document> T find(Collection<T> collection,
+                                               String key) {
+                T doc = super.find(collection, key);
+                if (collection == NODES && Utils.getPathFromId(key).startsWith("p")) {
+                    prevDocCalls.put(key, doc);
+                }
+                return doc;
+            }
+        };
+        Random random = new Random(42);
+        DocumentNodeStore ns = createTestStore(store, 1, 0);
+        List<RevisionVector> headRevisions = Lists.newArrayList();
+
+        for (int i = 0; i < 1000; i++) {
+            NodeBuilder builder = ns.getRoot().builder();
+            NodeBuilder test = builder.child("test");
+            test.setProperty("p", i);
+            // maintain four other properties and update
+            // them with different probabilities
+            for (int j = 0; j < 4; j++) {
+                if (random.nextInt(j + 1) == 0) {
+                    test.setProperty("p" + j, i);
+                }
+            }
+            merge(ns, builder);
+            headRevisions.add(ns.getHeadRevision());
+            if (i % 3 == 0) {
+                // split the document
+                RevisionVector head = ns.getHeadRevision();
+                NodeDocument doc = store.find(NODES, Utils.getIdFromPath("/test"));
+                for (UpdateOp op : SplitOperations.forDocument(
+                        doc, ns, head, NO_BINARY, 2)) {
+                    store.createOrUpdate(NODES, op);
+                }
+            }
+        }
+        ns.runBackgroundOperations();
+
+        NodeDocument doc = store.find(NODES, Utils.getIdFromPath("/test"));
+        List<Integer> numCalls = Lists.newArrayList();
+        long count = 0;
+        // go back in time and check number of find calls
+        for (RevisionVector rv : headRevisions) {
+            prevDocCalls.clear();
+            DocumentNodeState s = doc.getNodeAtRevision(ns, rv, null);
+            assertNotNull(s);
+            assertEquals(count++, s.getProperty("p").getValue(Type.LONG).longValue());
+            numCalls.add(prevDocCalls.size());
+        }
+        assertThat(numCalls.toString(), numCalls, everyItem(lessThan(36)));
+
+        ns.dispose();
+    }
+
+    @Test
     public void getVisibleChanges() throws Exception {
         final int numChanges = 200;
         Random random = new Random();