Author: mreutegg
Date: Thu Jun 19 08:25:22 2014
New Revision: 1603753

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

Merge r1603748 from trunk.

Modified:
    jackrabbit/oak/branches/1.0/   (props changed)
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java

Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
  Merged /jackrabbit/oak/trunk:r1603748

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1603753&r1=1603752&r2=1603753&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 Thu Jun 19 08:25:22 2014
@@ -708,10 +708,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;
@@ -721,13 +731,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;
@@ -748,8 +760,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);
         }
     }
 


Reply via email to