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/02/08 14:03:13 UTC

svn commit: r1443997 - /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java

Author: mduerig
Date: Fri Feb  8 13:03:13 2013
New Revision: 1443997

URL: http://svn.apache.org/r1443997
Log:
OAK-614: AssertionError in MemoryNodeBuilder

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java?rev=1443997&r1=1443996&r2=1443997&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java Fri Feb  8 13:03:13 2013
@@ -188,11 +188,13 @@ public class MemoryNodeBuilder implement
     }
 
     /**
-     * Determine whether this child exists.
-     * Assumes {@code read()}, {@code write()} needs not be called.
-     * @return  {@code true} iff this child exists
+     * Determine whether this child exists with its direct parent or existed with its direct
+     * parent and got disconnected.
+     * @return  {@code true} iff this child either exists or got disconnected from its direct parent.
      */
-    private boolean exists() {
+    private boolean existsOrDisconnected() {
+        // No need to check the base state. The fact that we have this
+        // builder instance proofs that this child existed at some point.
         return isRoot() || parent.writeState == null || parent.writeState.hasChildNode(name);
     }
 
@@ -200,7 +202,7 @@ public class MemoryNodeBuilder implement
     private NodeState read() {
         if (revision != root.revision) {
             assert(!isRoot()); // root never gets here since revision == root.revision
-            checkState(exists(), "This node has already been removed");
+            checkState(existsOrDisconnected(), "This node has already been removed");
             parent.read();
 
             // The builder could have been reset, need to re-get base state
@@ -209,6 +211,7 @@ public class MemoryNodeBuilder implement
             // ... same for the write state
             writeState = parent.getWriteState(name);
 
+            checkState(baseState != null || writeState != null, "This node is disconnected");
             revision = root.revision;
         }
 
@@ -230,7 +233,7 @@ public class MemoryNodeBuilder implement
     private MutableNodeState write(long newRevision, boolean skipRemovedCheck) {
         // make sure that all revision numbers up to the root gets updated
         if (!isRoot()) {
-            checkState(skipRemovedCheck || exists());
+            checkState(skipRemovedCheck || existsOrDisconnected(), "This node has already been removed");
             parent.write(newRevision, skipRemovedCheck);
         }
 
@@ -242,11 +245,12 @@ public class MemoryNodeBuilder implement
 
             writeState = parent.getWriteState(name);
             if (writeState == null) {
-                if (!exists()) {
-                    writeState = new MutableNodeState(null);
+                if (existsOrDisconnected()) {
+                    assert baseState != null;
+                    writeState = new MutableNodeState(baseState);
                 }
                 else {
-                    writeState = new MutableNodeState(baseState);
+                    writeState = new MutableNodeState(null);
                 }
                 assert parent.writeState != null; // guaranteed by called parent.write()
                 parent.writeState.nodes.put(name, writeState);