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/10/25 18:39:13 UTC
svn commit: r1535775 - 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: Fri Oct 25 16:39:12 2013
New Revision: 1535775
URL: http://svn.apache.org/r1535775
Log:
OAK-593: Segment-based MK
Special case references to the same segment, to reduce the overhead of
storing and accessing the majority of record identifiers.
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/SegmentWriter.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.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=1535775&r1=1535774&r2=1535775&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 Oct 25 16:39:12 2013
@@ -47,9 +47,9 @@ public class Segment {
/**
* The limit on segment references within one segment. Since record
* identifiers use one byte to indicate the referenced segment, a single
- * segment can hold references to up to 256 segments.
+ * segment can hold references to up to 255 segments plus itself.
*/
- static final int SEGMENT_REFERENCE_LIMIT = 1 << 8; // 256
+ static final int SEGMENT_REFERENCE_LIMIT = (1 << 8) - 1; // 255
/**
* The number of bytes (or bits of address space) to use for the
@@ -193,8 +193,14 @@ public class Segment {
}
private RecordId internalReadRecordId(int pos) {
- int refpos = data.position() + (data.get(pos) & 0xff) * 16;
- UUID refid = new UUID(data.getLong(refpos), data.getLong(refpos + 8));
+ UUID refid;
+ int refpos = data.get(pos) & 0xff;
+ if (refpos != 0xff) {
+ refpos = data.position() + refpos * 16;
+ refid = new UUID(data.getLong(refpos), data.getLong(refpos + 8));
+ } else {
+ refid = uuid;
+ }
int offset =
(((data.get(pos + 1) & 0xff) << 8) | (data.get(pos + 2) & 0xff))
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=1535775&r1=1535774&r2=1535775&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 Oct 25 16:39:12 2013
@@ -161,7 +161,7 @@ public class SegmentWriter {
Set<UUID> segmentIds = new HashSet<UUID>();
for (RecordId id : checkNotNull(ids)) {
UUID segmentId = id.getSegmentId();
- if (!uuids.containsKey(segmentId)) {
+ if (!equal(uuid, segmentId) && !uuids.containsKey(segmentId)) {
segmentIds.add(segmentId);
}
}
@@ -187,18 +187,22 @@ public class SegmentWriter {
checkNotNull(id);
UUID segmentId = id.getSegmentId();
- Byte segmentIndex = uuids.get(segmentId);
- if (segmentIndex == null) {
- checkState(uuids.size() < Segment.SEGMENT_REFERENCE_LIMIT);
- segmentIndex = Byte.valueOf((byte) uuids.size());
- uuids.put(segmentId, segmentIndex);
+ if (equal(uuid, segmentId)) {
+ buffer[position++] = (byte) 0xff;
+ } else {
+ Byte segmentIndex = uuids.get(segmentId);
+ if (segmentIndex == null) {
+ checkState(uuids.size() < Segment.SEGMENT_REFERENCE_LIMIT);
+ segmentIndex = Byte.valueOf((byte) uuids.size());
+ uuids.put(segmentId, segmentIndex);
+ }
+ buffer[position++] = segmentIndex.byteValue();
}
int offset = id.getOffset();
checkState(0 <= offset && offset < MAX_SEGMENT_SIZE);
checkState((offset & (Segment.RECORD_ALIGN_BYTES - 1)) == 0);
- buffer[position++] = segmentIndex.byteValue();
buffer[position++] = (byte) (offset >> (8 + Segment.RECORD_ALIGN_BITS));
buffer[position++] = (byte) (offset >> Segment.RECORD_ALIGN_BITS);
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java?rev=1535775&r1=1535774&r2=1535775&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java Fri Oct 25 16:39:12 2013
@@ -45,24 +45,24 @@ public class SegmentSizeTest {
builder = EMPTY_NODE.builder();
builder.setProperty("foo", "bar");
- assertEquals(40, getSize(builder));
+ assertEquals(24, getSize(builder));
assertEquals(8, getAmortizedSize(builder));
builder = EMPTY_NODE.builder();
builder.setProperty("foo", "bar");
builder.setProperty("baz", 123);
- assertEquals(56, getSize(builder));
+ assertEquals(40, getSize(builder));
assertEquals(12, getAmortizedSize(builder));
builder = EMPTY_NODE.builder();
builder.child("foo");
- assertEquals(56, getSize(builder));
+ assertEquals(40, getSize(builder));
assertEquals(12, getAmortizedSize(builder));
builder = EMPTY_NODE.builder();
builder.child("foo");
builder.child("bar");
- assertEquals(84, getSize(builder));
+ assertEquals(68, getSize(builder));
assertEquals(40, getAmortizedSize(builder));
}
@@ -106,7 +106,7 @@ public class SegmentSizeTest {
public void testAccessControlNodes() {
NodeBuilder builder = EMPTY_NODE.builder();
builder.setProperty("jcr:primaryType", "rep:ACL", Type.NAME);
- assertEquals(36, getSize(builder));
+ assertEquals(20, getSize(builder));
assertEquals(4, getAmortizedSize(builder));
NodeBuilder deny = builder.child("deny");
@@ -114,7 +114,7 @@ public class SegmentSizeTest {
deny.setProperty("rep:principalName", "everyone");
deny.setProperty(PropertyStates.createProperty(
"rep:privileges", ImmutableList.of("jcr:read"), Type.NAMES));
- assertEquals(160, getSize(builder));
+ assertEquals(144, getSize(builder));
assertEquals(28, getAmortizedSize(builder));
NodeBuilder allow = builder.child("allow");
@@ -122,7 +122,7 @@ public class SegmentSizeTest {
allow.setProperty("rep:principalName", "administrators");
allow.setProperty(PropertyStates.createProperty(
"rep:privileges", ImmutableList.of("jcr:all"), Type.NAMES));
- assertEquals(280, getSize(builder));
+ assertEquals(264, getSize(builder));
assertEquals(72, getAmortizedSize(builder));
NodeBuilder deny0 = builder.child("deny0");
@@ -131,7 +131,7 @@ public class SegmentSizeTest {
deny0.setProperty("rep:glob", "*/activities/*");
builder.setProperty(PropertyStates.createProperty(
"rep:privileges", ImmutableList.of("jcr:read"), Type.NAMES));
- assertEquals(372, getSize(builder));
+ assertEquals(356, getSize(builder));
assertEquals(108, getAmortizedSize(builder));
NodeBuilder allow0 = builder.child("allow0");
@@ -139,7 +139,7 @@ public class SegmentSizeTest {
allow0.setProperty("rep:principalName", "user-administrators");
allow0.setProperty(PropertyStates.createProperty(
"rep:privileges", ImmutableList.of("jcr:all"), Type.NAMES));
- assertEquals(428, getSize(builder));
+ assertEquals(412, getSize(builder));
assertEquals(136, getAmortizedSize(builder));
}
@@ -155,7 +155,7 @@ public class SegmentSizeTest {
SegmentNodeState state = writer.writeNode(builder.getNodeState());
Segment segment = store.readSegment(state.getRecordId().getSegmentId());
- assertEquals(26760, Segment.WEIGHER.weigh(null, segment));
+ assertEquals(26744, Segment.WEIGHER.weigh(null, segment));
writer.flush(); // force flushing of the previous segment
@@ -163,7 +163,7 @@ public class SegmentSizeTest {
builder.child("child1000");
state = writer.writeNode(builder.getNodeState());
segment = store.readSegment(state.getRecordId().getSegmentId());
- assertEquals(144, Segment.WEIGHER.weigh(null, segment));
+ assertEquals(128, Segment.WEIGHER.weigh(null, segment));
}
private int getSize(NodeBuilder builder) {