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 mr...@apache.org on 2014/06/19 10:04:50 UTC

svn commit: r1603748 - /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java

Author: mreutegg
Date: Thu Jun 19 08:04:49 2014
New Revision: 1603748

URL: http://svn.apache.org/r1603748
Log:
OAK-1861: Limit memory usage of DocumentNodeStore.readChildren()

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1603748&r1=1603747&r2=1603748&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Thu Jun 19 08:04:49 2014
@@ -709,10 +709,20 @@ public final class DocumentNodeStore
         return children;
     }
 
-    DocumentNodeState.Children readChildren(DocumentNodeState parent, String name, int limit) {
-        // TODO use offset, to avoid O(n^2) and running out of memory
-        // to do that, use the *name* of the last entry of the previous batch of children
-        // as the starting point
+    /**
+     * Read the children of the given parent node state starting at the child
+     * node with {@code name}. The given {@code name} is exclusive and will not
+     * appear in the list of children. The returned children are sorted in
+     * ascending order.
+     *
+     * @param parent the parent node.
+     * @param name the name of the lower bound child node (exclusive) or
+     *              {@code null} if no lower bound is given.
+     * @param limit the maximum number of child nodes to return.
+     * @return the children of {@code parent}.
+     */
+    DocumentNodeState.Children readChildren(DocumentNodeState parent,
+                                            String name, int limit) {
         String path = parent.getPath();
         Revision rev = parent.getLastRevision();
         Iterable<NodeDocument> docs;
@@ -722,13 +732,15 @@ public final class DocumentNodeStore
         // child nodes than requested.
         int rawLimit = (int) Math.min(Integer.MAX_VALUE, ((long) limit) + 1);
         for (;;) {
-            c.children.clear();
             docs = readChildDocs(path, name, rawLimit);
             int numReturned = 0;
             for (NodeDocument doc : docs) {
                 numReturned++;
-                // filter out deleted children
                 String p = doc.getPath();
+                // remember name of last returned document for
+                // potential next round of readChildDocs()
+                name = PathUtils.getName(p);
+                // filter out deleted children
                 DocumentNodeState child = getNode(p, rev);
                 if (child == null) {
                     continue;
@@ -749,8 +761,6 @@ public final class DocumentNodeStore
                 c.hasMore = false;
                 return c;
             }
-            // double rawLimit for next round
-            rawLimit = (int) Math.min(((long) rawLimit) * 2, Integer.MAX_VALUE);
         }
     }