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 to...@apache.org on 2016/12/21 11:01:27 UTC

svn commit: r1775389 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex: MultiplexingNodeBuilder.java MultiplexingNodeState.java

Author: tomekr
Date: Wed Dec 21 11:01:27 2016
New Revision: 1775389

URL: http://svn.apache.org/viewvc?rev=1775389&view=rev
Log:
OAK-5222: Optimize the multiplexing node store

-don't use the root states for resolving children

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeBuilder.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeState.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeBuilder.java?rev=1775389&r1=1775388&r2=1775389&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeBuilder.java Wed Dec 21 11:01:27 2016
@@ -34,6 +34,7 @@ import java.util.Map;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.ImmutableMap.copyOf;
 import static com.google.common.collect.Iterables.concat;
 import static com.google.common.collect.Iterables.filter;
@@ -55,19 +56,28 @@ class MultiplexingNodeBuilder implements
 
     private final Map<MountedNodeStore, NodeBuilder> nodeBuilders;
 
-    private final Map<MountedNodeStore, NodeBuilder> rootBuilders;
-
     private final MountedNodeStore owningStore;
 
-    MultiplexingNodeBuilder(String path, Map<MountedNodeStore, NodeBuilder> nodeBuilders, Map<MountedNodeStore, NodeBuilder> rootBuilders, MultiplexingContext ctx) {
-        checkArgument(nodeBuilders.size() == ctx.getStoresCount(), "Got %s builders but the context manages %s stores", nodeBuilders.size(), ctx.getStoresCount());
-        checkArgument(rootBuilders.size() == ctx.getStoresCount(), "Got %s builders but the context manages %s stores", rootBuilders.size(), ctx.getStoresCount());
+    private final MultiplexingNodeBuilder parent;
+
+    private final MultiplexingNodeBuilder rootBuilder;
+
+    MultiplexingNodeBuilder(String path, Map<MountedNodeStore, NodeBuilder> nodeBuilders, MultiplexingContext ctx) {
+        this(path, nodeBuilders, ctx, null);
+    }
 
+    private MultiplexingNodeBuilder(String path, Map<MountedNodeStore, NodeBuilder> nodeBuilders, MultiplexingContext ctx, MultiplexingNodeBuilder parent) {
+        checkArgument(nodeBuilders.size() == ctx.getStoresCount(), "Got %s builders but the context manages %s stores", nodeBuilders.size(), ctx.getStoresCount());
         this.path = path;
         this.ctx = ctx;
         this.nodeBuilders = newHashMap(nodeBuilders);
-        this.rootBuilders = copyOf(rootBuilders);
         this.owningStore = ctx.getOwningStore(path);
+        this.parent = parent;
+        if (parent == null) {
+            this.rootBuilder = this;
+        } else {
+            this.rootBuilder = parent.rootBuilder;
+        }
     }
 
     Map<MountedNodeStore, NodeBuilder> getBuilders() {
@@ -76,21 +86,23 @@ class MultiplexingNodeBuilder implements
 
     @Override
     public NodeState getNodeState() {
-        Map<MountedNodeStore, NodeState> rootNodes = buildersToNodeStates(rootBuilders);
-        return new MultiplexingNodeState(path, rootNodes, ctx);
+        return new MultiplexingNodeState(path, buildersToNodeStates(nodeBuilders), ctx);
     }
 
     @Override
     public NodeState getBaseState() {
-        Map<MountedNodeStore, NodeState> rootNodes = buildersToBaseStates(rootBuilders);
-        return new MultiplexingNodeState(path, rootNodes, ctx);
+        return new MultiplexingNodeState(path, buildersToBaseStates(nodeBuilders), ctx);
     }
 
     private static Map<MountedNodeStore, NodeState> buildersToNodeStates(Map<MountedNodeStore, NodeBuilder> builders) {
         return copyOf(transformValues(builders, new Function<NodeBuilder, NodeState>() {
             @Override
             public NodeState apply(NodeBuilder input) {
-                return input.getNodeState();
+                if (input.exists()) {
+                    return input.getNodeState();
+                } else {
+                    return MISSING_NODE;
+                }
             }
         }));
     }
@@ -242,21 +254,15 @@ class MultiplexingNodeBuilder implements
 
     @Override
     public NodeBuilder child(String name) {
-        String childPath = PathUtils.concat(path, name);
-        MountedNodeStore mountedNodeStore = ctx.getOwningStore(childPath);
-        createAncestors(mountedNodeStore);
-        nodeBuilders.get(mountedNodeStore).child(name);
-        return getChildNode(name);
+        if (hasChildNode(name)) {
+            return getChildNode(name);
+        } else {
+            return setChildNode(name);
+        }
     }
 
     private void createAncestors(MountedNodeStore mountedNodeStore) {
-        if (mountedNodeStore == owningStore) {
-            return;
-        }
-        if (nodeBuilders.get(mountedNodeStore).exists()) {
-            return;
-        }
-        NodeBuilder builder = rootBuilders.get(mountedNodeStore);
+        NodeBuilder builder = rootBuilder.nodeBuilders.get(mountedNodeStore);
         for (String element : PathUtils.elements(path)) {
             builder = builder.child(element);
         }
@@ -270,12 +276,11 @@ class MultiplexingNodeBuilder implements
         if (!nodeBuilders.get(mountedStore).hasChildNode(name)) {
             return MISSING_NODE.builder();
         }
-
         Map<MountedNodeStore, NodeBuilder> newNodeBuilders = newHashMap();
         for (MountedNodeStore mns : ctx.getAllMountedNodeStores()) {
             newNodeBuilders.put(mns, nodeBuilders.get(mns).getChildNode(name));
         }
-        return new MultiplexingNodeBuilder(childPath, newNodeBuilders, rootBuilders, ctx);
+        return new MultiplexingNodeBuilder(childPath, newNodeBuilders, ctx, this);
     }
 
     @Override
@@ -285,11 +290,23 @@ class MultiplexingNodeBuilder implements
 
     @Override
     public NodeBuilder setChildNode(String name, NodeState nodeState) {
+        checkState(exists(), "This builder does not exist: " + PathUtils.getName(path));
+
         String childPath = PathUtils.concat(path, name);
-        MountedNodeStore mountedNodeStore = ctx.getOwningStore(childPath);
-        createAncestors(mountedNodeStore);
-        nodeBuilders.get(mountedNodeStore).setChildNode(name, nodeState);
-        return getChildNode(name);
+        MountedNodeStore childStore = ctx.getOwningStore(childPath);
+        if (childStore != owningStore && !nodeBuilders.get(childStore).exists()) {
+            createAncestors(childStore);
+        }
+        NodeBuilder childBuilder = nodeBuilders.get(childStore).setChildNode(name, nodeState);
+
+        Map<MountedNodeStore, NodeBuilder> newNodeBuilders = newHashMap();
+        newNodeBuilders.put(childStore, childBuilder);
+        for (MountedNodeStore mns : ctx.getAllMountedNodeStores()) {
+            if (!newNodeBuilders.containsKey(mns)) {
+                newNodeBuilders.put(mns, nodeBuilders.get(mns).getChildNode(name));
+            }
+        }
+        return new MultiplexingNodeBuilder(childPath, newNodeBuilders, ctx, this);
     }
 
     @Override
@@ -337,22 +354,21 @@ class MultiplexingNodeBuilder implements
         // having a source path annotation or until we hit the root
         MultiplexingNodeBuilder builder = this;
         String sourcePath = getSourcePathAnnotation(builder);
-        while (sourcePath == null && !"/".equals(builder.path)) {
-            String parentPath = PathUtils.getParentPath(builder.path);
-            builder = getBuilderByPath(parentPath);
+        while (sourcePath == null && builder.parent != null) {
+            builder = builder.parent;
             sourcePath = getSourcePathAnnotation(builder);
         }
 
         if (sourcePath == null) {
             // Neither self nor any parent has a source path annotation. The source
             // path is just the path of this builder
-            return path;
+            return getPath();
         } else {
             // The source path is the source path of the first parent having a source
             // path annotation with the relative path from this builder up to that
             // parent appended.
             return PathUtils.concat(sourcePath,
-                    PathUtils.relativize(builder.path, path));
+                    PathUtils.relativize(builder.getPath(), getPath()));
         }
     }
 
@@ -368,33 +384,15 @@ class MultiplexingNodeBuilder implements
         }
     }
 
-    private boolean isTransientlyAdded(String sourcePath) {
-        NodeState node = rootBuilders.get(owningStore).getBaseState();
-        for (String name : PathUtils.elements(sourcePath)) {
+    private boolean isTransientlyAdded(String path) {
+        NodeState node = rootBuilder.getBaseState();
+        for (String name : PathUtils.elements(path)) {
             node = node.getChildNode(name);
         }
         return !node.exists();
     }
 
-    private MultiplexingNodeBuilder getBuilderByPath(String path) {
-        return new MultiplexingNodeBuilder(path, getBuildersByPath(rootBuilders, path), rootBuilders, ctx);
-    }
-
-    private static Map<MountedNodeStore, NodeBuilder> getBuildersByPath(Map<MountedNodeStore, NodeBuilder> rootNodes, final String path) {
-        return copyOf(transformValues(rootNodes, new Function<NodeBuilder, NodeBuilder>() {
-            @Override
-            public NodeBuilder apply(NodeBuilder input) {
-                NodeBuilder result = input;
-                for (String element : PathUtils.elements(path)) {
-                    if (result.hasChildNode(element)) {
-                        result = result.getChildNode(element);
-                    } else {
-                        result = MISSING_NODE.builder();
-                        break;
-                    }
-                }
-                return result;
-            }
-        }));
+    private String getPath() {
+        return path;
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeState.java?rev=1775389&r1=1775388&r2=1775389&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeState.java Wed Dec 21 11:01:27 2016
@@ -67,27 +67,12 @@ class MultiplexingNodeState extends Abst
 
     private final MountedNodeStore owningStore;
 
-    private final Map<MountedNodeStore, NodeState> rootStates;
-
     private final Map<MountedNodeStore, NodeState> nodeStates;
 
-    MultiplexingNodeState(String path, Map<MountedNodeStore, NodeState> rootStates, MultiplexingContext ctx) {
-        checkArgument(rootStates.size() == ctx.getStoresCount(), "Got %s node states but the context manages %s stores", rootStates.size(), ctx.getStoresCount());
-
-        this.path = path;
-        this.ctx = ctx;
-        this.rootStates = copyOf(rootStates);
-        this.nodeStates = copyOf(getNodesByPath(this.rootStates, path));
-        this.owningStore = ctx.getOwningStore(path);
-    }
-
-    MultiplexingNodeState(String path, Map<MountedNodeStore, NodeState> nodeStates, Map<MountedNodeStore, NodeState> rootStates, MultiplexingContext ctx) {
+    MultiplexingNodeState(String path, Map<MountedNodeStore, NodeState> nodeStates, MultiplexingContext ctx) {
         checkArgument(nodeStates.size() == ctx.getStoresCount(), "Got %s node states but the context manages %s stores", nodeStates.size(), ctx.getStoresCount());
-        checkArgument(rootStates.size() == ctx.getStoresCount(), "Got %s node states but the context manages %s stores", rootStates.size(), ctx.getStoresCount());
-
         this.path = path;
         this.ctx = ctx;
-        this.rootStates = copyOf(rootStates);
         this.nodeStates = copyOf(nodeStates);
         this.owningStore = ctx.getOwningStore(path);
     }
@@ -138,7 +123,7 @@ class MultiplexingNodeState extends Abst
         for (MountedNodeStore mns : ctx.getAllMountedNodeStores()) {
             newNodeStates.put(mns, nodeStates.get(mns).getChildNode(name));
         }
-        return new MultiplexingNodeState(childPath, newNodeStates, rootStates, ctx);
+        return new MultiplexingNodeState(childPath, newNodeStates, ctx);
     }
 
     @Override
@@ -216,52 +201,19 @@ class MultiplexingNodeState extends Abst
     // write operations
     @Override
     public NodeBuilder builder() {
-        Map<MountedNodeStore, NodeBuilder> rootBuilders = copyOf(transformValues(rootStates, new Function<NodeState, NodeBuilder>() {
+        Map<MountedNodeStore, NodeBuilder> nodeBuilders = copyOf(transformValues(nodeStates, new Function<NodeState, NodeBuilder>() {
             @Override
             public NodeBuilder apply(NodeState input) {
                 return input.builder();
             }
         }));
-        Map<MountedNodeStore, NodeBuilder> nodeBuilders = copyOf(transformValues(rootBuilders, new Function<NodeBuilder, NodeBuilder>() {
-            @Override
-            public NodeBuilder apply(NodeBuilder input) {
-                NodeBuilder result = input;
-                for (String element : PathUtils.elements(path)) {
-                    if (result.hasChildNode(element)) {
-                        result = result.getChildNode(element);
-                    } else {
-                        result = MISSING_NODE.builder();
-                        break;
-                    }
-                }
-                return result;
-            }
-        }));
-        return new MultiplexingNodeBuilder(path, nodeBuilders, rootBuilders, ctx);
+        return new MultiplexingNodeBuilder(path, nodeBuilders, ctx);
     }
 
     private NodeState getWrappedNodeState() {
         return nodeStates.get(owningStore);
     }
 
-    private static Map<MountedNodeStore, NodeState> getNodesByPath(Map<MountedNodeStore, NodeState> rootNodes, final String path) {
-        return copyOf(transformValues(rootNodes, new Function<NodeState, NodeState>() {
-            @Override
-            public NodeState apply(NodeState input) {
-                NodeState result = input;
-                for (String element : PathUtils.elements(path)) {
-                    if (result.hasChildNode(element)) {
-                        result = result.getChildNode(element);
-                    } else {
-                        result = MISSING_NODE;
-                        break;
-                    }
-                }
-                return result;
-            }
-        }));
-    }
-
     private class ChildrenDiffFilter implements NodeStateDiff {
 
         private final NodeStateDiff diff;