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 ba...@apache.org on 2016/09/28 15:25:56 UTC

svn commit: r1762683 - in /jackrabbit/oak/branches/1.4: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/

Author: baedke
Date: Wed Sep 28 15:25:56 2016
New Revision: 1762683

URL: http://svn.apache.org/viewvc?rev=1762683&view=rev
Log:
OAK-4539: Calculate children cache entry on commit

Modified:
    jackrabbit/oak/branches/1.4/   (props changed)
    jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
    jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
    jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java

Propchange: jackrabbit/oak/branches/1.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 28 15:25:56 2016
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735081,1735141,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738136,1738138,1738207,1738234,1738252,1738775,1738795,1738833,1738950,1738957,1738963,1739712,1739760,1739867,1739894,1739959-1739960,1740114,1740116,1740250,1740333,1740349,1740360,1740625-1740626,1740774,1740837,1740879,1740971,1741016,1741032,1741339,1741343,1742077,1742117,1742125,1742363,1742520,1742888,1742916,1743097,1743172,1743343,1743674,1744265,1744292,1744589,1744670,1744672,1744959,1745038,1745127,1745197,1745336,1745368,1746086,1746117,1746342,1746345,1746408,1746696,1746981,1747198,1747200,1747341-1747342,1747380,1747387,1747406,1747492,1747512,1747654,1748505,1748553,1748722,1748870,1749275,1749350,1749424,1749443,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287,1750457,1750462
 ,1750465,1750495,1750626,1750809,1750886,1751410,1751445-1751446,1751478,1751755,1751871,1752198,1752202,1752259,1752273-1752274,1752283,1752292,1752438,1752447-1752448,1752508,1752596,1752616,1752659,1752672,1753262,1753331-1753332,1753335-1753336,1753355,1753444,1754117,1754239,1755157,1755191,1756520,1756580,1757119,1757166,1759433,1760340,1760373,1760387,1760661-1760662,1761412,1761444,1761571,1761762,1761787,1761876,1762453,1762635
+/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735081,1735141,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738136,1738138,1738207,1738234,1738252,1738775,1738795,1738833,1738950,1738957,1738963,1739712,1739760,1739867,1739894,1739959-1739960,1740114,1740116,1740250,1740333,1740349,1740360,1740625-1740626,1740774,1740837,1740879,1740971,1741016,1741032,1741339,1741343,1742077,1742117,1742125,1742363,1742520,1742888,1742916,1743097,1743172,1743343,1743674,1744265,1744292,1744589,1744670,1744672,1744959,1745038,1745127,1745197,1745336,1745368,1746086,1746117,1746342,1746345,1746408,1746696,1746981,1747198,1747200,1747341-1747342,1747380,1747387,1747406,1747492,1747512,1747654,1748505,1748553,1748722,1748870,1749275,1749350,1749424,1749443,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287,1750457,1750462
 ,1750465,1750495,1750626,1750809,1750886,1751410,1751445-1751446,1751478,1751753,1751755,1751871,1752198,1752202,1752259,1752273-1752274,1752283,1752292,1752438,1752447-1752448,1752508,1752596,1752616,1752659,1752672,1753262,1753331-1753332,1753335-1753336,1753355,1753444,1754117,1754239,1755157,1755191,1756520,1756580,1757119,1757166,1759433,1760340,1760373,1760387,1760661-1760662,1761412,1761444,1761571,1761762,1761787,1761876,1762453,1762635
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java?rev=1762683&r1=1762682&r2=1762683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java Wed Sep 28 15:25:56 2016
@@ -661,7 +661,7 @@ public class Commit {
                 // track intermediate node and root
                 tracker.track(path);
             }
-            nodeStore.applyChanges(after, path, isNew,
+            nodeStore.applyChanges(before, after, rev, path, isNew,
                     added, removed, changed, cacheEntry);
         }
         cacheEntry.done();

Modified: jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1762683&r1=1762682&r2=1762683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Wed Sep 28 15:25:56 2016
@@ -461,9 +461,7 @@ public final class DocumentNodeStore
             DocumentNodeState n = new DocumentNodeState(this, "/", head);
             commit.addNode(n);
             commit.applyToDocumentStore();
-            // use dummy Revision as before
-            RevisionVector before = new RevisionVector(new Revision(0, 0, clusterId));
-            commit.applyToCache(before, false);
+            unsavedLastRevisions.put("/", commitRev);
             setRoot(head);
             // make sure _lastRev is written back to store
             backgroundWrite();
@@ -1118,27 +1116,101 @@ public final class DocumentNodeStore
     /**
      * Apply the changes of a node to the cache.
      *
+     * @param before the before revision (old head)
+     * @param after the after revision (new head)
      * @param rev the commit revision
      * @param path the path
      * @param isNew whether this is a new node
      * @param added the list of added child nodes
      * @param removed the list of removed child nodes
-     * @param changed the list of changed child nodes.
+     * @param changed the list of changed child nodes
      *
      */
-    void applyChanges(RevisionVector rev, String path,
+    void applyChanges(RevisionVector before, RevisionVector after,
+                      Revision rev, String path,
                       boolean isNew, List<String> added,
                       List<String> removed, List<String> changed,
                       DiffCache.Entry cacheEntry) {
-        if (isNew && !added.isEmpty()) {
-            DocumentNodeState.Children c = new DocumentNodeState.Children();
-            Set<String> set = Sets.newTreeSet();
-            for (String p : added) {
-                set.add(Utils.unshareString(PathUtils.getName(p)));
-            }
-            c.children.addAll(set);
-            PathRev key = childNodeCacheKey(path, rev, null);
-            nodeChildrenCache.put(key, c);
+        if (isNew) {
+            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);
+                    LOG.debug("nodeChildrenCache.put({},{})", key, "NO_CHILDREN");
+                    nodeChildrenCache.put(key, DocumentNodeState.NO_CHILDREN);
+                }
+            } else {
+                DocumentNodeState.Children c = new DocumentNodeState.Children();
+                Set<String> set = Sets.newTreeSet();
+                for (String p : added) {
+                    set.add(Utils.unshareString(PathUtils.getName(p)));
+                }
+                c.children.addAll(set);
+                PathRev key = childNodeCacheKey(path, after, null);
+                LOG.debug("nodeChildrenCache.put({},{})", key, c);
+                nodeChildrenCache.put(key, c);
+            }
+        } else {
+            // existed before
+            DocumentNodeState beforeState = getRoot(before);
+            // do we have a cached before state that can be used
+            // to calculate the new children?
+            int depth = PathUtils.getDepth(path);
+            for (int i = 1; i <= depth && beforeState != null; i++) {
+                String p = PathUtils.getAncestorPath(path, depth - i);
+                PathRev key = new PathRev(p, beforeState.getLastRevision());
+                beforeState = nodeCache.getIfPresent(key);
+            }
+            DocumentNodeState.Children children = null;
+            if (beforeState != null) {
+                if (beforeState.hasNoChildren()) {
+                    children = DocumentNodeState.NO_CHILDREN;
+                } else {
+                    PathRev key = childNodeCacheKey(path, beforeState.getLastRevision(), null);
+                    children = nodeChildrenCache.getIfPresent(key);
+                }
+            }
+            if (children != null) {
+                PathRev afterKey = new PathRev(path, before.update(rev));
+                // are there any added or removed children?
+                if (added.isEmpty() && removed.isEmpty()) {
+                    // simply use the same list
+                    LOG.debug("nodeChildrenCache.put({},{})", afterKey, children);
+                    nodeChildrenCache.put(afterKey, children);
+                } else if (!children.hasMore){
+                    // list is complete. use before children as basis
+                    Set<String> afterChildren = Sets.newTreeSet(children.children);
+                    for (String p : added) {
+                        afterChildren.add(Utils.unshareString(PathUtils.getName(p)));
+                    }
+                    for (String p : removed) {
+                        afterChildren.remove(PathUtils.getName(p));
+                    }
+                    DocumentNodeState.Children c = new DocumentNodeState.Children();
+                    c.children.addAll(afterChildren);
+                    if (c.children.size() <= DocumentNodeState.MAX_FETCH_SIZE) {
+                        LOG.debug("nodeChildrenCache.put({},{})", afterKey, c);
+                        nodeChildrenCache.put(afterKey, c);
+                    } else {
+                        LOG.info("not caching more than {} child names for {}",
+                                DocumentNodeState.MAX_FETCH_SIZE, path);
+                    }
+                } else if (added.isEmpty()) {
+                    // incomplete list, but we only removed nodes
+                    // use linked hash set to retain order
+                    Set<String> afterChildren = Sets.newLinkedHashSet(children.children);
+                    for (String p : removed) {
+                        afterChildren.remove(PathUtils.getName(p));
+                    }
+                    DocumentNodeState.Children c = new DocumentNodeState.Children();
+                    c.children.addAll(afterChildren);
+                    c.hasMore = true;
+                    LOG.debug("nodeChildrenCache.put({},{})", afterKey, c);
+                    nodeChildrenCache.put(afterKey, c);
+                }
+            }
         }
 
         // update diff cache

Modified: jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1762683&r1=1762682&r2=1762683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java Wed Sep 28 15:25:56 2016
@@ -218,14 +218,8 @@ public class DocumentNodeStoreTest {
         }
         store.merge(root, EmptyHook.INSTANCE, CommitInfo.EMPTY);
         counter.set(0);
-        // the following should just make one call to DocumentStore.query()
-        for (ChildNodeEntry e : store.getRoot().getChildNodeEntries()) {
-            e.getNodeState();
-        }
-        assertEquals(1, counter.get());
-
-        counter.set(0);
-        // now the child node entries are cached and no call should happen
+        // the following must read from the nodeChildrenCache populated by
+        // the commit and not use a query on the document store (OAK-1322)
         for (ChildNodeEntry e : store.getRoot().getChildNodeEntries()) {
             e.getNodeState();
         }
@@ -2228,6 +2222,8 @@ public class DocumentNodeStoreTest {
         NodeState afterTest = after.getChildNode("test");
 
         startValues.clear();
+        // make sure diff is not served from node children cache entries
+        ns.invalidateNodeChildrenCache();
         afterTest.compareAgainstBaseState(beforeTest, new DefaultNodeStateDiff());
 
         assertEquals(1, startValues.size());

Modified: jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java?rev=1762683&r1=1762682&r2=1762683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeStoreDiffTest.java Wed Sep 28 15:25:56 2016
@@ -131,11 +131,18 @@ public class NodeStoreDiffTest {
                 //but less then lastRev of the of readRevision. Where readRevision is the rev of root node when
                 //rebase was performed
 
+                // remember paths accessed so far
+                List<String> paths = Lists.newArrayList(tds.paths);
+
                 //This is not to be done in actual cases as CommitHooks are invoked in critical sections
                 //and creating nodes from within CommitHooks would cause deadlock. This is done here to ensure
                 //that changes are done when rebase has been performed and merge is about to happen
                 createNodes("/oak:index/prop-b/b1");
 
+                // reset accessed paths
+                tds.reset();
+                tds.paths.addAll(paths);
+
                 //For now we the cache is disabled (size 0) so this is not required
                 //ns.nodeCache.invalidateAll();