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"));