Author: jukka
Date: Tue Sep 24 17:09:04 2013
New Revision: 1525945
URL: http://svn.apache.org/r1525945
Log:
OAK-630: SegmentMK: Implement compareAgainstBaseState
Optimize comparisons against empty base states
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java?rev=1525945&r1=1525944&r2=1525945&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
Tue Sep 24 17:09:04 2013
@@ -153,4 +153,23 @@ class MapBranch extends MapRecord {
return true;
}
+ @Override
+ public boolean compareAgainstEmptyMap(MapDiff diff) {
+ Segment segment = getSegment();
+ int offset = getOffset() + 8;
+
+ for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
+ if ((bitmap & (1 << i)) != 0) {
+ MapRecord bucket =
+ MapRecord.readMap(store, segment.readRecordId(offset));
+ if (!bucket.compareAgainstEmptyMap(diff)) {
+ return false;
+ }
+ offset += RECORD_ID_BYTES;
+ }
+ }
+
+ return true;
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java?rev=1525945&r1=1525944&r2=1525945&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
Tue Sep 24 17:09:04 2013
@@ -156,6 +156,23 @@ class MapLeaf extends MapRecord {
return true;
}
+ @Override
+ public boolean compareAgainstEmptyMap(MapDiff diff) {
+ Segment segment = getSegment();
+
+ int keyOffset = getOffset() + 4 + size * 4;
+ int valueOffset = keyOffset + size * RECORD_ID_BYTES;
+ for (int i = 0; i < size; i++) {
+ RecordId key = segment.readRecordId(keyOffset + i *
RECORD_ID_BYTES);
+ RecordId value = segment.readRecordId(valueOffset + i *
RECORD_ID_BYTES);
+ if (!diff.entryAdded(segment.readString(key), value)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
//-----------------------------------------------------------< private >--
private Iterator<String> getKeyIterator() {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java?rev=1525945&r1=1525944&r2=1525945&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
Tue Sep 24 17:09:04 2013
@@ -111,6 +111,8 @@ abstract class MapRecord extends Record
abstract Iterable<MapEntry> getEntries();
+ abstract boolean compareAgainstEmptyMap(MapDiff diff);
+
interface MapDiff {
boolean entryAdded(String key, RecordId after);
boolean entryChanged(String key, RecordId before, RecordId after);
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=1525945&r1=1525944&r2=1525945&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
Tue Sep 24 17:09:04 2013
@@ -24,7 +24,6 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
@@ -139,7 +138,8 @@ public class SegmentNodeState extends Ab
if (base == this) {
return true; // no changes
} else if (base == EMPTY_NODE || !base.exists()) { // special case
- return EmptyNodeState.compareAgainstEmptyState(this, diff);
+ return getTemplate().compareAgainstEmptyState(
+ store, recordId, diff);
} else if (base instanceof SegmentNodeState) {
SegmentNodeState that = (SegmentNodeState) base;
return recordId.equals(that.recordId)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java?rev=1525945&r1=1525944&r2=1525945&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
Tue Sep 24 17:09:04 2013
@@ -33,6 +33,7 @@ import javax.annotation.Nonnull;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
+
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
@@ -541,6 +542,66 @@ public class Template {
return true;
}
+ public boolean compareAgainstEmptyState(
+ final SegmentStore store, RecordId recordId,
+ final NodeStateDiff diff) {
+ checkNotNull(store);
+ checkNotNull(recordId);
+ checkNotNull(diff);
+
+ // Type properties
+ if (primaryType != null && !diff.propertyAdded(primaryType)) {
+ return false;
+ }
+ if (mixinTypes != null && !diff.propertyAdded(mixinTypes)) {
+ return false;
+ }
+
+ Segment segment = store.readSegment(recordId.getSegmentId());
+ int offset = recordId.getOffset() + RECORD_ID_BYTES;
+
+ if (childName == MANY_CHILD_NODES) {
+ RecordId childNodesId = segment.readRecordId(offset);
+ MapRecord children = MapRecord.readMap(store, childNodesId);
+ children.compareAgainstEmptyMap(new MapDiff() {
+ @Override
+ public boolean entryAdded(String key, RecordId after) {
+ return diff.childNodeAdded(
+ key, new SegmentNodeState(store, after));
+ }
+ @Override
+ public boolean entryChanged(
+ String key, RecordId before, RecordId after) {
+ throw new IllegalStateException();
+ }
+ @Override
+ public boolean entryDeleted(String key, RecordId before) {
+ throw new IllegalStateException();
+ }
+ });
+ offset += RECORD_ID_BYTES;
+ } else if (childName != ZERO_CHILD_NODES) {
+ RecordId childNodeId = segment.readRecordId(offset);
+ if (!diff.childNodeAdded(
+ childName, new SegmentNodeState(store, childNodeId))) {
+ return false;
+ }
+ offset += RECORD_ID_BYTES;
+ }
+
+ // Other properties
+ for (int i = 0; i < properties.length; i++) {
+ if (!diff.propertyAdded(new SegmentPropertyState(
+ properties[i], store, segment.readRecordId(offset)))) {
+ return false;
+ }
+ offset += RECORD_ID_BYTES;
+ }
+
+ return true;
+ }
+
+
private boolean fastEquals(NodeState a, NodeState b) {
if (a == b) {
return true;