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/25 15:50:20 UTC
svn commit: r1449732 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/segment/
test/java/org/apache/jackrabbit/oak/plugins/segment/
Author: jukka
Date: Mon Feb 25 14:50:20 2013
New Revision: 1449732
URL: http://svn.apache.org/r1449732
Log:
OAK-593: Segment-based MK
Reduce the number of readSegment() calls by keeping better track of the current segment where referenced values are most likely located
Modified:
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/SegmentPropertyState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentReader.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
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=1449732&r1=1449731&r2=1449732&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 Mon Feb 25 14:50:20 2013
@@ -19,10 +19,12 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndexes;
+import static org.apache.jackrabbit.oak.plugins.segment.SegmentWriter.BLOCK_SIZE;
import java.nio.ByteBuffer;
import java.util.UUID;
+import com.google.common.base.Charsets;
import com.google.common.cache.Weigher;
class Segment {
@@ -92,8 +94,27 @@ class Segment {
private final OffsetCache<String> strings = new OffsetCache<String>() {
@Override
protected String load(int offset) {
- return new SegmentReader(store).readString(
- new RecordId(uuid, offset));
+ int pos = offset - (MAX_SEGMENT_SIZE - data.length);
+ checkElementIndex(pos, data.length);
+ long length = internalReadLength(pos);
+ if (length < SMALL_LIMIT) {
+ return new String(data, pos + 1, (int) length, Charsets.UTF_8);
+ } else if (length < MEDIUM_LIMIT) {
+ return new String(data, pos + 2, (int) length, Charsets.UTF_8);
+ } else if (length < Integer.MAX_VALUE) {
+ int size = (int) ((length + BLOCK_SIZE - 1) / BLOCK_SIZE);
+ ListRecord list = new ListRecord(readRecordId(offset + 8), size);
+ SegmentStream stream = new SegmentStream(
+ new SegmentReader(store), new RecordId(uuid, offset),
+ list, length);
+ try {
+ return stream.getString();
+ } finally {
+ stream.close();
+ }
+ } else {
+ throw new IllegalStateException("String is too long: " + length);
+ }
}
};
@@ -185,4 +206,31 @@ class Segment {
return segment.readString(id.getOffset());
}
+ long readLength(int position) {
+ int pos = position - (MAX_SEGMENT_SIZE - data.length);
+ checkElementIndex(pos, data.length);
+ return internalReadLength(pos);
+ }
+
+ private long internalReadLength(int pos) {
+ int length = data[pos++] & 0xff;
+ if ((length & 0x80) == 0) {
+ return length;
+ } else if ((length & 0x40) == 0) {
+ return ((length & 0x3f) << 8
+ | data[pos++] & 0xff)
+ + SMALL_LIMIT;
+ } else {
+ return (((long) length & 0x3f) << 56
+ | ((long) (data[pos++] & 0xff)) << 48
+ | ((long) (data[pos++] & 0xff)) << 40
+ | ((long) (data[pos++] & 0xff)) << 32
+ | ((long) (data[pos++] & 0xff)) << 24
+ | ((long) (data[pos++] & 0xff)) << 16
+ | ((long) (data[pos++] & 0xff)) << 8
+ | ((long) (data[pos++] & 0xff)))
+ + MEDIUM_LIMIT;
+ }
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java?rev=1449732&r1=1449731&r2=1449732&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java Mon Feb 25 14:50:20 2013
@@ -113,12 +113,14 @@ class SegmentPropertyState extends Abstr
checkNotNull(type);
checkArgument(!type.isArray(), "Type must not be an array type");
+ Segment segment = reader.getStore().readSegment(recordId.getSegmentId());
+
Type<?> base;
ListRecord values;
if (isArray()) {
base = getType().getBaseType();
- int size = reader.readInt(recordId, 0);
- RecordId listId = reader.readRecordId(recordId, 4);
+ int size = segment.readInt(recordId.getOffset());
+ RecordId listId = segment.readRecordId(recordId.getOffset() + 4);
values = new ListRecord(listId, size);
} else {
base = getType();
@@ -130,7 +132,7 @@ class SegmentPropertyState extends Abstr
if (type == Type.BINARY) {
return (T) new SegmentBlob(reader, valueId);
} else {
- String value = reader.readString(valueId);
+ String value = segment.readString(valueId);
if (type == Type.STRING || type == Type.URI
|| type == Type.NAME || type == Type.PATH
|| type == Type.REFERENCE || type == Type.WEAKREFERENCE) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentReader.java?rev=1449732&r1=1449731&r2=1449732&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentReader.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentReader.java Mon Feb 25 14:50:20 2013
@@ -37,12 +37,6 @@ public class SegmentReader {
private final SegmentStore store;
- private final LoadingCache<RecordId, String> strings =
- CacheBuilder.newBuilder()
- .maximumWeight(1 << 20) // 1 MB
- .weigher(newStringWeigher())
- .build(newStringLoader());
-
private final LoadingCache<RecordId, Template> templates =
CacheBuilder.newBuilder()
.maximumSize(1000)
@@ -52,29 +46,6 @@ public class SegmentReader {
this.store = store;
}
- private static Weigher<RecordId, String> newStringWeigher() {
- return new Weigher<RecordId, String>() {
- @Override
- public int weigh(RecordId key, String value) {
- return 32 + value.length() * 2;
- }
- };
- }
-
- private CacheLoader<RecordId, String> newStringLoader() {
- return new CacheLoader<RecordId, String>() {
- @Override
- public String load(RecordId key) throws Exception {
- SegmentStream stream = readStream(key);
- try {
- return stream.getString();
- } finally {
- stream.close();
- }
- }
- };
- }
-
private CacheLoader<RecordId, Template> newTemplateLoader() {
return new CacheLoader<RecordId, Template>() {
@Override
@@ -95,7 +66,7 @@ public class SegmentReader {
if (hasPrimaryType) {
RecordId primaryId = segment.readRecordId(offset);
primaryType = PropertyStates.createProperty(
- "jcr:primaryType", readString(primaryId), Type.NAME);
+ "jcr:primaryType", segment.readString(primaryId), Type.NAME);
offset += Segment.RECORD_ID_BYTES;
}
@@ -104,7 +75,7 @@ public class SegmentReader {
String[] mixins = new String[mixinCount];
for (int i = 0; i < mixins.length; i++) {
RecordId mixinId = segment.readRecordId(offset);
- mixins[i] = readString(mixinId);
+ mixins[i] = segment.readString(mixinId);
offset += Segment.RECORD_ID_BYTES;
}
mixinTypes = PropertyStates.createProperty(
@@ -116,7 +87,7 @@ public class SegmentReader {
childName = Template.MANY_CHILD_NODES;
} else if (!zeroChildNodes) {
RecordId childNameId = segment.readRecordId(offset);
- childName = readString(childNameId);
+ childName = segment.readString(childNameId);
offset += Segment.RECORD_ID_BYTES;
}
@@ -127,7 +98,7 @@ public class SegmentReader {
offset += Segment.RECORD_ID_BYTES;
byte type = segment.readByte(offset++);
properties[i] = new PropertyTemplate(
- readString(propertyNameId),
+ segment.readString(propertyNameId),
Type.fromTag(Math.abs(type), type < 0));
}
@@ -146,15 +117,6 @@ public class SegmentReader {
}
}
- public String readString(RecordId recordId) {
- try {
- return strings.get(recordId);
- } catch (ExecutionException e) {
- throw new IllegalStateException(
- "Unable to access string record " + recordId, e);
- }
- }
-
public long readLength(RecordId recordId) {
checkNotNull(recordId);
Segment segment = store.readSegment(recordId.getSegmentId());
@@ -162,24 +124,7 @@ public class SegmentReader {
}
private long readLength(Segment segment, int offset) {
- int length = segment.readByte(offset++) & 0xff;
- if ((length & 0x80) == 0) {
- return length;
- } else if ((length & 0x40) == 0) {
- return ((length & 0x3f) << 8
- | segment.readByte(offset) & 0xff)
- + Segment.SMALL_LIMIT;
- } else {
- return (((long) length & 0x3f) << 56
- | ((long) (segment.readByte(offset++) & 0xff)) << 48
- | ((long) (segment.readByte(offset++) & 0xff)) << 40
- | ((long) (segment.readByte(offset++) & 0xff)) << 32
- | ((long) (segment.readByte(offset++) & 0xff)) << 24
- | ((long) (segment.readByte(offset++) & 0xff)) << 16
- | ((long) (segment.readByte(offset++) & 0xff)) << 8
- | ((long) (segment.readByte(offset) & 0xff)))
- + Segment.MEDIUM_LIMIT;
- }
+ return segment.readLength(offset);
}
public SegmentStream readStream(RecordId recordId) {
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java?rev=1449732&r1=1449731&r2=1449732&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java Mon Feb 25 14:50:20 2013
@@ -161,11 +161,12 @@ public class RecordTest {
RecordId large = writer.writeString(builder.toString());
writer.flush();
+ Segment segment = store.readSegment(large.getSegmentId());
- assertEquals("", reader.readString(empty));
- assertEquals(" ", reader.readString(space));
- assertEquals("Hello, World!", reader.readString(hello));
- assertEquals(builder.toString(), reader.readString(large));
+ assertEquals("", segment.readString(empty));
+ assertEquals(" ", segment.readString(space));
+ assertEquals("Hello, World!", segment.readString(hello));
+ assertEquals(builder.toString(), segment.readString(large));
}
@Test