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;