Author: mreutegg
Date: Mon Aug 29 12:32:50 2016
New Revision: 1758213

URL: http://svn.apache.org/viewvc?rev=1758213&view=rev
Log:
OAK-4715: Reduce DocumentStore reads for local changes

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1758213&r1=1758212&r2=1758213&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 Mon Aug 29 12:32:50 2016
@@ -1123,12 +1123,20 @@ public final class DocumentNodeStore
                       List<String> removed, List<String> changed,
                       DiffCache.Entry cacheEntry) {
         if (isNew) {
+            // determine the revision for the nodeChildrenCache entry when
+            // the node is new. Fallback to after revision in case document
+            // is not in the cache. (OAK-4715)
+            NodeDocument doc = store.getIfCached(NODES, getIdFromPath(path));
+            RevisionVector afterLastRev = after;
+            if (doc != null) {
+                afterLastRev = new RevisionVector(doc.getLastRev().values());
+                afterLastRev = afterLastRev.update(rev);
+            }
             if (added.isEmpty()) {
                 // this is a leaf node.
                 // check if it has the children flag set
-                NodeDocument doc = store.find(NODES, getIdFromPath(path));
                 if (doc != null && doc.hasChildren()) {
-                    PathRev key = childNodeCacheKey(path, after, null);
+                    PathRev key = childNodeCacheKey(path, afterLastRev, null);
                     LOG.debug("nodeChildrenCache.put({},{})", key, 
"NO_CHILDREN");
                     nodeChildrenCache.put(key, DocumentNodeState.NO_CHILDREN);
                 }
@@ -1139,7 +1147,7 @@ public final class DocumentNodeStore
                     set.add(Utils.unshareString(PathUtils.getName(p)));
                 }
                 c.children.addAll(set);
-                PathRev key = childNodeCacheKey(path, after, null);
+                PathRev key = childNodeCacheKey(path, afterLastRev, null);
                 LOG.debug("nodeChildrenCache.put({},{})", key, c);
                 nodeChildrenCache.put(key, c);
             }

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1758213&r1=1758212&r2=1758213&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
 Mon Aug 29 12:32:50 2016
@@ -76,6 +76,7 @@ import com.google.common.collect.Sets;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.json.JsopDiff;
 import org.apache.jackrabbit.oak.plugins.commit.AnnotatingConflictHandler;
 import org.apache.jackrabbit.oak.plugins.commit.ConflictHook;
 import org.apache.jackrabbit.oak.plugins.commit.ConflictValidatorProvider;
@@ -2734,6 +2735,64 @@ public class DocumentNodeStoreTest {
         }
     }
 
+    // OAK-4715
+    @Test
+    public void localChangesFromCache() throws Exception {
+        final AtomicInteger numQueries = new AtomicInteger();
+        DocumentStore store = new MemoryDocumentStore() {
+            @Nonnull
+            @Override
+            public <T extends Document> List<T> query(Collection<T> collection,
+                                                      String fromKey,
+                                                      String toKey,
+                                                      int limit) {
+                numQueries.incrementAndGet();
+                return super.query(collection, fromKey, toKey, limit);
+            }
+        };
+        DocumentNodeStore ns1 = builderProvider.newBuilder().setClusterId(1)
+                .setDocumentStore(store).getNodeStore();
+        NodeBuilder builder = ns1.getRoot().builder();
+        builder.child("node-1");
+        merge(ns1, builder);
+        ns1.runBackgroundOperations();
+        DocumentNodeStore ns2 = builderProvider.newBuilder().setClusterId(2)
+                .setDocumentStore(store).getNodeStore();
+        builder = ns2.getRoot().builder();
+        builder.child("node-2");
+        merge(ns2, builder);
+        ns2.runBackgroundOperations();
+        ns1.runBackgroundOperations();
+
+        NodeState before = ns1.getRoot();
+
+        builder = before.builder();
+        builder.child("node-1").child("foo").child("bar");
+        NodeState after = merge(ns1, builder);
+
+        numQueries.set(0);
+        JsopDiff.diffToJsop(before, after);
+        assertEquals(0, numQueries.get());
+
+        before = after;
+        builder = ns1.getRoot().builder();
+        builder.child("node-1").child("foo").child("bar").setProperty("p", 1);
+        after = merge(ns1, builder);
+
+        numQueries.set(0);
+        JsopDiff.diffToJsop(before, after);
+        assertEquals(0, numQueries.get());
+
+        before = after;
+        builder = ns1.getRoot().builder();
+        builder.child("node-1").child("foo").child("bar").remove();
+        after = merge(ns1, builder);
+
+        numQueries.set(0);
+        JsopDiff.diffToJsop(before, after);
+        assertEquals(0, numQueries.get());
+    }
+
     private static class TestException extends RuntimeException {
 
     }


Reply via email to