jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1526651 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/segment/ test/java/org/apache/jackrabbit/oak/plugins/segment/
Date Thu, 26 Sep 2013 19:22:44 GMT
Author: jukka
Date: Thu Sep 26 19:22:43 2013
New Revision: 1526651

URL: http://svn.apache.org/r1526651
Log:
OAK-1031: SegmentMK: Fewer segment lookups

Include a Segment reference in the Record base class to avoid extra lookups.
The reference is lazily adjusted to point to the correct segment to avoid
potentially costly pre-loading of all referenced segments that might not
end up being read at all.

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/BlockRecord.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/ListRecord.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
    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/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStream.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/BlockRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/BlockRecord.java?rev=1526651&r1=1526650&r2=1526651&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/BlockRecord.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/BlockRecord.java
Thu Sep 26 19:22:43 2013
@@ -24,8 +24,8 @@ class BlockRecord extends Record {
 
     private final int size;
 
-    BlockRecord(RecordId id, int size) {
-        super(id);
+    BlockRecord(Segment segment, RecordId id, int size) {
+        super(segment, id);
         this.size = size;
     }
 
@@ -34,16 +34,13 @@ class BlockRecord extends Record {
      * read starting from the given position within this block. The number
      * of bytes read is returned.
      *
-     * @param reader segment reader
      * @param position position within this block
      * @param buffer target buffer
      * @param offset offset within the target buffer
      * @param length maximum number of bytes to read
      * @return number of bytes that could be read
      */
-    public int read(
-            SegmentReader reader, int position,
-            byte[] buffer, int offset, int length) {
+    public int read(int position, byte[] buffer, int offset, int length) {
         checkElementIndex(position, size);
         checkNotNull(buffer);
         checkPositionIndexes(offset, offset + length, buffer.length);
@@ -52,7 +49,7 @@ class BlockRecord extends Record {
             length = size - position;
         }
         if (length > 0) {
-            reader.readBytes(getRecordId(), position, buffer, offset, length);
+            getSegment().readBytes(getOffset(position), buffer, offset, length);
         }
         return length;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/ListRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/ListRecord.java?rev=1526651&r1=1526650&r2=1526651&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/ListRecord.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/ListRecord.java
Thu Sep 26 19:22:43 2013
@@ -27,8 +27,8 @@ class ListRecord extends Record {
 
     private final int bucketSize;
 
-    ListRecord(RecordId id, int size) {
-        super(id);
+    ListRecord(Segment segment, RecordId id, int size) {
+        super(segment, id);
         checkArgument(size >= 0);
         this.size = size;
 
@@ -51,10 +51,9 @@ class ListRecord extends Record {
         } else {
             int bucketIndex = index / bucketSize;
             int bucketOffset = index % bucketSize;
-            RecordId bucketId = reader.readRecordId(
-                    getRecordId(), bucketIndex * Segment.RECORD_ID_BYTES);
-            ListRecord bucket =
-                new ListRecord(bucketId, bucketSize);
+            Segment segment = getSegment();
+            RecordId bucketId = segment.readRecordId(getOffset(0, bucketIndex));
+            ListRecord bucket = new ListRecord(segment, bucketId, bucketSize);
             return bucket.getEntry(reader, bucketOffset);
         }
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java?rev=1526651&r1=1526650&r2=1526651&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
Thu Sep 26 19:22:43 2013
@@ -23,6 +23,8 @@ import static com.google.common.collect.
 import static java.lang.Integer.highestOneBit;
 import static java.lang.Integer.numberOfTrailingZeros;
 
+import java.nio.ByteBuffer;
+import java.util.Collections;
 import java.util.Set;
 import java.util.UUID;
 
@@ -83,7 +85,8 @@ abstract class MapRecord extends Record 
     protected final int level;
 
     protected MapRecord(SegmentStore store, RecordId id, int size, int level) {
-        super(checkNotNull(id));
+        // FIXME: ugly hack
+        super(new Segment(store, UUID.randomUUID(), ByteBuffer.allocate(0), Collections.<UUID>emptyList()),
checkNotNull(id));
         this.store = checkNotNull(store);
         this.size = checkElementIndex(size, MAX_SIZE);
         this.level = checkPositionIndex(level, MAX_NUMBER_OF_LEVELS);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java?rev=1526651&r1=1526650&r2=1526651&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
Thu Sep 26 19:22:43 2013
@@ -16,18 +16,82 @@
  */
 package org.apache.jackrabbit.oak.plugins.segment;
 
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.UUID;
+
+import javax.annotation.Nonnull;
+
 /**
  * Record within a segment.
  */
 class Record {
 
     /**
-     * Identifier of this record.
+     * The segment that contains this record, or initially some other segment
+     * in the same store. The reference is lazily updated when the
+     * {@link #getSegment()} method is first called to prevent the potentially
+     * costly pre-loading of segments that might actually not be needed.
+     */
+    private Segment segment;
+
+    /**
+     * Identifier of the segment that contains this record. The value of
+     * this identifier never changes, but the exact instance reference may
+     * get updated by the {@link #getSegment()} method to indicate that
+     * lazy initialization has happened.
      */
-    private final RecordId id;
+    private UUID uuid;
 
-    protected Record(RecordId id) {
-        this.id = id;
+    /**
+     * Segment offset of this record.
+     */
+    private final int offset;
+
+    /**
+     * Creates a new object for the identified record. The segment from which
+     * the record identifier was read is also given as it either directly
+     * contains the identified record (common case) or can be used to look
+     * up the segment that contains the record.
+     *
+     * @param segment from which the record identifier was read
+     * @param id record identified
+     */
+    protected Record(@Nonnull Segment segment, @Nonnull RecordId id) {
+        this.segment = checkNotNull(segment);
+
+        checkNotNull(id);
+        if (equal(id.getSegmentId(), segment.getSegmentId())) {
+            this.uuid = segment.getSegmentId();
+        } else {
+            this.uuid = id.getSegmentId();
+        }
+        this.offset = id.getOffset();
+    }
+
+    // TODO: remove this ugly hack
+    protected Record(SegmentStore store, RecordId id) {
+        this(new Segment(
+                store, UUID.randomUUID(),
+                ByteBuffer.allocate(0), Collections.<UUID>emptyList()), id);
+    }
+
+    /**
+     * Returns the segment that contains this record.
+     *
+     * @return segment that contains this record
+     */
+    protected synchronized Segment getSegment() {
+        if (uuid != segment.getSegmentId()) {
+            segment = segment.getSegment(uuid);
+            checkState(uuid.equals(segment.getSegmentId()));
+            uuid = segment.getSegmentId();
+        }
+        return segment;
     }
 
     /**
@@ -35,8 +99,8 @@ class Record {
      *
      * @return record identifier
      */
-    public RecordId getRecordId() {
-        return id;
+    public synchronized RecordId getRecordId() {
+        return new RecordId(uuid, offset);
     }
 
     /**
@@ -44,8 +108,8 @@ class Record {
      *
      * @return segment offset of this record
      */
-    protected int getOffset() {
-        return id.getOffset();
+    protected final int getOffset() {
+        return offset;
     }
 
     /**
@@ -54,7 +118,7 @@ class Record {
      * @param position byte position within this record
      * @return segment offset of the given byte position
      */
-    protected int getOffset(int position) {
+    protected final int getOffset(int position) {
         return getOffset() + position;
     }
 
@@ -67,7 +131,7 @@ class Record {
      * @param ids number of record identifiers before the position
      * @return segment offset of the specified byte position
      */
-    protected int getOffset(int bytes, int ids) {
+    protected final int getOffset(int bytes, int ids) {
         return getOffset(bytes + ids * Segment.RECORD_ID_BYTES);
     }
 

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=1526651&r1=1526650&r2=1526651&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
Thu Sep 26 19:22:43 2013
@@ -152,6 +152,15 @@ public class Segment {
     }
 
     /**
+     * Returns the identified segment.
+     *
+     * @param uuid segment identifier
+     */
+    Segment getSegment(UUID uuid) {
+        return store.readSegment(uuid);
+    }
+
+    /**
      * Reads the given number of bytes starting from the given position
      * in this segment.
      *
@@ -219,7 +228,7 @@ public class Segment {
         } else if (length < Integer.MAX_VALUE) {
             int size = (int) ((length + BLOCK_SIZE - 1) / BLOCK_SIZE);
             ListRecord list =
-                    new ListRecord(internalReadRecordId(pos + 8), size);
+                    new ListRecord(this, internalReadRecordId(pos + 8), size);
             SegmentStream stream = new SegmentStream(
                     store, new RecordId(uuid, offset), list, length);
             try {
@@ -340,7 +349,8 @@ public class Segment {
             return new SegmentStream(id, inline);
         } else {
             int size = (int) ((length + BLOCK_SIZE - 1) / BLOCK_SIZE);
-            ListRecord list = new ListRecord(internalReadRecordId(pos + 8), size);
+            ListRecord list =
+                    new ListRecord(this, internalReadRecordId(pos + 8), size);
             return new SegmentStream(store, id, list, length);
         }
     }

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=1526651&r1=1526650&r2=1526651&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
Thu Sep 26 19:22:43 2013
@@ -56,14 +56,14 @@ class SegmentPropertyState extends Abstr
     private ListRecord getValueList() {
         RecordId listId = recordId;
         int size = 1;
+        Segment segment = store.readSegment(recordId.getSegmentId());
         if (isArray()) {
-            Segment segment = store.readSegment(recordId.getSegmentId());
             size = segment.readInt(recordId.getOffset());
             if (size > 0) {
                 listId = segment.readRecordId(recordId.getOffset() + 4);
             }
         }
-        return new ListRecord(listId, size);
+        return new ListRecord(segment, listId, size);
     }
 
     Map<String, RecordId> getValueRecords() {

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=1526651&r1=1526650&r2=1526651&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
Thu Sep 26 19:22:43 2013
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.plugin
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
 
 public class SegmentReader {
 
@@ -57,19 +56,6 @@ public class SegmentReader {
         return segment.readInt(recordId.getOffset() + position);
     }
 
-    public void readBytes(
-            RecordId recordId, int position,
-            byte[] buffer, int offset, int length) {
-        checkNotNull(recordId);
-        checkArgument(position >= 0);
-        checkNotNull(buffer);
-        checkPositionIndexes(offset, offset + length, buffer.length);
-
-        Segment segment = store.readSegment(recordId.getSegmentId());
-        segment.readBytes(
-                recordId.getOffset() + position, buffer, offset, length);
-    }
-
     public RecordId readRecordId(RecordId recordId, int position) {
         checkNotNull(recordId);
         checkArgument(position >= 0);
@@ -82,21 +68,15 @@ public class SegmentReader {
         checkNotNull(recordId);
         checkArgument(numberOfEntries >= 0);
 
+        Segment segment = store.readSegment(recordId.getSegmentId());
         if (numberOfEntries > 0) {
-            Segment segment = store.readSegment(recordId.getSegmentId());
             RecordId id = segment.readRecordId(recordId.getOffset());
-            return new ListRecord(id, numberOfEntries);
+            return new ListRecord(segment, id, numberOfEntries);
         } else {
-            return new ListRecord(recordId, numberOfEntries);
+            return new ListRecord(segment, recordId, numberOfEntries);
         }
     }
 
-    public BlockRecord readBlock(RecordId recordId, int size) {
-        checkNotNull(recordId);
-        checkArgument(size > 0);
-        return new BlockRecord(recordId, size);
-    }
-
     SegmentStore getStore() {
         return store;
     }

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=1526651&r1=1526650&r2=1526651&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
Thu Sep 26 19:22:43 2013
@@ -157,9 +157,11 @@ public class SegmentStream extends Input
             }
 
             SegmentReader reader = new SegmentReader(store);
-            BlockRecord block = reader.readBlock(
-                    blocks.getEntry(reader, blockIndex), BLOCK_SIZE);
-            len = block.read(reader, blockOffset, b, off, len);
+            BlockRecord block = new BlockRecord(
+                    blocks.getSegment(),
+                    blocks.getEntry(reader, blockIndex),
+                    BLOCK_SIZE);
+            len = block.read(blockOffset, b, off, len);
             position += len;
             return len;
         }

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=1526651&r1=1526650&r2=1526651&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
Thu Sep 26 19:22:43 2013
@@ -26,12 +26,14 @@ import static org.junit.Assert.assertTru
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
+import java.util.UUID;
 
 import org.apache.jackrabbit.oak.plugins.segment.memory.MemoryStore;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
@@ -50,6 +52,10 @@ public class RecordTest {
 
     private SegmentStore store = new MemoryStore();
 
+    private Segment segment = new Segment(
+            store, UUID.randomUUID(),
+            ByteBuffer.allocate(0), Collections.<UUID>emptyList());
+
     private SegmentReader reader = new SegmentReader(store);
 
     private SegmentWriter writer = store.getWriter();
@@ -59,20 +65,20 @@ public class RecordTest {
     @Test
     public void testBlockRecord() {
         RecordId blockId = writer.writeBlock(bytes, 0, bytes.length);
-        BlockRecord block = new BlockRecord(blockId, bytes.length);
+        BlockRecord block = new BlockRecord(segment, blockId, bytes.length);
 
         // Check reading with all valid positions and lengths
         for (int n = 1; n < bytes.length; n++) {
             for (int i = 0; i + n <= bytes.length; i++) {
                 Arrays.fill(bytes, i, i + n, (byte) '.');
-                assertEquals(n, block.read(reader, i, bytes, i, n));
+                assertEquals(n, block.read(i, bytes, i, n));
                 assertEquals(hello, new String(bytes, Charsets.UTF_8));
             }
         }
 
         // Check reading with a too long length
         byte[] large = new byte[bytes.length * 2];
-        assertEquals(bytes.length, block.read(reader, 0, large, 0, large.length));
+        assertEquals(bytes.length, block.read(0, large, 0, large.length));
         assertEquals(hello, new String(large, 0, bytes.length, Charsets.UTF_8));
     }
 
@@ -104,7 +110,7 @@ public class RecordTest {
 
     private ListRecord writeList(int size, RecordId id) {
         List<RecordId> list = Collections.nCopies(size, id);
-        return new ListRecord(writer.writeList(list), size);
+        return new ListRecord(segment, writer.writeList(list), size);
     }
 
     @Test



Mime
View raw message