Author: mreutegg
Date: Tue Jan 21 16:16:59 2014
New Revision: 1560061

URL: http://svn.apache.org/r1560061
Log:
OAK-1345: Incorrect hasMore flag in nodeChildrenCache

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java?rev=1560061&r1=1560060&r2=1560061&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
 Tue Jan 21 16:16:59 2014
@@ -75,7 +75,7 @@ public final class KernelNodeState exten
     /**
      * Maximum number of child nodes kept in memory.
      */
-    static final int MAX_CHILD_NODE_NAMES = 100;
+    public static final int MAX_CHILD_NODE_NAMES = 100;
 
     /**
      * Number of child nodes beyond which {@link MicroKernel#diff(String, 
String, String, int)}

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java?rev=1560061&r1=1560060&r2=1560061&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
 Tue Jan 21 16:16:59 2014
@@ -596,11 +596,10 @@ public final class MongoNodeStore
         // as the starting point
         Iterable<NodeDocument> docs;
         Node.Children c = new Node.Children();
-        int rawLimit = limit;
+        int rawLimit = (int) Math.min(Integer.MAX_VALUE, ((long) limit) + 1);
         Set<Revision> validRevisions = new HashSet<Revision>();
-        do {
+        for (;;) {
             c.children.clear();
-            c.hasMore = true;
             docs = readChildren(path, rawLimit);
             int numReturned = 0;
             for (NodeDocument doc : docs) {
@@ -613,17 +612,22 @@ public final class MongoNodeStore
                 if (c.children.size() < limit) {
                     // add to children until limit is reached
                     c.children.add(p);
+                } else {
+                    // enough collected and we know there are more
+                    c.hasMore = true;
+                    return c;
                 }
             }
+            // if we get here we have less than or equal the requested children
             if (numReturned < rawLimit) {
                 // fewer documents returned than requested
                 // -> no more documents
                 c.hasMore = false;
+                return c;
             }
             // double rawLimit for next round
             rawLimit = (int) Math.min(((long) rawLimit) * 2, 
Integer.MAX_VALUE);
-        } while (c.children.size() < limit && c.hasMore);
-        return c;
+        }
     }
 
     @Nonnull

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreTest.java?rev=1560061&r1=1560060&r2=1560061&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreTest.java
 Tue Jan 21 16:16:59 2014
@@ -16,14 +16,21 @@
  */
 package org.apache.jackrabbit.oak.plugins.mongomk;
 
+import java.util.ArrayList;
+import java.util.SortedSet;
+import java.util.TreeSet;
 import java.util.concurrent.Semaphore;
 
+import org.apache.jackrabbit.oak.kernel.KernelNodeState;
 import 
org.apache.jackrabbit.oak.plugins.mongomk.util.TimingDocumentStoreWrapper;
 import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.junit.Test;
 
+import com.google.common.collect.Iterables;
+
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -86,4 +93,25 @@ public class MongoNodeStoreTest {
         // now node2 is visible
         assertTrue(root.hasChildNode("node2"));
     }
+
+    @Test
+    public void childNodeCache() throws Exception {
+        MongoNodeStore store = new MongoMK.Builder().getNodeStore();
+        NodeBuilder builder = store.getRoot().builder();
+        int max = (int) (KernelNodeState.MAX_CHILD_NODE_NAMES * 1.5);
+        SortedSet<String> children = new TreeSet<String>();
+        for (int i = 0; i < max; i++) {
+            String name = "c" + i;
+            children.add(name);
+            builder.child(name);
+        }
+        store.merge(builder, EmptyHook.INSTANCE, null);
+        builder = store.getRoot().builder();
+        String name = new ArrayList<String>(children).get(
+                KernelNodeState.MAX_CHILD_NODE_NAMES / 2);
+        builder.child(name).remove();
+        store.merge(builder, EmptyHook.INSTANCE, null);
+        int numEntries = Iterables.size(store.getRoot().getChildNodeEntries());
+        assertEquals(max - 1, numEntries);
+    }
 }


Reply via email to