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/26 12:22:49 UTC

svn commit: r1365937 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/kernel/ main/java/org/apache/jackrabbit/oak/plugins/memory/ test/java/org/apache/jackrabbit/oak/kernel/

Author: jukka
Date: Thu Jul 26 10:22:49 2012
New Revision: 1365937

URL: http://svn.apache.org/viewvc?rev=1365937&view=rev
Log:
OAK-167: Caching NodeStore implementation

Add automatic copy and move handling to KernelRootStateBuilder

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStateBuilder.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootStateBuilder.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.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/kernel/JsopDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java?rev=1365937&r1=1365936&r2=1365937&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java Thu Jul 26 10:22:49 2012
@@ -30,9 +30,9 @@ import org.apache.jackrabbit.oak.spi.sta
 
 class JsopDiff implements NodeStateDiff {
 
-    private final JsopBuilder jsop;
+    protected final JsopBuilder jsop;
 
-    private final String path;
+    protected final String path;
 
     public JsopDiff(JsopBuilder jsop, String path) {
         this.jsop = jsop;
@@ -49,6 +49,10 @@ class JsopDiff implements NodeStateDiff 
         after.compareAgainstBaseState(before, new JsopDiff(jsop, path));
     }
 
+    protected JsopDiff createChildDiff(JsopBuilder jsop, String path) {
+        return new JsopDiff(jsop, path);
+    }
+
     //-----------------------------------------------------< NodeStateDiff >--
 
     @Override
@@ -81,8 +85,8 @@ class JsopDiff implements NodeStateDiff 
 
     @Override
     public void childNodeChanged(String name, NodeState before, NodeState after) {
-        after.compareAgainstBaseState(
-                before, new JsopDiff(jsop, PathUtils.concat(path, name)));
+        String path = buildPath(name);
+        after.compareAgainstBaseState(before, createChildDiff(jsop, path));
     }
 
     //------------------------------------------------------------< Object >--
@@ -93,7 +97,7 @@ class JsopDiff implements NodeStateDiff 
 
     //-----------------------------------------------------------< private >--
 
-    private String buildPath(String name) {
+    protected String buildPath(String name) {
         return PathUtils.concat(path, name);
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStateBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStateBuilder.java?rev=1365937&r1=1365936&r2=1365937&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStateBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStateBuilder.java Thu Jul 26 10:22:49 2012
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.oak.kernel;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStateBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
@@ -27,9 +29,11 @@ class KernelNodeStateBuilder extends Mem
             MemoryNodeStateBuilder parent, String name,
             NodeState base, KernelRootStateBuilder root) {
         super(parent, name, base);
-        this.root = root;
+        this.root = checkNotNull(root);
     }
 
+    //--------------------------------------------< MemoryNodeStateBuilder >--
+
     @Override
     protected MemoryNodeStateBuilder createChildBuilder(
             String name, NodeState child) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootStateBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootStateBuilder.java?rev=1365937&r1=1365936&r2=1365937&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootStateBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelRootStateBuilder.java Thu Jul 26 10:22:49 2012
@@ -16,10 +16,19 @@
  */
 package org.apache.jackrabbit.oak.kernel;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.json.JsopBuilder;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStateBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
 class KernelRootStateBuilder extends MemoryNodeStateBuilder {
 
     /**
@@ -38,11 +47,13 @@ class KernelRootStateBuilder extends Mem
 
     public KernelRootStateBuilder(MicroKernel kernel, String revision) {
         super(new KernelNodeState(kernel, "/", revision));
-        this.kernel = kernel;
-        this.baseRevision = revision;
+        this.kernel = checkNotNull(kernel);
+        this.baseRevision = checkNotNull(revision);
         this.branchRevision = null;
     }
 
+    //--------------------------------------------< MemoryNodeStateBuilder >--
+
     @Override
     protected MemoryNodeStateBuilder createChildBuilder(
             String name, NodeState child) {
@@ -52,15 +63,126 @@ class KernelRootStateBuilder extends Mem
     @Override
     protected void updated() {
         if (updates++ > UPDATE_LIMIT) {
+            CopyAndMoveAwareJsopDiff diff = new CopyAndMoveAwareJsopDiff();
+            compareAgainstBaseState(diff);
+            diff.processMovesAndCopies();
+
             if (branchRevision == null) {
                 branchRevision = kernel.branch(baseRevision);
             }
-            JsopDiff diff = new JsopDiff();
-            getNodeState().compareAgainstBaseState(getBaseState(), diff);
             branchRevision = kernel.commit(
                     "/", diff.toString(), branchRevision, null);
+
             updates = 0;
         }
     }
 
+    private class CopyAndMoveAwareJsopDiff extends JsopDiff {
+
+        private final Map<String, NodeState> added;
+
+
+        private final Set<String> deleted;
+
+        public CopyAndMoveAwareJsopDiff() {
+            added = Maps.newHashMap();
+            deleted = Sets.newHashSet();
+        }
+
+        private CopyAndMoveAwareJsopDiff(
+                JsopBuilder jsop, String path,
+                Map<String, NodeState> added, Set<String> deleted) {
+            super(jsop, path);
+            this.added = added;
+            this.deleted = deleted;
+        }
+
+        public void processMovesAndCopies() {
+            for (Map.Entry<String, NodeState> entry : added.entrySet()) {
+                NodeState state = entry.getValue();
+                String path = entry.getKey();
+
+                KernelNodeState kstate = getKernelBaseState(state);
+                String kpath = kstate.getPath();
+
+                if (deleted.remove(kpath)) {
+                    jsop.tag('>');
+                } else {
+                    jsop.tag('*');
+                }
+                jsop.key(kpath).value(path);
+
+                if (state != kstate) {
+                    state.compareAgainstBaseState(
+                            kstate, new JsopDiff(jsop, path));
+                }
+            }
+
+            for (String path : deleted) {
+                jsop.tag('-').value(path);
+            }
+        }
+
+        //------------------------------------------------------< JsopDiff >--
+
+        @Override
+        protected JsopDiff createChildDiff(JsopBuilder jsop, String path) {
+            return new CopyAndMoveAwareJsopDiff(jsop, path, added, deleted);
+        }
+
+        //-------------------------------------------------< NodeStateDiff >--
+
+        @Override
+        public void childNodeAdded(String name, NodeState after) {
+            KernelNodeState kstate = getKernelBaseState(after);
+            if (kstate != null) {
+                added.put(buildPath(name), after);
+            } else {
+                super.childNodeAdded(name, after);
+            }
+        }
+
+        
+        @Override
+        public void childNodeChanged(
+                String name, NodeState before, NodeState after) {
+            KernelNodeState kstate = getKernelBaseState(after);
+            String path = buildPath(name);
+            if (kstate != null && !path.equals(kstate.getPath())) {
+                deleted.add(path);
+                added.put(path, after);
+            } else {
+                super.childNodeChanged(name, before, after);
+            }
+        }
+
+        @Override
+        public void childNodeDeleted(String name, NodeState before) {
+            deleted.add(buildPath(name));
+        }
+
+        //-------------------------------------------------------< private >--
+
+        private KernelNodeState getKernelBaseState(NodeState state) {
+            if (state instanceof MutableNodeState) {
+                state = ((MutableNodeState) state).getBaseState();
+            }
+
+            if (state instanceof KernelNodeState) {
+                KernelNodeState kstate = (KernelNodeState) state;
+                String arev = kstate.getRevision();
+                String brev = branchRevision;
+                if (brev == null) {
+                    brev = baseRevision;
+                }
+                if (arev.equals(brev)) {
+                    return kstate;
+                }
+            }
+
+            return 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=1365937&r1=1365936&r2=1365937&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 Thu Jul 26 10:22:49 2012
@@ -194,15 +194,15 @@ public class MemoryNodeStateBuilder impl
         // do nothing
     }
 
-    protected NodeState getBaseState() {
+    protected void compareAgainstBaseState(NodeStateDiff diff) {
         NodeState state = read();
         if (writeState != null) {
-            return writeState.base;
-        } else {
-            return state;
+            writeState.compareAgainstBaseState(state, diff);
         }
     }
 
+    //-------------------------------------------------< NodeStateBuilder >--
+
     @Override
     public NodeState getNodeState() {
         NodeState state = read();
@@ -375,7 +375,7 @@ public class MemoryNodeStateBuilder impl
      * so it's not a problem that we intentionally break the immutability
      * assumption of the {@link NodeState} interface.
      */
-    private static class MutableNodeState extends AbstractNodeState {
+    protected static class MutableNodeState extends AbstractNodeState {
 
         /**
          * The immutable base state.
@@ -418,6 +418,10 @@ public class MemoryNodeStateBuilder impl
             }
         }
 
+        public NodeState getBaseState() {
+            return base;
+        }
+
         //-----------------------------------------------------< NodeState >--
 
         @Override
@@ -629,7 +633,7 @@ public class MemoryNodeStateBuilder impl
     /**
      * Immutable snapshot of a mutable node state.
      */
-    private static class ModifiedNodeState extends MutableNodeState {
+    protected static class ModifiedNodeState extends MutableNodeState {
 
         public ModifiedNodeState(MutableNodeState mstate) {
             super(mstate.base);

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=1365937&r1=1365936&r2=1365937&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 Thu Jul 26 10:22:49 2012
@@ -19,9 +19,9 @@
 package org.apache.jackrabbit.oak.kernel;
 
 import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.core.MicroKernelImpl;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.CoreValue;
-import org.apache.jackrabbit.oak.core.AbstractOakTest;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
 import org.apache.jackrabbit.oak.spi.commit.CommitEditor;
 import org.apache.jackrabbit.oak.spi.commit.Observer;
@@ -29,24 +29,28 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.oak.spi.state.NodeStateBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
+import org.junit.Before;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
-public class KernelNodeStoreTest extends AbstractOakTest {
+public class KernelNodeStoreTest {
+
+    private KernelNodeStore store;
 
     private NodeState root;
 
-    @Override
-    protected NodeState createInitialState(MicroKernel microKernel) {
+    @Before
+    public void setUp() {
+        MicroKernel kernel = new MicroKernelImpl();
         String jsop =
                 "+\"test\":{\"a\":1,\"b\":2,\"c\":3,"
-                        + "\"x\":{},\"y\":{},\"z\":{}}";
-        microKernel.commit("/", jsop, null, "test data");
+                + "\"x\":{},\"y\":{},\"z\":{}}";
+        kernel .commit("/", jsop, null, "test data");
+        store = new KernelNodeStore(kernel);
         root = store.getRoot();
-        return root;
     }
 
     @Test