Author: alexparvulescu
Date: Fri Apr  7 11:49:52 2017
New Revision: 1790536

URL: http://svn.apache.org/viewvc?rev=1790536&view=rev
Log:
OAK-5910 Reduce copying of data when reading mmapped records


Modified:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordId.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBlob.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStream.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordId.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordId.java?rev=1790536&r1=1790535&r2=1790536&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordId.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordId.java
 Fri Apr  7 11:49:52 2017
@@ -22,6 +22,7 @@ import static com.google.common.base.Pre
 import static java.lang.Integer.parseInt;
 import static 
org.apache.jackrabbit.oak.segment.CacheWeights.OBJECT_HEADER_SIZE;
 
+import java.nio.ByteBuffer;
 import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -102,12 +103,12 @@ public final class RecordId implements C
      * @return  this record id as byte array
      */
     @Nonnull
-    byte[] getBytes() {
+    ByteBuffer getBytes() {
         byte[] buffer = new byte[SERIALIZED_RECORD_ID_BYTES];
         BinaryUtils.writeLong(buffer, 0, segmentId.getMostSignificantBits());
         BinaryUtils.writeLong(buffer, 8, segmentId.getLeastSignificantBits());
         BinaryUtils.writeInt(buffer, 16, offset);
-        return buffer;
+        return ByteBuffer.wrap(buffer);
     }
 
     //--------------------------------------------------------< Comparable >--

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java?rev=1790536&r1=1790535&r2=1790536&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
 Fri Apr  7 11:49:52 2017
@@ -441,27 +441,18 @@ public class Segment {
         return data.getLong(pos(recordNumber, 8));
     }
 
-    /**
-     * Reads the given number of bytes starting from the given position
-     * in this segment.
-     *
-     * @param recordNumber position within segment
-     * @param buffer target buffer
-     * @param offset offset within target buffer
-     * @param length number of bytes to read
-     */
-    void readBytes(int recordNumber, byte[] buffer, int offset, int length) {
-        readBytes(recordNumber, 0, buffer, offset, length);
-    }
-
     void readBytes(int recordNumber, int position, byte[] buffer, int offset, 
int length) {
         checkNotNull(buffer);
         checkPositionIndexes(offset, offset + length, buffer.length);
-        ByteBuffer d = data.duplicate();
-        d.position(pos(recordNumber, position, length));
+        ByteBuffer d = readBytes(recordNumber, position, length);
         d.get(buffer, offset, length);
     }
 
+    ByteBuffer readBytes(int recordNumber, int position, int length) {
+        int pos = pos(recordNumber, position, length);
+        return slice(pos, length);
+    }
+
     @Nonnull
     RecordId readRecordId(int recordNumber, int rawOffset, int recordIdOffset) 
{
         return internalReadRecordId(pos(recordNumber, rawOffset, 
recordIdOffset, RECORD_ID_BYTES));
@@ -505,17 +496,9 @@ public class Segment {
         int pos = pos(offset, 1);
         long length = internalReadLength(pos);
         if (length < SMALL_LIMIT) {
-            byte[] bytes = new byte[(int) length];
-            ByteBuffer buffer = data.duplicate();
-            buffer.position(pos + 1);
-            buffer.get(bytes);
-            return new String(bytes, Charsets.UTF_8);
+            return Charsets.UTF_8.decode(slice(pos + 1, (int) 
length)).toString();
         } else if (length < MEDIUM_LIMIT) {
-            byte[] bytes = new byte[(int) length];
-            ByteBuffer buffer = data.duplicate();
-            buffer.position(pos + 2);
-            buffer.get(bytes);
-            return new String(bytes, Charsets.UTF_8);
+            return Charsets.UTF_8.decode(slice(pos + 2, (int) 
length)).toString();
         } else if (length < Integer.MAX_VALUE) {
             int size = (int) ((length + BLOCK_SIZE - 1) / BLOCK_SIZE);
             ListRecord list = new ListRecord(internalReadRecordId(pos + 8), 
size);
@@ -527,6 +510,13 @@ public class Segment {
         }
     }
 
+    private ByteBuffer slice(int pos, int length) {
+        ByteBuffer buffer = data.duplicate();
+        buffer.position(pos);
+        buffer.limit(pos + length);
+        return buffer.slice();
+    }
+
     @Nonnull
     Template readTemplate(int recordNumber) {
         int head = readInt(recordNumber);

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBlob.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBlob.java?rev=1790536&r1=1790535&r2=1790536&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBlob.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBlob.java
 Fri Apr  7 11:49:52 2017
@@ -60,9 +60,7 @@ public class SegmentBlob extends Record
     }
 
     private InputStream getInlineStream(Segment segment, int offset, int 
length) {
-        byte[] inline = new byte[length];
-        segment.readBytes(getRecordNumber(), offset, inline, 0, length);
-        return new SegmentStream(getRecordId(), inline);
+        return new SegmentStream(getRecordId(), 
segment.readBytes(getRecordNumber(), offset, length), length);
     }
 
     @Override @Nonnull
@@ -202,9 +200,7 @@ public class SegmentBlob extends Record
 
     private static String readShortBlobId(Segment segment, int recordNumber, 
byte head) {
         int length = (head & 0x0f) << 8 | (segment.readByte(recordNumber, 1) & 
0xff);
-        byte[] bytes = new byte[length];
-        segment.readBytes(recordNumber, 2, bytes, 0, length);
-        return new String(bytes, UTF_8);
+        return UTF_8.decode(segment.readBytes(recordNumber, 2, 
length)).toString();
     }
 
     private static String readLongBlobId(Segment segment, int recordNumber) {

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java?rev=1790536&r1=1790535&r2=1790536&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeState.java
 Fri Apr  7 11:49:52 2017
@@ -117,7 +117,7 @@ public class SegmentNodeState extends Re
      * @return  stable id
      */
     String getStableId() {
-        ByteBuffer buffer = ByteBuffer.wrap(getStableIdBytes());
+        ByteBuffer buffer = getStableIdBytes();
         long msb = buffer.getLong();
         long lsb = buffer.getLong();
         int offset = buffer.getInt();
@@ -132,7 +132,7 @@ public class SegmentNodeState extends Re
      *
      * @return the stable ID of this node.
      */
-    byte[] getStableIdBytes() {
+    ByteBuffer getStableIdBytes() {
         // The first record id of this node points to the stable id.
         RecordId id = getSegment().readRecordId(getRecordNumber());
 
@@ -144,9 +144,7 @@ public class SegmentNodeState extends Re
         } else {
             // Otherwise that id points to the serialised (msb, lsb, offset)
             // stable id.
-            byte[] buffer = new byte[RecordId.SERIALIZED_RECORD_ID_BYTES];
-            id.getSegment().readBytes(id.getRecordNumber(), buffer, 0, 
buffer.length);
-            return buffer;
+            return id.getSegment().readBytes(id.getRecordNumber(), 0, 
RecordId.SERIALIZED_RECORD_ID_BYTES);
         }
     }
 

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStream.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStream.java?rev=1790536&r1=1790535&r2=1790536&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStream.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStream.java
 Fri Apr  7 11:49:52 2017
@@ -26,6 +26,7 @@ import static org.apache.jackrabbit.oak.
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
 import java.util.List;
 
 import javax.annotation.CheckForNull;
@@ -72,11 +73,13 @@ public class SegmentStream extends Input
         this.length = length;
     }
 
-    SegmentStream(RecordId recordId, byte[] inline) {
+    SegmentStream(RecordId recordId, ByteBuffer inline, int length) {
         this.recordId = checkNotNull(recordId);
-        this.inline = checkNotNull(inline);
+        // TODO rewrite this class to leverage the ByteBuffer apis
+        this.inline = new byte[length];
+        inline.get(this.inline);
         this.blocks = null;
-        this.length = inline.length;
+        this.length = length;
     }
 
     List<RecordId> getBlockIds() {

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java?rev=1790536&r1=1790535&r2=1790536&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
 Fri Apr  7 11:49:52 2017
@@ -51,6 +51,7 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.SequenceInputStream;
+import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -1026,7 +1027,9 @@ public class SegmentWriter {
 
             RecordId stableId = null;
             if (state instanceof SegmentNodeState) {
-                byte[] id = ((SegmentNodeState) state).getStableIdBytes();
+                ByteBuffer bid = ((SegmentNodeState) state).getStableIdBytes();
+                byte[] id = new byte[RecordId.SERIALIZED_RECORD_ID_BYTES];
+                bid.get(id);
                 stableId = writeBlock(id, 0, id.length);
             }
             return newNodeStateWriter(stableId, ids).write(writer, store);

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java?rev=1790536&r1=1790535&r2=1790536&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java
 Fri Apr  7 11:49:52 2017
@@ -22,6 +22,8 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 
+import java.nio.ByteBuffer;
+
 import javax.annotation.Nonnull;
 
 import com.google.common.base.Supplier;
@@ -82,11 +84,17 @@ public class NodeRecordTest {
             SegmentNodeState three = writer.writeNode(two);
             writer.flush();
 
-            assertArrayEquals(three.getStableIdBytes(), 
two.getStableIdBytes());
-            assertArrayEquals(two.getStableIdBytes(), one.getStableIdBytes());
+            assertArrayEquals(asByteArray(three.getStableIdBytes()), 
asByteArray(two.getStableIdBytes()));
+            assertArrayEquals(asByteArray(two.getStableIdBytes()), 
asByteArray(one.getStableIdBytes()));
         }
     }
 
+    private static final byte[] asByteArray(ByteBuffer bytes) {
+        byte[] buffer = new byte[RecordId.SERIALIZED_RECORD_ID_BYTES];
+        bytes.get(buffer);
+        return buffer;
+    }
+
     @Test
     public void baseNodeStateShouldBeReusedAcrossGenerations() throws 
Exception {
         try (FileStore store = newFileStore()) {


Reply via email to