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 th...@apache.org on 2013/06/06 15:18:19 UTC
svn commit: r1490270 -
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
Author: thomasm
Date: Thu Jun 6 13:18:18 2013
New Revision: 1490270
URL: http://svn.apache.org/r1490270
Log:
OAK-858 NodeBuilder.getChildNodeCount - don't rely on child count from the MK being exact, and reduce memory usage if there are many child nodes
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.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=1490270&r1=1490269&r2=1490270&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 Thu Jun 6 13:18:18 2013
@@ -75,7 +75,7 @@ public final class KernelNodeState exten
/**
* Maximum number of child nodes kept in memory.
*/
- static final int MAX_CHILD_NODE_NAMES = 1000;
+ static final int MAX_CHILD_NODE_NAMES = 100;
/**
* Dummy cache instance for static {@link #NULL} kernel node state.
@@ -305,18 +305,87 @@ public final class KernelNodeState exten
@Override
public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
init();
- Iterable<ChildNodeEntry> iterable = iterable(childNames);
- if (childNodeCount > childNames.size()) {
- List<Iterable<ChildNodeEntry>> iterables = Lists.newArrayList();
- iterables.add(iterable);
- long offset = childNames.size();
- while (offset < childNodeCount) {
- iterables.add(getChildNodeEntries(offset, MAX_CHILD_NODE_NAMES));
- offset += MAX_CHILD_NODE_NAMES;
- }
- iterable = Iterables.concat(iterables);
+ if (childNodeCount <= childNames.size()) {
+ return iterable(childNames);
}
- return iterable;
+ List<Iterable<ChildNodeEntry>> iterables = Lists.newArrayList();
+ iterables.add(iterable(childNames));
+ iterables.add(getChildNodeEntries(childNames.size()));
+ return Iterables.concat(iterables);
+ }
+
+ private Iterable<ChildNodeEntry> getChildNodeEntries(final long offset) {
+ return new Iterable<ChildNodeEntry>() {
+ @Override
+ public Iterator<ChildNodeEntry> iterator() {
+ return new Iterator<ChildNodeEntry>() {
+ private long currentOffset = offset;
+ private Iterator<ChildNodeEntry> current;
+
+ {
+ fetchEntries();
+ }
+
+ private void fetchEntries() {
+ List<ChildNodeEntry> entries = Lists
+ .newArrayListWithCapacity(MAX_CHILD_NODE_NAMES);
+ String json = kernel.getNodes(path, revision, 0,
+ currentOffset, MAX_CHILD_NODE_NAMES, null);
+ JsopReader reader = new JsopTokenizer(json);
+ reader.read('{');
+ do {
+ String name = StringCache.get(reader.readString());
+ reader.read(':');
+ if (reader.matches('{')) {
+ reader.read('}');
+ entries.add(new KernelChildNodeEntry(name));
+ } else if (reader.matches('[')) {
+ while (reader.read() != ']') {
+ // skip
+ }
+ } else {
+ reader.read();
+ }
+ } while (reader.matches(','));
+ reader.read('}');
+ reader.read(JsopReader.END);
+ if (entries.isEmpty()) {
+ current = null;
+ } else {
+ currentOffset += entries.size();
+ current = entries.iterator();
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ while (true) {
+ if (current == null) {
+ return false;
+ } else if (current.hasNext()) {
+ return true;
+ }
+ fetchEntries();
+ }
+ }
+
+ @Override
+ public ChildNodeEntry next() {
+ if (!hasNext()) {
+ throw new IllegalStateException(
+ "Reading past the end");
+ }
+ return current.next();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+ };
}
@Override
@@ -539,38 +608,6 @@ public final class KernelNodeState exten
}
}
- private Iterable<ChildNodeEntry> getChildNodeEntries(
- final long offset, final int count) {
- return new Iterable<ChildNodeEntry>() {
- @Override
- public Iterator<ChildNodeEntry> iterator() {
- List<ChildNodeEntry> entries =
- Lists.newArrayListWithCapacity(count);
- String json = kernel.getNodes(
- path, revision, 0, offset, count, null);
- JsopReader reader = new JsopTokenizer(json);
- reader.read('{');
- do {
- String name = StringCache.get(reader.readString());
- reader.read(':');
- if (reader.matches('{')) {
- reader.read('}');
- entries.add(new KernelChildNodeEntry(name));
- } else if (reader.matches('[')) {
- while (reader.read() != ']') {
- // skip
- }
- } else {
- reader.read();
- }
- } while (reader.matches(','));
- reader.read('}');
- reader.read(JsopReader.END);
- return entries.iterator();
- }
- };
- }
-
private String getChildPath(String name) {
if ("/".equals(path)) {
return '/' + name;