Author: jukka
Date: Fri Sep 27 02:08:43 2013
New Revision: 1526774
URL: http://svn.apache.org/r1526774
Log:
OAK-1031: SegmentMK: Fewer segment lookups
Use the segment tracking mechanism in map records
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/MapEntry.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/Segment.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.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=1526774&r1=1526773&r2=1526774&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
Fri Sep 27 02:08:43 2013
@@ -23,7 +23,6 @@ import static com.google.common.collect.
import static com.google.common.collect.Iterables.transform;
import static java.lang.Integer.bitCount;
import static java.util.Arrays.asList;
-import static
org.apache.jackrabbit.oak.plugins.segment.Segment.RECORD_ID_BYTES;
import java.util.Collections;
@@ -35,8 +34,8 @@ class MapBranch extends MapRecord {
private final int bitmap;
- MapBranch(SegmentStore store, RecordId id, int size, int level, int
bitmap) {
- super(store, id, size, level);
+ MapBranch(Segment segment, RecordId id, int size, int level, int bitmap) {
+ super(segment, id, size, level);
checkArgument(size > BUCKETS_PER_LEVEL);
checkArgument(level < MAX_NUMBER_OF_LEVELS);
this.bitmap = bitmap;
@@ -44,13 +43,12 @@ class MapBranch extends MapRecord {
RecordId[] getBuckets() {
Segment segment = getSegment();
- int offset = getOffset() + 8;
-
+ int bytes = 8;
+ int ids = 0;
RecordId[] buckets = new RecordId[BUCKETS_PER_LEVEL];
for (int i = 0; i < buckets.length; i++) {
if ((bitmap & (1 << i)) != 0) {
- buckets[i] = segment.readRecordId(offset);
- offset += RECORD_ID_BYTES;
+ buckets[i] = segment.readRecordId(getOffset(bytes, ids++));
} else {
buckets[i] = null;
}
@@ -68,10 +66,11 @@ class MapBranch extends MapRecord {
int bit = 1 << index;
if ((bitmap & bit) != 0) {
- int offset = getOffset()
- + 8 + bitCount(bitmap & (bit - 1)) * RECORD_ID_BYTES;
- RecordId id = getSegment().readRecordId(offset);
- return MapRecord.readMap(store, id).getEntry(key);
+ Segment segment = getSegment();
+ int bytes = 8;
+ int ids = bitCount(bitmap & (bit - 1));
+ RecordId id = segment.readRecordId(getOffset(bytes, ids));
+ return MapRecord.readMap(segment, id).getEntry(key);
} else {
return null;
}
@@ -79,13 +78,14 @@ class MapBranch extends MapRecord {
@Override
Iterable<String> getKeys() {
+ final Segment segment = getSegment();
return concat(transform(
asList(getBuckets()),
new Function<RecordId, Iterable<String>>() {
@Override @Nullable
public Iterable<String> apply(@Nullable RecordId input) {
if (input != null) {
- return MapRecord.readMap(store, input).getKeys();
+ return MapRecord.readMap(segment, input).getKeys();
} else {
return Collections.emptyList();
}
@@ -95,13 +95,14 @@ class MapBranch extends MapRecord {
@Override
Iterable<MapEntry> getEntries() {
+ final Segment segment = getSegment();
return concat(transform(
asList(getBuckets()),
new Function<RecordId, Iterable<MapEntry>>() {
@Override @Nullable
public Iterable<MapEntry> apply(@Nullable RecordId input) {
if (input != null) {
- return MapRecord.readMap(store,
input).getEntries();
+ return MapRecord.readMap(segment,
input).getEntries();
} else {
return Collections.emptyList();
}
@@ -122,12 +123,14 @@ class MapBranch extends MapRecord {
MapBranch after = this;
checkState(after.level == before.level);
+ Segment afterSegment = after.getSegment();
+ Segment beforeSegment = before.getSegment();
RecordId[] afterBuckets = after.getBuckets();
RecordId[] beforeBuckets = before.getBuckets();
for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
if (afterBuckets[i] == null) {
if (beforeBuckets[i] != null) {
- MapRecord map = MapRecord.readMap(store, beforeBuckets[i]);
+ MapRecord map = MapRecord.readMap(beforeSegment,
beforeBuckets[i]);
for (MapEntry entry : map.getEntries()) {
if (!diff.entryDeleted(entry.getName(),
entry.getValue())) {
return false;
@@ -135,15 +138,15 @@ class MapBranch extends MapRecord {
}
}
} else if (beforeBuckets[i] == null) {
- MapRecord map = MapRecord.readMap(store, afterBuckets[i]);
+ MapRecord map = MapRecord.readMap(afterSegment,
afterBuckets[i]);
for (MapEntry entry : map.getEntries()) {
if (!diff.entryAdded(entry.getName(), entry.getValue())) {
return false;
}
}
} else if (!afterBuckets[i].equals(beforeBuckets[i])) {
- MapRecord afterMap = MapRecord.readMap(store, afterBuckets[i]);
- MapRecord beforeMap = MapRecord.readMap(store,
beforeBuckets[i]);
+ MapRecord afterMap = MapRecord.readMap(afterSegment,
afterBuckets[i]);
+ MapRecord beforeMap = MapRecord.readMap(beforeSegment,
beforeBuckets[i]);
if (!afterMap.compare(beforeMap, diff)) {
return false;
}
@@ -156,16 +159,15 @@ class MapBranch extends MapRecord {
@Override
public boolean compareAgainstEmptyMap(MapDiff diff) {
Segment segment = getSegment();
- int offset = getOffset() + 8;
-
+ int bytes = 8;
+ int ids = 0;
for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
if ((bitmap & (1 << i)) != 0) {
- MapRecord bucket =
- MapRecord.readMap(store, segment.readRecordId(offset));
+ MapRecord bucket = MapRecord.readMap(
+ segment, segment.readRecordId(getOffset(bytes,
ids++)));
if (!bucket.compareAgainstEmptyMap(diff)) {
return false;
}
- offset += RECORD_ID_BYTES;
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapEntry.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapEntry.java?rev=1526774&r1=1526773&r2=1526774&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapEntry.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapEntry.java
Fri Sep 27 02:08:43 2013
@@ -34,7 +34,7 @@ import com.google.common.collect.Compari
class MapEntry extends AbstractChildNodeEntry
implements Map.Entry<RecordId, RecordId>, Comparable<MapEntry> {
- private final SegmentStore store;
+ private final Segment segment;
private final String name;
@@ -42,8 +42,8 @@ class MapEntry extends AbstractChildNode
private RecordId value;
- MapEntry(SegmentStore store, String name, RecordId key, RecordId value) {
- this.store = checkNotNull(store);
+ MapEntry(Segment segment, String name, RecordId key, RecordId value) {
+ this.segment = checkNotNull(segment);
this.name = checkNotNull(name);
this.key = checkNotNull(key);
this.value = value;
@@ -59,7 +59,7 @@ class MapEntry extends AbstractChildNode
@Override @Nonnull
public NodeState getNodeState() {
checkState(value != null);
- return new SegmentNodeState(store, value);
+ return new SegmentNodeState(segment.store, value);
}
//---------------------------------------------------------< Map.Entry >--
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=1526774&r1=1526773&r2=1526774&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
Fri Sep 27 02:08:43 2013
@@ -28,8 +28,8 @@ import com.google.common.collect.Maps;
class MapLeaf extends MapRecord {
- MapLeaf(SegmentStore store, RecordId id, int size, int level) {
- super(store, id, size, level);
+ MapLeaf(Segment segment, RecordId id, int size, int level) {
+ super(segment, id, size, level);
checkArgument(size != 0 || level == 0);
checkArgument(size <= BUCKETS_PER_LEVEL || level ==
MAX_NUMBER_OF_LEVELS);
}
@@ -39,20 +39,19 @@ class MapLeaf extends MapRecord {
RecordId[] values = new RecordId[size];
Segment segment = getSegment();
- int offset = getOffset() + 4 + size * 4;
+ int bytes = 4 + size * 4;
+ int ids = 0;
for (int i = 0; i < size; i++) {
- keys[i] = segment.readRecordId(offset);
- offset += RECORD_ID_BYTES;
+ keys[i] = segment.readRecordId(getOffset(bytes, ids++));
}
for (int i = 0; i < size; i++) {
- values[i] = segment.readRecordId(offset);
- offset += RECORD_ID_BYTES;
+ values[i] = segment.readRecordId(getOffset(bytes, ids++));
}
Map<String, MapEntry> entries = Maps.newHashMapWithExpectedSize(size);
for (int i = 0; i < size; i++) {
String name = segment.readString(keys[i]);
- entries.put(name, new MapEntry(store, name, keys[i], values[i]));
+ entries.put(name, new MapEntry(segment, name, keys[i], values[i]));
}
return entries;
}
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=1526774&r1=1526773&r2=1526774&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
Fri Sep 27 02:08:43 2013
@@ -60,43 +60,30 @@ abstract class MapRecord extends Record
*/
protected static final int MAX_SIZE = (1 << SIZE_BITS) - 1; // ~268e6
- static MapRecord readMap(SegmentStore store, RecordId id) {
- checkNotNull(store);
- checkNotNull(id);
-
- Segment segment = checkNotNull(store).readSegment(id.getSegmentId());
- int head = segment.readInt(id.getOffset());
+ static MapRecord readMap(Segment segment, RecordId id) {
+ segment = checkNotNull(segment).getSegment(checkNotNull(id));
+ int offset = id.getOffset();
+ int head = segment.readInt(offset);
int level = head >>> SIZE_BITS;
int size = head & ((1 << SIZE_BITS) - 1);
if (size > BUCKETS_PER_LEVEL && level < MAX_NUMBER_OF_LEVELS) {
- int bitmap = segment.readInt(id.getOffset() + 4);
- return new MapBranch(store, id, size, level, bitmap);
+ int bitmap = segment.readInt(offset + 4);
+ return new MapBranch(segment, id, size, level, bitmap);
} else {
- return new MapLeaf(store, id, size, level);
+ return new MapLeaf(segment, id, size, level);
}
}
- protected final SegmentStore store;
-
protected final int size;
protected final int level;
- protected MapRecord(SegmentStore store, RecordId id, int size, int level) {
- super(store.getWriter().getDummySegment(), id);
- this.store = checkNotNull(store);
+ protected MapRecord(Segment segment, RecordId id, int size, int level) {
+ super(segment, id);
this.size = checkElementIndex(size, MAX_SIZE);
this.level = checkPositionIndex(level, MAX_NUMBER_OF_LEVELS);
}
- protected Segment getSegment() {
- return getSegment(getRecordId().getSegmentId());
- }
-
- protected Segment getSegment(UUID uuid) {
- return store.readSegment(uuid);
- }
-
int size() {
return size;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java?rev=1526774&r1=1526773&r2=1526774&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
Fri Sep 27 02:08:43 2013
@@ -89,7 +89,7 @@ public class Segment {
}
};
- private final SegmentStore store;
+ final SegmentStore store; // TODO: should be private
private final UUID uuid;
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java?rev=1526774&r1=1526773&r2=1526774&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
Fri Sep 27 02:08:43 2013
@@ -247,7 +247,7 @@ public class SegmentWriter {
for (MapEntry entry : array) {
writeRecordId(entry.getValue());
}
- return new MapLeaf(store, id, size, level);
+ return new MapLeaf(dummySegment, id, size, level);
}
}
@@ -268,7 +268,7 @@ public class SegmentWriter {
for (RecordId id : ids) {
writeRecordId(id);
}
- return new MapBranch(store, mapId, size, level, bitmap);
+ return new MapBranch(dummySegment, mapId, size, level, bitmap);
}
}
@@ -288,19 +288,19 @@ public class SegmentWriter {
if (entries == null || entries.isEmpty()) {
if (baseId != null) {
- return MapRecord.readMap(store, baseId);
+ return MapRecord.readMap(dummySegment, baseId);
} else if (level == 0) {
synchronized (this) {
RecordId id = prepare(4);
writeInt(0);
- return new MapLeaf(store, id, 0, 0);
+ return new MapLeaf(dummySegment, id, 0, 0);
}
} else {
return null;
}
} else if (baseId != null) {
// FIXME: messy code with lots of duplication
- MapRecord base = MapRecord.readMap(store, baseId);
+ MapRecord base = MapRecord.readMap(dummySegment, baseId);
if (base instanceof MapLeaf) {
Map<String, MapEntry> map = ((MapLeaf) base).getMapEntries();
for (MapEntry entry : entries) {
@@ -353,7 +353,7 @@ public class SegmentWriter {
synchronized (this) {
RecordId id = prepare(4);
writeInt(0);
- return new MapLeaf(store, id, 0, 0);
+ return new MapLeaf(dummySegment, id, 0, 0);
}
} else {
return null;
@@ -448,7 +448,7 @@ public class SegmentWriter {
for (Map.Entry<String, RecordId> entry : changes.entrySet()) {
String name = entry.getKey();
entries.add(new MapEntry(
- store, name, writeString(name), entry.getValue()));
+ dummySegment, name, writeString(name), entry.getValue()));
}
RecordId baseId = null;
if (base != null) {
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=1526774&r1=1526773&r2=1526774&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
Fri Sep 27 02:08:43 2013
@@ -281,7 +281,7 @@ public class Template {
int offset = recordId.getOffset() + RECORD_ID_BYTES;
Segment segment = store.readSegment(recordId.getSegmentId());
RecordId childNodesId = segment.readRecordId(offset);
- return MapRecord.readMap(store, childNodesId);
+ return MapRecord.readMap(segment, childNodesId);
}
public boolean hasChildNode(
@@ -562,7 +562,7 @@ public class Template {
if (childName == MANY_CHILD_NODES) {
RecordId childNodesId = segment.readRecordId(offset);
- MapRecord children = MapRecord.readMap(store, childNodesId);
+ MapRecord children = MapRecord.readMap(segment, childNodesId);
children.compareAgainstEmptyMap(new MapDiff() {
@Override
public boolean entryAdded(String key, RecordId after) {