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 2013/02/20 14:13:17 UTC
svn commit: r1448150 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment:
NodeTemplate.java SegmentNodeState.java
Author: jukka
Date: Wed Feb 20 13:13:17 2013
New Revision: 1448150
URL: http://svn.apache.org/r1448150
Log:
OAK-630: SegmentMK: Implement compareAgainstBaseState
Initial SegmentNodeState.compareAgainstBaseState implementation
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/NodeTemplate.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/NodeTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/NodeTemplate.java?rev=1448150&r1=1448149&r2=1448150&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/NodeTemplate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/NodeTemplate.java Wed Feb 20 13:13:17 2013
@@ -16,11 +16,15 @@
*/
package org.apache.jackrabbit.oak.plugins.segment;
+import static com.google.common.base.Preconditions.checkElementIndex;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -32,6 +36,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.segment.MapRecord.Entry;
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 com.google.common.base.Function;
import com.google.common.base.Objects;
@@ -181,16 +186,10 @@ class NodeTemplate {
} else if ("jcr:mixinTypes".equals(name) && mixinTypes != null) {
return mixinTypes;
} else {
- int offset = 8;
- if (hasNoChildNodes()) {
- offset = 4;
- }
for (int i = 0; i < properties.length; i++) {
int diff = name.compareTo(properties[i].getName());
if (diff == 0) {
- return new SegmentPropertyState(
- properties[i], reader,
- reader.readRecordId(recordId, offset + i * 4));
+ return getProperty(reader, recordId, i);
} else if (diff < 0) {
return null;
}
@@ -199,6 +198,21 @@ class NodeTemplate {
}
}
+ private PropertyState getProperty(
+ SegmentReader reader, RecordId recordId, int index) {
+ checkNotNull(reader);
+ checkNotNull(recordId);
+ checkElementIndex(index, properties.length);
+
+ int offset = 8;
+ if (hasNoChildNodes()) {
+ offset = 4;
+ }
+ return new SegmentPropertyState(
+ properties[index], reader,
+ reader.readRecordId(recordId, offset + index * 4));
+ }
+
public Iterable<PropertyState> getProperties(
SegmentReader reader, RecordId recordId) {
List<PropertyState> list =
@@ -308,6 +322,116 @@ class NodeTemplate {
}
}
+ public void compareAgainstBaseState(
+ SegmentReader reader, RecordId afterId,
+ NodeTemplate beforeTemplate, RecordId beforeId,
+ NodeStateDiff diff) {
+ checkNotNull(reader);
+ checkNotNull(afterId);
+ checkNotNull(beforeTemplate);
+ checkNotNull(beforeId);
+ checkNotNull(diff);
+
+ // Compare type properties
+ compareProperties(beforeTemplate.primaryType, primaryType, diff);
+ compareProperties(beforeTemplate.mixinTypes, mixinTypes, diff);
+
+ // Compare other properties, leveraging the ordering
+ int beforeIndex = 0;
+ int afterIndex = 0;
+ while (beforeIndex < beforeTemplate.properties.length
+ && afterIndex < properties.length) {
+ int d = properties[afterIndex].compareTo(
+ beforeTemplate.properties[beforeIndex]);
+ PropertyState beforeProperty = null;
+ PropertyState afterProperty = null;
+ if (d < 0) {
+ afterProperty = getProperty(reader, afterId, afterIndex++);
+ } else if (d > 0) {
+ beforeProperty = beforeTemplate.getProperty(
+ reader, beforeId, beforeIndex++);
+ } else {
+ afterProperty = getProperty(reader, afterId, afterIndex++);
+ beforeProperty = beforeTemplate.getProperty(
+ reader, beforeId, beforeIndex++);
+ }
+ compareProperties(beforeProperty, afterProperty, diff);
+ }
+ while (afterIndex < properties.length) {
+ diff.propertyAdded(getProperty(reader, afterId, afterIndex++));
+ }
+ while (beforeIndex < beforeTemplate.properties.length) {
+ diff.propertyDeleted(beforeTemplate.getProperty(
+ reader, beforeId, beforeIndex++));
+ }
+
+ if (hasNoChildNodes()) {
+ if (!beforeTemplate.hasNoChildNodes()) {
+ for (ChildNodeEntry entry :
+ beforeTemplate.getChildNodeEntries(reader, beforeId)) {
+ diff.childNodeDeleted(
+ entry.getName(), entry.getNodeState());
+ }
+ }
+ } else if (hasOneChildNode()) {
+ NodeState afterNode = getChildNode(childName, reader, afterId);
+ NodeState beforeNode = beforeTemplate.getChildNode(
+ childName, reader, beforeId);
+ if (beforeNode == null) {
+ diff.childNodeAdded(childName, afterNode);
+ } else if (!beforeNode.equals(afterNode)) {
+ diff.childNodeChanged(childName, beforeNode, afterNode);
+ }
+ if ((beforeTemplate.hasOneChildNode() && beforeNode == null)
+ || beforeTemplate.hasManyChildNodes()) {
+ for (ChildNodeEntry entry :
+ beforeTemplate.getChildNodeEntries(reader, beforeId)) {
+ if (!childName.equals(entry.getName())) {
+ diff.childNodeDeleted(
+ entry.getName(), entry.getNodeState());
+ }
+ }
+ }
+ } else {
+ // TODO: Leverage the HAMT data structure for the comparison
+ Set<String> baseChildNodes = new HashSet<String>();
+ for (ChildNodeEntry beforeCNE
+ : beforeTemplate.getChildNodeEntries(reader, beforeId)) {
+ String name = beforeCNE.getName();
+ NodeState beforeChild = beforeCNE.getNodeState();
+ NodeState afterChild = getChildNode(name, reader, afterId);
+ if (afterChild == null) {
+ diff.childNodeDeleted(name, beforeChild);
+ } else {
+ baseChildNodes.add(name);
+ if (!beforeChild.equals(afterChild)) {
+ diff.childNodeChanged(name, beforeChild, afterChild);
+ }
+ }
+ }
+ for (ChildNodeEntry afterChild
+ : getChildNodeEntries(reader, afterId)) {
+ String name = afterChild.getName();
+ if (!baseChildNodes.contains(name)) {
+ diff.childNodeAdded(name, afterChild.getNodeState());
+ }
+ }
+ }
+ }
+
+ private void compareProperties(
+ PropertyState before, PropertyState after, NodeStateDiff diff) {
+ if (before == null) {
+ if (after != null) {
+ diff.propertyAdded(after);
+ }
+ } else if (after == null) {
+ diff.propertyDeleted(before);
+ } else if (!before.equals(after)) {
+ diff.propertyChanged(before, after);
+ }
+ }
+
//------------------------------------------------------------< Object >--
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java?rev=1448150&r1=1448149&r2=1448150&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java Wed Feb 20 13:13:17 2013
@@ -27,6 +27,7 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
class SegmentNodeState extends AbstractNodeState {
@@ -102,6 +103,20 @@ class SegmentNodeState extends AbstractN
return new MemoryNodeBuilder(this);
}
+ @Override
+ public void compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
+ if (base instanceof SegmentNodeState) {
+ SegmentNodeState that = (SegmentNodeState) base;
+ if (!recordId.equals(that.recordId)) {
+ getTemplate().compareAgainstBaseState(
+ reader, recordId, that.getTemplate(), that.recordId,
+ diff);
+ }
+ } else {
+ super.compareAgainstBaseState(base, diff); // fallback
+ }
+ }
+
public boolean equals(Object object) {
if (this == object) {
return true;