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 ju...@apache.org on 2012/07/06 14:28:06 UTC
svn commit: r1358157 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/lucene/
main/java/org/apache/jackrabbit/oak/plugins/memory/
main/java/org/apache/jackrabbit/oak/spi/state/
test/java/org/apache/jackrabbit/oak/ker...
Author: jukka
Date: Fri Jul 6 12:28:06 2012
New Revision: 1358157
URL: http://svn.apache.org/viewvc?rev=1358157&view=rev
Log:
OAK-170: Child node state builder
Add the getChildBuilder() method and an initial implementation
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/OakDirectory.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateBuilder.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/OakDirectory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/OakDirectory.java?rev=1358157&r1=1358156&r2=1358157&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/OakDirectory.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/OakDirectory.java Fri Jul 6 12:28:06 2012
@@ -38,13 +38,9 @@ import org.apache.lucene.store.NoLockFac
class OakDirectory extends Directory {
- private final NodeStore store;
-
private final CoreValueFactory factory;
- private final String[] path;
-
- private final NodeStateBuilder[] builders;
+ private final NodeStateBuilder rootBuilder;
private final NodeStateBuilder directoryBuilder;
@@ -52,36 +48,20 @@ class OakDirectory extends Directory {
public OakDirectory(NodeStore store, NodeState root, String... path) {
this.lockFactory = NoLockFactory.getNoLockFactory();
- this.store = store;
this.factory = store.getValueFactory();
- this.path = path;
- this.builders = new NodeStateBuilder[path.length + 1];
+ this.rootBuilder = store.getBuilder(root);
- NodeState state = root;
- builders[0] = store.getBuilder(state);
+ NodeStateBuilder builder = rootBuilder;
for (int i = 0; i < path.length; i++) {
- NodeState child = state.getChildNode(path[i]);
- if (child == null) {
- builders[i + 1] = store.getBuilder(null);
- state = builders[i + 1].getNodeState();
- } else {
- builders[i + 1] = store.getBuilder(child);
- state = child;
- }
+ builder = builder.getChildBuilder(path[i]);
}
- this.directoryBuilder = builders[path.length];
- this.directory = state;
+ this.directoryBuilder = builder;
+ this.directory = null;
}
@Nonnull
public NodeState getRoot() {
- NodeState state = getDirectory();
- for (int i = 1; i <= path.length; i++) {
- builders[path.length - i].setNode(
- path[path.length - i], state);
- state = builders[path.length - i].getNodeState();
- }
- return state;
+ return rootBuilder.getNodeState();
}
@Nonnull
@@ -125,12 +105,10 @@ class OakDirectory extends Directory {
@Override
public void touchFile(String name) throws IOException {
- NodeState file = getDirectory().getChildNode(name);
- NodeStateBuilder builder = store.getBuilder(file);
+ NodeStateBuilder builder = directoryBuilder.getChildBuilder(name);
builder.setProperty(
"jcr:lastModified",
factory.createValue(System.currentTimeMillis()));
- directoryBuilder.setNode(name, builder.getNodeState());
directory = null;
}
@@ -319,7 +297,7 @@ class OakDirectory extends Directory {
}
NodeStateBuilder fileBuilder =
- store.getBuilder(getDirectory().getChildNode(name));
+ directoryBuilder.getChildBuilder(name);
fileBuilder.setProperty(
"jcr:lastModified",
factory.createValue(System.currentTimeMillis()));
@@ -327,7 +305,6 @@ class OakDirectory extends Directory {
"jcr:data",
factory.createValue(new ByteArrayInputStream(data)));
- directoryBuilder.setNode(name, fileBuilder.getNodeState());
directory = null;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java?rev=1358157&r1=1358156&r2=1358157&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java Fri Jul 6 12:28:06 2012
@@ -41,10 +41,11 @@ class MemoryNodeStateBuilder implements
new HashMap<String, PropertyState>();
/**
- * Set of added, modified or removed ({@code null} value) child node states.
+ * Set of builders for added, modified or removed ({@code null} value)
+ * child nodes.
*/
- private final Map<String, NodeState> nodes =
- new HashMap<String, NodeState>();
+ private final Map<String, NodeStateBuilder> builders =
+ new HashMap<String, NodeStateBuilder>();
public MemoryNodeStateBuilder(NodeState base) {
assert base != null;
@@ -53,9 +54,19 @@ class MemoryNodeStateBuilder implements
@Override
public NodeState getNodeState() {
- if (properties.isEmpty() && nodes.isEmpty()) {
+ if (properties.isEmpty() && builders.isEmpty()) {
return base; // shortcut
} else {
+ Map<String, NodeState> nodes = new HashMap<String, NodeState>();
+ for (Map.Entry<String, NodeStateBuilder> entry
+ : builders.entrySet()) {
+ NodeStateBuilder builder = entry.getValue();
+ if (builder != null) {
+ nodes.put(entry.getKey(), builder.getNodeState());
+ } else {
+ nodes.put(entry.getKey(), null);
+ }
+ }
return new ModifiedNodeState(
base, snapshot(properties), snapshot(nodes));
}
@@ -80,15 +91,23 @@ class MemoryNodeStateBuilder implements
@Override
public void setNode(String name, NodeState nodeState) {
- nodes.put(name, nodeState);
+ if (nodeState == null) {
+ removeNode(name);
+ } else {
+ if (nodeState.equals(base.getChildNode(name))) {
+ builders.remove(name);
+ } else {
+ builders.put(name, new MemoryNodeStateBuilder(nodeState));
+ }
+ }
}
@Override
public void removeNode(String name) {
if (base.getChildNode(name) != null) {
- nodes.put(name, null);
+ builders.put(name, null);
} else {
- nodes.remove(name);
+ builders.remove(name);
}
}
@@ -113,4 +132,18 @@ class MemoryNodeStateBuilder implements
}
}
+ @Override
+ public NodeStateBuilder getChildBuilder(String name) {
+ NodeStateBuilder builder = builders.get(name);
+ if (builder == null) {
+ NodeState baseState = base.getChildNode(name);
+ if (baseState == null) {
+ baseState = MemoryNodeState.EMPTY_NODE;
+ }
+ builder = new MemoryNodeStateBuilder(baseState);
+ builders.put(name, builder);
+ }
+ return builder;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateBuilder.java?rev=1358157&r1=1358156&r2=1358157&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStateBuilder.java Fri Jul 6 12:28:06 2012
@@ -71,4 +71,28 @@ public interface NodeStateBuilder {
*/
void removeProperty(String name);
+ /**
+ * Returns a builder for constructing changes to the named child node.
+ * If the named child node does not already exist, a new empty child
+ * node is automatically created as the base state of the returned
+ * child builder. Otherwise the existing child node state is used
+ * as the base state of the returned builder.
+ * <p>
+ * All updates to the returned child builder will implicitly affect
+ * also this builder, as if a
+ * <code>setNode(name, childBilder.getNodeState())</code> method call
+ * had been made after each update. Repeated calls to this method with
+ * the same name will return the same child builder instance until an
+ * explicit {@link #setNode(String, NodeState)} or
+ * {@link #removeNode(String)} call is made, at which point the link
+ * between this builder and a previously returned child builder for
+ * that child node name will get broken.
+ *
+ * @since Oak 0.4
+ * @param name name of the child node
+ * @return child builder
+ */
+ @Nonnull
+ NodeStateBuilder getChildBuilder(String name);
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java?rev=1358157&r1=1358156&r2=1358157&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreTest.java Fri Jul 6 12:28:06 2012
@@ -68,20 +68,14 @@ public class KernelNodeStoreTest extends
NodeStoreBranch branch = store.branch();
NodeStateBuilder rootBuilder = store.getBuilder(branch.getRoot());
- NodeStateBuilder testBuilder = store.getBuilder(root.getChildNode("test"));
+ NodeStateBuilder testBuilder = rootBuilder.getChildBuilder("test");
+ NodeStateBuilder newNodeBuilder = testBuilder.getChildBuilder("newNode");
- testBuilder.setNode("newNode", MemoryNodeState.EMPTY_NODE);
testBuilder.removeNode("x");
- NodeStateBuilder newNodeBuilder = store.getBuilder(
- testBuilder.getNodeState().getChildNode("newNode"));
-
CoreValue fortyTwo = store.getValueFactory().createValue(42);
newNodeBuilder.setProperty("n", fortyTwo);
- testBuilder.setNode("newNode", newNodeBuilder.getNodeState());
- rootBuilder.setNode("test", testBuilder.getNodeState());
-
// Assert changes are present in the builder
NodeState testState = rootBuilder.getNodeState().getChildNode("test");
assertNotNull(testState.getChildNode("newNode"));
@@ -129,18 +123,14 @@ public class KernelNodeStoreTest extends
NodeState root = store.getRoot();
NodeStateBuilder rootBuilder= store.getBuilder(root);
+ NodeStateBuilder testBuilder = rootBuilder.getChildBuilder("test");
+ NodeStateBuilder newNodeBuilder = testBuilder.getChildBuilder("newNode");
- NodeState test = root.getChildNode("test");
- NodeStateBuilder testBuilder = store.getBuilder(test);
-
- NodeStateBuilder newNodeBuilder = store.getBuilder(MemoryNodeState.EMPTY_NODE);
CoreValue fortyTwo = store.getValueFactory().createValue(42);
newNodeBuilder.setProperty("n", fortyTwo);
- testBuilder.setNode("newNode", newNodeBuilder.getNodeState());
testBuilder.removeNode("a");
- rootBuilder.setNode("test", testBuilder.getNodeState());
NodeState newRoot = rootBuilder.getNodeState();
NodeStoreBranch branch = store.branch();
@@ -176,25 +166,21 @@ public class KernelNodeStoreTest extends
NodeState root = store.getRoot();
NodeStateBuilder rootBuilder = store.getBuilder(root);
+ NodeStateBuilder testBuilder = rootBuilder.getChildBuilder("test");
+ NodeStateBuilder newNodeBuilder = testBuilder.getChildBuilder("newNode");
- NodeState test = root.getChildNode("test");
- NodeStateBuilder testBuilder = store.getBuilder(test);
-
- NodeStateBuilder newNodeBuilder = store.getBuilder(MemoryNodeState.EMPTY_NODE);
final CoreValue fortyTwo = store.getValueFactory().createValue(42);
newNodeBuilder.setProperty("n", fortyTwo);
- testBuilder.setNode("newNode", newNodeBuilder.getNodeState());
testBuilder.removeNode("a");
- rootBuilder.setNode("test", testBuilder.getNodeState());
NodeState newRoot = rootBuilder.getNodeState();
NodeStoreBranch branch = store.branch();
branch.setRoot(newRoot);
branch.merge();
- test = store.getRoot().getChildNode("test");
+ NodeState test = store.getRoot().getChildNode("test");
assertNotNull(test.getChildNode("newNode"));
assertNotNull(test.getChildNode("fromHook"));
assertNull(test.getChildNode("a"));