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 md...@apache.org on 2013/09/23 17:25:40 UTC

svn commit: r1525623 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: kernel/KernelNodeStore.java plugins/memory/MemoryNodeStore.java spi/state/AbstractNodeStore.java

Author: mduerig
Date: Mon Sep 23 15:25:40 2013
New Revision: 1525623

URL: http://svn.apache.org/r1525623
Log:
OAK-659 Move purge logic for transient changes below the NodeBuilder interface
Throw IAE on rebase/reset/merge when passed builder has wrong instance

Removed:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStore.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java?rev=1525623&r1=1525622&r2=1525623&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java Mon Sep 23 15:25:40 2013
@@ -34,25 +34,23 @@ import com.google.common.cache.LoadingCa
 import com.google.common.cache.Weigher;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
-
 import org.apache.jackrabbit.mk.api.MicroKernel;
 import org.apache.jackrabbit.mk.api.MicroKernelException;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.cache.CacheStats;
-import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.EmptyObserver;
 import org.apache.jackrabbit.oak.spi.commit.Observer;
 import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
-import org.apache.jackrabbit.oak.spi.state.AbstractNodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
 
 /**
  * {@code NodeStore} implementations against {@link MicroKernel}.
  */
-public class KernelNodeStore extends AbstractNodeStore {
+public class KernelNodeStore implements NodeStore {
 
     private static final long DEFAULT_CACHE_SIZE = 16 * 1024 * 1024;
 
@@ -137,10 +135,11 @@ public class KernelNodeStore extends Abs
         this.observer = checkNotNull(observer);
     }
 
-    @Override
-    protected void reset(NodeBuilder builder, NodeState state) {
-        checkArgument(builder instanceof MemoryNodeBuilder);
-        ((MemoryNodeBuilder) builder).reset(state);
+    /**
+     * Returns a string representation the head state of this node store.
+     */
+    public String toString() {
+        return getRoot().toString();
     }
 
     //----------------------------------------------------------< NodeStore >---
@@ -158,59 +157,40 @@ public class KernelNodeStore extends Abs
 
     /**
      * This implementation delegates to {@link KernelRootBuilder#merge(CommitHook, PostCommitHook)}
-     * if {@code builder} is a {@link KernelNodeBuilder} instance. Otherwise it falls
-     * back to the default implementation of its super class.
+     * if {@code builder} is a {@link KernelNodeBuilder} instance. Otherwise it throws
+     * an {@code IllegalArgumentException}.
      */
     @Override
     public NodeState merge(@Nonnull NodeBuilder builder, @Nonnull CommitHook commitHook,
             PostCommitHook committed) throws CommitFailedException {
-        if (builder instanceof KernelRootBuilder) {
-            return ((KernelRootBuilder) builder).merge(commitHook, committed);
-        } else {
-            mergeLock.lock();
-            try {
-                return super.merge(builder, commitHook, committed);
-            } finally {
-                mergeLock.unlock();
-            }
-        }
+        checkArgument(builder instanceof KernelRootBuilder);
+        return ((KernelRootBuilder) builder).merge(commitHook, committed);
     }
 
     /**
      * This implementation delegates to {@link KernelRootBuilder#rebase()} if {@code builder}
-     * is a {@link KernelNodeBuilder} instance. Otherwise it falls back to the default
-     * implementation of its super class.
+     * is a {@link KernelNodeBuilder} instance. Otherwise Otherwise it throws an
+     * {@code IllegalArgumentException}.
      * @param builder  the builder to rebase
      * @return
      */
     @Override
     public NodeState rebase(@Nonnull NodeBuilder builder) {
-        if (builder instanceof KernelRootBuilder) {
-            return ((KernelRootBuilder) builder).rebase();
-        } else {
-            return super.rebase(builder);
-        }
+        checkArgument(builder instanceof KernelRootBuilder);
+        return ((KernelRootBuilder) builder).rebase();
     }
 
     /**
      * This implementation delegates to {@link KernelRootBuilder#reset()} if {@code builder}
-     * is a {@link KernelNodeBuilder} instance. Otherwise it falls back to the default
-     * implementation of its super class.
+     * is a {@link KernelNodeBuilder} instance. Otherwise it throws an
+     * {@code IllegalArgumentException}.
      * @param builder  the builder to rebase
      * @return
      */
     @Override
     public NodeState reset(@Nonnull NodeBuilder builder) {
-        if (builder instanceof KernelRootBuilder) {
-            return ((KernelRootBuilder) builder).reset();
-        } else {
-            return super.reset(builder);
-        }
-    }
-
-    @Override
-    protected NodeStoreBranch createBranch(NodeState base) {
-        return new KernelNodeStoreBranch(this, mergeLock, (KernelNodeState) base);
+        checkArgument(builder instanceof KernelRootBuilder);
+        return ((KernelRootBuilder) builder).reset();
     }
 
     /**
@@ -256,6 +236,10 @@ public class KernelNodeStore extends Abs
         }
     }
 
+    NodeStoreBranch createBranch(NodeState base) {
+        return new KernelNodeStoreBranch(this, mergeLock, (KernelNodeState) base);
+    }
+
     MicroKernel getKernel() {
         return kernel;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java?rev=1525623&r1=1525622&r2=1525623&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java Mon Sep 23 15:25:40 2013
@@ -31,21 +31,21 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
 import com.google.common.io.ByteStreams;
-
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
-import org.apache.jackrabbit.oak.spi.state.AbstractNodeStore;
 import org.apache.jackrabbit.oak.spi.state.AbstractNodeStoreBranch;
+import org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
 
 /**
  * Basic in-memory node store implementation. Useful as a base class for
  * more complex functionality.
  */
-public class MemoryNodeStore extends AbstractNodeStore {
+public class MemoryNodeStore implements NodeStore {
 
     private final AtomicReference<NodeState> root;
 
@@ -59,20 +59,81 @@ public class MemoryNodeStore extends Abs
         this(EMPTY_NODE);
     }
 
+    /**
+     * Returns a string representation the head state of this node store.
+     */
+    public String toString() {
+        return getRoot().toString();
+    }
+
+    @Override
+    public NodeState getRoot() {
+        return root.get();
+    }
+
+    /**
+     * This implementation is equal to first rebasing the builder and then applying it to a
+     * new branch and immediately merging it back.
+     * @param builder  the builder whose changes to apply
+     * @param commitHook the commit hook to apply while merging changes
+     * @param committed  the pos commit hook
+     * @return the node state resulting from the merge.
+     * @throws CommitFailedException
+     * @throws IllegalArgumentException if the builder is not acquired from a root state of
+     *                                  this store
+     */
     @Override
-    protected void reset(NodeBuilder builder, NodeState state) {
+    public synchronized NodeState merge(@Nonnull NodeBuilder builder, @Nonnull CommitHook commitHook,
+            PostCommitHook committed) throws CommitFailedException {
         checkArgument(builder instanceof MemoryNodeBuilder);
-        ((MemoryNodeBuilder) builder).reset(state);
+        checkNotNull(commitHook);
+        rebase(checkNotNull(builder));
+        NodeStoreBranch branch = new MemoryNodeStoreBranch(this, getRoot());
+        branch.setRoot(builder.getNodeState());
+        NodeState merged = branch.merge(commitHook, committed);
+        ((MemoryNodeBuilder) builder).reset(merged);
+        return merged;
     }
 
+    /**
+     * This implementation is equal to applying the differences between the builders base state
+     * and its head state to a fresh builder on the stores root state using
+     * {@link org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff} for resolving
+     * conflicts.
+     * @param builder  the builder to rebase
+     * @return the node state resulting from the rebase.
+     * @throws IllegalArgumentException if the builder is not acquired from a root state of
+     *                                  this store
+     */
     @Override
-    protected NodeStoreBranch createBranch(NodeState base) {
-        return new MemoryNodeStoreBranch(this, base);
+    public NodeState rebase(@Nonnull NodeBuilder builder) {
+        checkArgument(builder instanceof MemoryNodeBuilder);
+        NodeState head = checkNotNull(builder).getNodeState();
+        NodeState base = builder.getBaseState();
+        NodeState newBase = getRoot();
+        if (base != newBase) {
+            ((MemoryNodeBuilder) builder).reset(newBase);
+            head.compareAgainstBaseState(
+                    base, new ConflictAnnotatingRebaseDiff(builder));
+            head = builder.getNodeState();
+        }
+        return head;
     }
 
+    /**
+     * This implementation is equal resetting the builder to the root of the store and returning
+     * the resulting node state from the builder.
+     * @param builder the builder to reset
+     * @return the node state resulting from the reset.
+     * @throws IllegalArgumentException if the builder is not acquired from a root state of
+     *                                  this store
+     */
     @Override
-    public NodeState getRoot() {
-        return root.get();
+    public NodeState reset(@Nonnull NodeBuilder builder) {
+        checkArgument(builder instanceof MemoryNodeBuilder);
+        NodeState head = getRoot();
+        ((MemoryNodeBuilder) builder).reset(head);
+        return head;
     }
 
     /**
@@ -101,6 +162,8 @@ public class MemoryNodeStore extends Abs
         return checkpoints.get(checkNotNull(checkpoint));
     }
 
+    //------------------------------------------------------------< private >---
+
     private static class MemoryNodeStoreBranch extends AbstractNodeStoreBranch {
 
         /** The underlying store to which this branch belongs */