Author: jukka
Date: Mon Jul 9 21:38:12 2012
New Revision: 1359413
URL: http://svn.apache.org/viewvc?rev=1359413&view=rev
Log:
OAK-175: MemoryNodeStateBuilder inefficient for large child node lists
Add a partially optimized KernelNodeState.compareAgainstBaseState
implementation.
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=1359413&r1=1359412&r2=1359413&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
Mon Jul 9 21:38:12 2012
@@ -28,6 +28,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
import org.apache.jackrabbit.oak.util.Iterators;
import org.apache.jackrabbit.oak.util.PagedIterator;
@@ -178,17 +179,55 @@ final class KernelNodeState extends Abst
};
}
+ /**
+ * Optimised comparison method that can avoid traversing all properties
+ * and child nodes if both this and the given base node state come from
+ * the same MicroKernel and either have the same content hash (when
+ * available) or are located at the same path in different revisions.
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/OAK-175">OAK-175</a>
+ */
+ @Override
+ public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+ if (this == base) {
+ return; // no differences
+ } else if (base instanceof KernelNodeState) {
+ KernelNodeState kbase = (KernelNodeState) base;
+ if (kernel.equals(kbase.kernel)) {
+ if (revision.equals(kbase.revision) &&
path.equals(kbase.path)) {
+ return; // no differences
+ } else {
+ init();
+ kbase.init();
+ if (hash != null && hash.equals(kbase.hash)) {
+ return; // no differences
+ } else if (path.equals(kbase.path)) {
+ // TODO: Parse the JSON diff returned by the kernel
+ // kernel.diff(kbase.revision, revision, path);
+ }
+ }
+ }
+ }
+ // fall back to the generic node state diff algorithm
+ super.compareAgainstBaseState(base, diff);
+ }
+
//------------------------------------------------------------< Object >--
+ /**
+ * Optimised equality check that can avoid a full tree comparison if
+ * both instances come from the same MicroKernel and have either
+ * the same revision and path or the same content hash (when available).
+ * Otherwise we fall back to the default tree comparison algorithm.
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/OAK-172">OAK-172</a>
+ */
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object instanceof KernelNodeState) {
KernelNodeState that = (KernelNodeState) object;
- // When both instances come from the same MicroKernel, we can
- // use revision/path information or content hashes (when available)
- // to avoid a full tree comparison in many cases.
if (kernel.equals(that.kernel)) {
if (revision.equals(that.revision) && path.equals(that.path)) {
return true;
@@ -201,7 +240,7 @@ final class KernelNodeState extends Abst
}
}
}
- // fallback
+ // fall back to the generic tree equality comparison algorithm
return super.equals(object);
}