jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1560882 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment: Segment.java SegmentBlob.java SegmentStream.java SegmentWriter.java
Date Fri, 24 Jan 2014 02:01:39 GMT
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)



Mime
View raw message