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 ju...@apache.org on 2012/07/06 17:52:53 UTC
svn commit: r1358282 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak:
plugins/memory/ spi/state/
Author: jukka
Date: Fri Jul 6 15:52:53 2012
New Revision: 1358282
URL: http://svn.apache.org/viewvc?rev=1358282&view=rev
Log:
OAK-171: Add NodeState.compareAgainstBaseState()
First version, not yet optimized.
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java?rev=1358282&r1=1358281&r2=1358282&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeState.java Fri Jul 6 15:52:53 2012
@@ -20,8 +20,10 @@ import org.apache.jackrabbit.oak.api.Pro
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 java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -94,4 +96,42 @@ public class MemoryNodeState extends Abs
};
}
+ /**
+ * We don't keep track of a separate base node state for
+ * {@link MemoryNodeState} instances, so this method will just do
+ * a generic diff against the given state.
+ */
+ @Override
+ public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+ Map<String, PropertyState> newProperties =
+ new HashMap<String, PropertyState>(properties);
+ for (PropertyState before : base.getProperties()) {
+ PropertyState after = newProperties.remove(before.getName());
+ if (after == null) {
+ diff.propertyDeleted(before);
+ } else if (!after.equals(before)) {
+ diff.propertyChanged(before, after);
+ }
+ }
+ for (PropertyState after : newProperties.values()) {
+ diff.propertyAdded(after);
+ }
+
+ Map<String, NodeState> newNodes =
+ new HashMap<String, NodeState>(nodes);
+ for (ChildNodeEntry entry : base.getChildNodeEntries()) {
+ String name = entry.getName();
+ NodeState before = entry.getNodeState();
+ NodeState after = newNodes.remove(name);
+ if (after == null) {
+ diff.childNodeDeleted(name, before);
+ } else if (!after.equals(before)) {
+ diff.childNodeChanged(name, before, after);
+ }
+ }
+ for (Map.Entry<String, NodeState> entry : newNodes.entrySet()) {
+ diff.childNodeAdded(entry.getKey(), entry.getValue());
+ }
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java?rev=1358282&r1=1358281&r2=1358282&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java Fri Jul 6 15:52:53 2012
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.oak.plugin
import org.apache.jackrabbit.oak.spi.state.AbstractNodeStore;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
/**
* Abstract node store base class with in-memory node state builder
@@ -35,18 +34,4 @@ public abstract class MemoryNodeStore ex
return new MemoryNodeStateBuilder(base);
}
- @Override
- public void compare(NodeState before, NodeState after, NodeStateDiff diff) {
- if (after instanceof ModifiedNodeState) {
- ModifiedNodeState modified = (ModifiedNodeState) after;
- if (before.equals(modified.getBase())) {
- modified.diffAgainstBase(diff);
- } else {
- super.compare(before, after, diff);
- }
- } else {
- super.compare(before, after, diff);
- }
- }
-
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java?rev=1358282&r1=1358281&r2=1358282&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java Fri Jul 6 15:52:53 2012
@@ -46,39 +46,6 @@ public class ModifiedNodeState extends A
this.nodes = nodes;
}
- NodeState getBase() {
- return base;
- }
-
- void diffAgainstBase(NodeStateDiff diff) {
- for (Map.Entry<String, PropertyState> entry : properties.entrySet()) {
- PropertyState before = base.getProperty(entry.getKey());
- PropertyState after = entry.getValue();
- if (after == null) {
- assert before != null;
- diff.propertyDeleted(before);
- } else if (before == null) {
- diff.propertyAdded(after);
- } else {
- diff.propertyChanged(before, after);
- }
- }
-
- for (Map.Entry<String, NodeState> entry : nodes.entrySet()) {
- String name = entry.getKey();
- NodeState before = base.getChildNode(name);
- NodeState after = entry.getValue();
- if (after == null) {
- assert before != null;
- diff.childNodeDeleted(name, before);
- } else if (before == null) {
- diff.childNodeAdded(name, after);
- } else {
- diff.childNodeChanged(name, before, after);
- }
- }
- }
-
//---------------------------------------------------------< NodeState >--
@Override
@@ -177,6 +144,89 @@ public class ModifiedNodeState extends A
};
}
+ /**
+ * Since we keep track of an explicit base node state for a
+ * {@link ModifiedNodeState} instance, we can do this in two steps:
+ * first compare the base states to each other (often a fast operation),
+ * ignoring all changed properties and child nodes for which we have
+ * further modifications, and then compare all the modified properties
+ * and child nodes to those in the given base state.
+ */
+ @Override
+ public void compareAgainstBaseState(
+ NodeState base, final NodeStateDiff diff) {
+ this.base.compareAgainstBaseState(base, new NodeStateDiff() {
+ @Override
+ public void propertyAdded(PropertyState after) {
+ if (!properties.containsKey(after.getName())) {
+ diff.propertyAdded(after);
+ }
+ }
+ @Override
+ public void propertyChanged(
+ PropertyState before, PropertyState after) {
+ if (!properties.containsKey(before.getName())) {
+ diff.propertyChanged(before, after);
+ }
+ }
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ if (!properties.containsKey(before.getName())) {
+ diff.propertyDeleted(before);
+ }
+ }
+ @Override
+ public void childNodeAdded(String name, NodeState after) {
+ if (!nodes.containsKey(name)) {
+ diff.childNodeAdded(name, after);
+ }
+ }
+ @Override
+ public void childNodeChanged(String name, NodeState before, NodeState after) {
+ if (!nodes.containsKey(name)) {
+ diff.childNodeChanged(name, before, after);
+ }
+ }
+ @Override
+ public void childNodeDeleted(String name, NodeState before) {
+ if (!nodes.containsKey(name)) {
+ diff.childNodeDeleted(name, before);
+ }
+ }
+ });
+
+ for (Map.Entry<String, PropertyState> entry : properties.entrySet()) {
+ PropertyState before = base.getProperty(entry.getKey());
+ PropertyState after = entry.getValue();
+ if (before == null && after == null) {
+ // do nothing
+ } else if (after == null) {
+ diff.propertyDeleted(before);
+ } else if (before == null) {
+ diff.propertyAdded(after);
+ } else if (!before.equals(after)) {
+ diff.propertyChanged(before, after);
+ }
+ }
+
+ for (Map.Entry<String, NodeState> entry : nodes.entrySet()) {
+ String name = entry.getKey();
+ NodeState before = base.getChildNode(name);
+ NodeState after = entry.getValue();
+ if (before == null && after == null) {
+ // do nothing
+ } else if (after == null) {
+ diff.childNodeDeleted(name, before);
+ } else if (before == null) {
+ diff.childNodeAdded(name, after);
+ } else if (!before.equals(after)) {
+ diff.childNodeChanged(name, before, after);
+ }
+ }
+ }
+
+ //-----------------------------------------------------------< private >--
+
private class UnmodifiedPropertyPredicate implements Predicate<PropertyState> {
@Override
public boolean evaluate(PropertyState property) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java?rev=1358282&r1=1358281&r2=1358282&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java Fri Jul 6 15:52:53 2012
@@ -18,6 +18,9 @@ package org.apache.jackrabbit.oak.spi.st
import org.apache.jackrabbit.oak.api.PropertyState;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -65,12 +68,52 @@ public abstract class AbstractNodeState
return count(getChildNodeEntries());
}
- private static long count(Iterable<?> iterable) {
- long n = 0;
- for (Object x : iterable) {
- n++;
+ /**
+ * Generic default comparison algorithm that simply walks through the
+ * property and child node lists of the given base state and compares
+ * the entries one by one with corresponding ones (if any) in this state.
+ */
+ @Override
+ public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+ Set<String> baseProperties = new HashSet<String>();
+ for (PropertyState beforeProperty : base.getProperties()) {
+ String name = beforeProperty.getName();
+ PropertyState afterProperty = getProperty(name);
+ if (afterProperty == null) {
+ diff.propertyDeleted(beforeProperty);
+ } else {
+ baseProperties.add(name);
+ if (!beforeProperty.equals(afterProperty)) {
+ diff.propertyChanged(beforeProperty, afterProperty);
+ }
+ }
+ }
+ for (PropertyState afterProperty : getProperties()) {
+ if (!baseProperties.contains(afterProperty.getName())) {
+ diff.propertyAdded(afterProperty);
+ }
+ }
+
+ Set<String> baseChildNodes = new HashSet<String>();
+ for (ChildNodeEntry beforeCNE : base.getChildNodeEntries()) {
+ String name = beforeCNE.getName();
+ NodeState beforeChild = beforeCNE.getNodeState();
+ NodeState afterChild = getChildNode(name);
+ if (afterChild == null) {
+ diff.childNodeDeleted(name, beforeChild);
+ } else {
+ baseChildNodes.add(name);
+ if (!beforeChild.equals(afterChild)) {
+ diff.childNodeChanged(name, beforeChild, afterChild);
+ }
+ }
+ }
+ for (ChildNodeEntry afterChild : getChildNodeEntries()) {
+ String name = afterChild.getName();
+ if (!baseChildNodes.contains(name)) {
+ diff.childNodeAdded(name, afterChild.getNodeState());
+ }
}
- return n;
}
/**
@@ -153,4 +196,16 @@ public abstract class AbstractNodeState
return 0;
}
+ //-----------------------------------------------------------< private >--
+
+ private static long count(Iterable<?> iterable) {
+ long n = 0;
+ Iterator<?> iterator = iterable.iterator();
+ while (iterator.hasNext()) {
+ iterator.next();
+ n++;
+ }
+ return n;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStore.java?rev=1358282&r1=1358281&r2=1358282&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStore.java Fri Jul 6 15:52:53 2012
@@ -18,81 +18,12 @@
*/
package org.apache.jackrabbit.oak.spi.state;
-import org.apache.jackrabbit.oak.api.PropertyState;
-
-import java.util.HashSet;
-import java.util.Set;
public abstract class AbstractNodeStore implements NodeStore {
@Override
public void compare(NodeState before, NodeState after, NodeStateDiff diff) {
- compareProperties(before, after, diff);
- compareChildNodes(before, after, diff);
- }
-
- /**
- * Compares the properties of the given two node states.
- *
- * @param before node state before changes
- * @param after node state after changes
- * @param diff handler of node state differences
- */
- protected void compareProperties(
- NodeState before, NodeState after, NodeStateDiff diff) {
- Set<String> beforeProperties = new HashSet<String>();
-
- for (PropertyState beforeProperty : before.getProperties()) {
- String name = beforeProperty.getName();
- PropertyState afterProperty = after.getProperty(name);
- if (afterProperty == null) {
- diff.propertyDeleted(beforeProperty);
- } else {
- beforeProperties.add(name);
- if (!beforeProperty.equals(afterProperty)) {
- diff.propertyChanged(beforeProperty, afterProperty);
- }
- }
- }
-
- for (PropertyState afterProperty : after.getProperties()) {
- if (!beforeProperties.contains(afterProperty.getName())) {
- diff.propertyAdded(afterProperty);
- }
- }
- }
-
- /**
- * Compares the child nodes of the given two node states.
- *
- * @param before node state before changes
- * @param after node state after changes
- * @param diff handler of node state differences
- */
- protected void compareChildNodes(
- NodeState before, NodeState after, NodeStateDiff diff) {
- Set<String> beforeChildNodes = new HashSet<String>();
-
- for (ChildNodeEntry beforeCNE : before.getChildNodeEntries()) {
- String name = beforeCNE.getName();
- NodeState beforeChild = beforeCNE.getNodeState();
- NodeState afterChild = after.getChildNode(name);
- if (afterChild == null) {
- diff.childNodeDeleted(name, beforeChild);
- } else {
- beforeChildNodes.add(name);
- if (!beforeChild.equals(afterChild)) {
- diff.childNodeChanged(name, beforeChild, afterChild);
- }
- }
- }
-
- for (ChildNodeEntry afterChild : after.getChildNodeEntries()) {
- String name = afterChild.getName();
- if (!beforeChildNodes.contains(name)) {
- diff.childNodeAdded(name, afterChild.getNodeState());
- }
- }
+ after.compareAgainstBaseState(before, diff);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java?rev=1358282&r1=1358281&r2=1358282&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java Fri Jul 6 15:52:53 2012
@@ -159,4 +159,15 @@ public interface NodeState {
@Nonnull
Iterable<? extends ChildNodeEntry> getChildNodeEntries();
+ /**
+ * Compares this node state against the given base state. Any differences
+ * are reported by calling the relevant added/changed/deleted methods of
+ * the given handler.
+ *
+ * @param base base state
+ * @param diff handler of node state differences
+ * @since 0ak 0.4
+ */
+ void compareAgainstBaseState(NodeState base, NodeStateDiff diff);
+
}