Author: jukka
Date: Fri Jan 24 02:01:39 2014
New Revision: 1560882
URL: http://svn.apache.org/r1560882
Log:
OAK-1333: SegmentMK: Support for Blobs in external storage
Move blob parsing code to SegmentBlob
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/SegmentBlob.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStream.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.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=1560882&r1=1560881&r2=1560882&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 Jan 24 02:01:39 2014
@@ -222,6 +222,18 @@ public class Segment {
return data.get(pos(offset, 1));
}
+ short readShort(int offset) {
+ return data.getShort(pos(offset, 2));
+ }
+
+ int readInt(int offset) {
+ return data.getInt(pos(offset, 4));
+ }
+
+ long readLong(int offset) {
+ return data.getLong(pos(offset, 8));
+ }
+
/**
* Returns the identified segment.
*
@@ -284,14 +296,6 @@ public class Segment {
return new RecordId(refid, offset);
}
- int readInt(int offset) {
- int pos = pos(offset, 4);
- return (data.get(pos) & 0xff) << 24
- | (data.get(pos + 1) & 0xff) << 16
- | (data.get(pos + 2) & 0xff) << 8
- | (data.get(pos + 3) & 0xff);
- }
-
String readString(final RecordId id) {
return getSegment(id).readString(id.getOffset());
}
@@ -442,43 +446,7 @@ public class Segment {
SegmentBlob createBlob(int offset) {
RecordId id = new RecordId(uuid, offset);
- int n = readByte(offset) & 0xff;
- return new SegmentBlob(this, id, (n & 0xe0) == 0xe0);
- }
-
- SegmentStream readStream(int offset) {
- RecordId id = new RecordId(uuid, offset);
- int pos = pos(offset, 1);
- long length = internalReadLength(pos);
- if (length < Segment.MEDIUM_LIMIT) {
- byte[] inline = new byte[(int) length];
- ByteBuffer buffer = data.duplicate();
- if (length < Segment.SMALL_LIMIT) {
- buffer.position(pos + 1);
- } else {
- buffer.position(pos + 2);
- }
- buffer.get(inline);
- return new SegmentStream(id, inline);
- } else {
- int size = (int) ((length + BLOCK_SIZE - 1) / BLOCK_SIZE);
- ListRecord list =
- new ListRecord(this, internalReadRecordId(pos + 8), size);
- return new SegmentStream(store, id, list, length);
- }
- }
-
- String readBlobReference(int offset) {
- int pos = pos(offset, 1);
-
- int length = (data.get(pos++) & 0x1f) << 8
- | (data.get(pos++) & 0xff);
-
- byte[] bytes = new byte[length];
- ByteBuffer buffer = data.duplicate();
- buffer.position(pos + 8); // skip blob length
- buffer.get(bytes);
- return new String(bytes, Charsets.UTF_8);
+ return new SegmentBlob(this, id);
}
long readBlobLength(int offset) {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentBlob.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentBlob.java?rev=1560882&r1=1560881&r2=1560882&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentBlob.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentBlob.java
Fri Jan 24 02:01:39 2014
@@ -16,6 +16,11 @@
*/
package org.apache.jackrabbit.oak.plugins.segment;
+import static com.google.common.base.Charsets.UTF_8;
+import static org.apache.jackrabbit.oak.plugins.segment.Segment.MEDIUM_LIMIT;
+import static org.apache.jackrabbit.oak.plugins.segment.Segment.SMALL_LIMIT;
+import static
org.apache.jackrabbit.oak.plugins.segment.SegmentWriter.BLOCK_SIZE;
+
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -26,34 +31,69 @@ import java.io.InputStream;
class SegmentBlob extends Record implements Blob {
- private boolean external;
-
- SegmentBlob(Segment segment, RecordId id, boolean external) {
+ SegmentBlob(Segment segment, RecordId id) {
super(segment, id);
+ }
- this.external = external;
+ private InputStream getInlineStream(
+ Segment segment, int offset, int length) {
+ byte[] inline = new byte[length];
+ segment.readBytes(offset, inline, 0, length);
+ return new SegmentStream(getRecordId(), inline);
}
@Override @Nonnull
public InputStream getNewStream() {
- if (external) {
- String refererence = getSegment().readBlobReference(getOffset());
+ Segment segment = getSegment();
+ int offset = getOffset();
+ byte head = segment.readByte(offset);
+ if ((head & 0x80) == 0x00) {
+ // 0xxx xxxx: small value
+ return getInlineStream(segment, offset + 1, head);
+ } else if ((head & 0xc0) == 0x80) {
+ // 10xx xxxx: medium value
+ int length = (segment.readShort(offset) & 0x3fff) + SMALL_LIMIT;
+ return getInlineStream(segment, offset + 2, length);
+ } else if ((head & 0xe0) == 0xc0) {
+ // 110x xxxx: long value
+ long length = (segment.readLong(offset) & 0x1fffffffffffffffL) +
MEDIUM_LIMIT;
+ int listSize = (int) ((length + BLOCK_SIZE - 1) / BLOCK_SIZE);
+ ListRecord list = new ListRecord(
+ segment, segment.readRecordId(offset + 8), listSize);
+ return new SegmentStream(getStore(), getRecordId(), list, length);
+ } else if ((head & 0xf0) == 0xe0) {
+ // 1110 xxxx: external value
+ int length = segment.readShort(offset) & 0x0fff;
+ byte[] bytes = new byte[length];
+ segment.readBytes(offset + 10, bytes, 0, length);
+ String refererence = new String(bytes, UTF_8);
return getStore().readBlob(refererence).getNewStream();
+ } else {
+ throw new IllegalStateException(String.format(
+ "Unexpected value record type: %02x", head & 0xff));
}
- return getSegment().readStream(getOffset());
}
@Override
public long length() {
- if (external) {
- return getSegment().readBlobLength(getOffset());
- }
-
- SegmentStream stream = (SegmentStream) getNewStream();
- try {
- return stream.getLength();
- } finally {
- stream.close();
+ Segment segment = getSegment();
+ int offset = getOffset();
+ byte head = segment.readByte(offset);
+ if ((head & 0x80) == 0x00) {
+ // 0xxx xxxx: small value
+ return head;
+ } else if ((head & 0xc0) == 0x80) {
+ // 10xx xxxx: medium value
+ return (segment.readShort(offset) & 0x3fff) + SMALL_LIMIT;
+ } else if ((head & 0xe0) == 0xc0) {
+ // 110x xxxx: long value
+ return (segment.readLong(offset) & 0x1fffffffffffffffL) +
MEDIUM_LIMIT;
+ } else if ((head & 0xf0) == 0xe0) {
+ // 1110 xxxx: external value
+ return segment.readLong(offset + 2);
+ } else {
+ throw new IllegalStateException(String.format(
+ "Unexpected value record type: %02x", head & 0xff));
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStream.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStream.java?rev=1560882&r1=1560881&r2=1560882&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStream.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStream.java
Fri Jan 24 02:01:39 2014
@@ -43,7 +43,6 @@ public class SegmentStream extends Input
return null;
}
-
private final SegmentStore store;
private final RecordId recordId;
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=1560882&r1=1560881&r2=1560882&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 Jan 24 02:01:39 2014
@@ -679,7 +679,7 @@ public class SegmentWriter {
private SegmentBlob writeBlob(ExternalBlob blob) {
RecordId id = writeValueRecord(blob.getReference(), blob.length());
- return new SegmentBlob(dummySegment, id, true);
+ return new SegmentBlob(dummySegment, id);
}
/**
@@ -701,7 +701,7 @@ public class SegmentWriter {
Closeables.close(stream, threw);
}
}
- return new SegmentBlob(dummySegment, id, false);
+ return new SegmentBlob(dummySegment, id);
}
private RecordId internalWriteStream(InputStream stream)