Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java (revision 1558009) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java (working copy) @@ -452,6 +452,10 @@ addOrRemove.addAll(addedNodes); addOrRemove.addAll(removedNodes); for (String p : addOrRemove) { + if (PathUtils.denotesRoot(p)) { + // special case: root node was added + continue; + } String parent = PathUtils.getParentPath(p); ArrayList list = nodesWithChangedChildren.get(parent); if (list == null) { @@ -478,7 +482,7 @@ boolean pendingLastRev = op == null || !NodeDocument.hasLastRev(op, revision.getClusterId()); boolean isDelete = op != null && op.isDelete(); - nodeStore.applyChanges(revision, path, isNew, isDelete, pendingLastRev, isBranchCommit, added, removed); + nodeStore.applyChanges(revision, baseRevision, path, isNew, isDelete, pendingLastRev, isBranchCommit, added, removed); } } Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java (revision 1558009) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java (working copy) @@ -677,6 +677,15 @@ @CheckForNull Node readNode(String path, Revision readRevision) { + if (!PathUtils.denotesRoot(path)) { + // check children cache first + String parentKey = PathUtils.getParentPath(path) + + "@" + readRevision; + Node.Children c = nodeChildrenCache.getIfPresent(parentKey); + if (c != null && !c.hasMore && !c.children.contains(path)) { + return null; + } + } String id = Utils.getIdFromPath(path); Revision lastRevision = getPendingModifications().get(path); NodeDocument doc = store.find(Collection.NODES, id); @@ -689,7 +698,8 @@ /** * Apply the changes of a node to the cache. * - * @param rev the revision + * @param rev the commit revision. + * @param base the base revision of the commit. * @param path the path * @param isNew whether this is a new node * @param isDelete whether the node is deleted @@ -699,7 +709,7 @@ * @param removed the list of removed child nodes * */ - public void applyChanges(Revision rev, String path, + public void applyChanges(Revision rev, Revision base, String path, boolean isNew, boolean isDelete, boolean pendingLastRev, boolean isBranchCommit, ArrayList added, ArrayList removed) { @@ -723,20 +733,38 @@ } } } - String key = path + "@" + rev; + String key = path + "@" + (isBranchCommit ? rev.asBranchRevision() : rev); Node.Children c = nodeChildrenCache.getIfPresent(key); if (isNew || (!isDelete && c != null)) { + // we can put the result of the operations into the + // cache if this is a new node. there can be no other + // commit adding children to this node concurrently Node.Children c2 = new Node.Children(); TreeSet set = new TreeSet(); if (c != null) { set.addAll(c.children); } set.removeAll(removed); - for (String name : added) { - set.add(Utils.unshareString(name)); + for (String p : added) { + set.add(Utils.unshareString(p)); } c2.children.addAll(set); nodeChildrenCache.put(key, c2); + } else if (isBranchCommit) { + // branch commits are isolated, hence we can calculate + // the new cache entry from the entry for the base revision + // (if available and complete). + c = nodeChildrenCache.getIfPresent(path + "@" + base); + if (c != null && !c.hasMore) { + Node.Children c2 = new Node.Children(); + TreeSet set = new TreeSet(c.children); + set.removeAll(removed); + for (String p : added) { + set.add(Utils.unshareString(p)); + } + c2.children.addAll(set); + nodeChildrenCache.put(key, c2); + } } if (!added.isEmpty()) { NodeDocument.Children docChildren = docChildrenCache.getIfPresent(path); Index: oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java (revision 1558009) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java (working copy) @@ -71,16 +71,17 @@ @Test public void addNodeGetNode() { MongoMK mk = new MongoMK.Builder().open(); - Revision rev = Revision.fromString(mk.getHeadRevision()); + MongoNodeStore ns = mk.getNodeStore(); + Revision rev = ns.newRevision(); Node n = new Node("/test", rev); n.setProperty("name", "Hello"); UpdateOp op = n.asOperation(true); // mark as commit root NodeDocument.setRevision(op, rev, "c"); DocumentStore s = mk.getDocumentStore(); - MongoNodeStore ns = mk.getNodeStore(); assertTrue(s.create(Collection.NODES, Lists.newArrayList(op))); Node n2 = ns.getNode("/test", rev); + assertNotNull(n2); assertEquals("Hello", n2.getProperty("name")); mk.dispose(); }