Hi,

Starting with this revision there is some experimental support for large child node lists in spi2microkernel and jcr2spi (jackrabbit-mk branch in the sandbox). The Microkernel itself is not yet optimized for large child node list but AFAIK Stefan is working on this.

To support large child node lists, I basically defer loading of child entries as much as possible. Furthermore child nodes are loaded in chunks of max. 512 entries at a time. Loaded child nodes are kept internally by the ChildNodeEntries class until cleared by the garbage collector. Using the garbage collector to control the child entries is not optimal and may lead to memory thrashing when clients fully iterate over large child node lists. Within the current design of the jcr2spi layer there does not seem to be a better solution though.

Disclaimer: while the test cases pass, I did not yet test the effectiveness of this solution.

Michael


-------- Original Message --------
Subject: svn commit: r1214921 - /jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java
Date: Thu, 15 Dec 2011 19:25:18 -0000
From: [email protected]
Reply-To: [email protected]
To: [email protected]

Author: mduerig
Date: Thu Dec 15 19:25:17 2011
New Revision: 1214921

URL: http://svn.apache.org/viewvc?rev=1214921&view=rev
Log:
Microkernel based Jackrabbit prototype (WIP)
batch loading of child nodes

Modified:

jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java?rev=1214921&r1=1214920&r2=1214921&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java (original) +++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java Thu Dec 15 19:25:17 2011
@@ -301,7 +301,7 @@ public class RepositoryServiceImpl exten

     @Override
protected void checkWorkspace(String workspaceName) throws NoSuchWorkspaceException {
-        if (workspaceName == null || "".equals(workspaceName)) {
+        if (workspaceName == null || workspaceName.isEmpty()) {
             workspaceName = defaultWorkspace;
         }
         else if (workspaceName.contains("/")) {
@@ -339,7 +339,7 @@ public class RepositoryServiceImpl exten
                 throw new PathNotFoundException(itemPath.toString());
             }

-            String json = microKernel.getNodes(mkPath, rev);
+            String json = microKernel.getNodes(mkPath, rev, 0, 0, 0);
return buildItemInfos(nodePath, itemPath, json, readFromDataStore);
         }
         catch (MicroKernelException e) {
@@ -352,18 +352,65 @@ public class RepositoryServiceImpl exten
public Iterator<ChildInfo> getChildInfos(SessionInfo sessionInfo, NodeId parentId) throws RepositoryException {
         try {
             String wspName = sessionInfo.getWorkspaceName();
-            String rev = getRevision(sessionInfo);
-            Path path = getPath(parentId, wspName, rev);
-            String mkPath = Paths.pathToString(wspName, path);
+            final String rev = getRevision(sessionInfo);
+            final Path path = getPath(parentId, wspName, rev);
+            final String mkPath = Paths.pathToString(wspName, path);

             if (!microKernel.nodeExists(mkPath, rev)) {
                 throw new PathNotFoundException(path.toString());
             }

-            String json = microKernel.getNodes(mkPath, rev);
- Iterator<? extends ItemInfo> infos = buildItemInfos(path, path, json, readFromDataStore);
-            NodeInfo info = (NodeInfo) infos.next();
-            return info.getChildInfos();
+            return new Iterator<ChildInfo>() {
+                private static final int chunkSize = 512;
+
+                private int pos;
+                private Iterator<ChildInfo> currentChunk;
+
+                {
+                    nextChunk();
+                }
+
+                @Override
+                public boolean hasNext() {
+                    if (currentChunk.hasNext()) {
+                        return true;
+                    }
+                    else {
+                        nextChunk();
+                        return currentChunk.hasNext();
+                    }
+                }
+
+                @Override
+                public ChildInfo next() {
+                    if (currentChunk.hasNext()) {
+                        return currentChunk.next();
+                    }
+                    else {
+                        nextChunk();
+                        return currentChunk.next();
+                    }
+                }
+
+                @Override
+                public void remove() {
+                    throw new UnsupportedOperationException("remove");
+                }
+
+                private void nextChunk() {
+                    try {
+ String json = microKernel.getNodes(mkPath, rev, 0, pos, chunkSize);
+                        pos += chunkSize;
+ Iterator<? extends ItemInfo> infos = buildItemInfos(path, path, json, readFromDataStore);
+                        NodeInfo info = (NodeInfo) infos.next();
+                        currentChunk = info.getChildInfos();
+                    }
+                    catch (RepositoryException e) {
+                        // fixme think of a better way to handle this
+                        log.error(e.getMessage(), e);
+                    }
+                }
+            };
         }
         catch (MicroKernelException e) {
             log.error(e.getMessage(), e);



Reply via email to