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 2014/04/02 07:20:20 UTC
svn commit: r1583881 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment:
ListRecord.java SegmentStream.java
Author: jukka
Date: Wed Apr 2 05:20:20 2014
New Revision: 1583881
URL: http://svn.apache.org/r1583881
Log:
OAK-1660 - SegmentMK: Optimize reading of large binaries
Some further improvements
Modified:
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/SegmentStream.java
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=1583881&r1=1583880&r2=1583881&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 Wed Apr 2 05:20:20 2014
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkElementIndex;
+import static com.google.common.base.Preconditions.checkPositionIndexes;
import static com.google.common.collect.Lists.newArrayListWithCapacity;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
@@ -71,13 +72,27 @@ class ListRecord extends Record {
if (index + count > size) {
count = size - index;
}
- if (size == 0 || count == 0) {
+ if (count == 0) {
return emptyList();
- } else if (size == 1) {
- return singletonList(getRecordId());
+ } else if (count == 1) {
+ return singletonList(getEntry(index));
+ } else {
+ List<RecordId> ids = newArrayListWithCapacity(count);
+ getEntries(index, count, ids);
+ return ids;
+ }
+ }
+
+ private void getEntries(int index, int count, List<RecordId> ids) {
+ checkPositionIndexes(index, index + count, size);
+ Segment segment = getSegment();
+ if (size == 1) {
+ ids.add(getRecordId());
+ } else if (bucketSize == 1) {
+ for (int i = 0; i < count; i++) {
+ ids.add(segment.readRecordId(getOffset(0, index + i)));
+ }
} else {
- List<RecordId> list = newArrayListWithCapacity(count);
- Segment segment = getSegment();
while (count > 0) {
int bucketIndex = index / bucketSize;
int bucketOffset = index % bucketSize;
@@ -85,11 +100,10 @@ class ListRecord extends Record {
ListRecord bucket = new ListRecord(
id, Math.min(bucketSize, size - bucketIndex * bucketSize));
int n = Math.min(bucket.size() - bucketOffset, count);
- list.addAll(bucket.getEntries(bucketOffset, n));
+ bucket.getEntries(bucketOffset, n, ids);
index += n;
count -= n;
}
- return list;
}
}
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=1583881&r1=1583880&r2=1583881&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 Wed Apr 2 05:20:20 2014
@@ -19,7 +19,7 @@ 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;
-import static org.apache.jackrabbit.oak.plugins.segment.Segment.MAX_SEGMENT_SIZE;
+import static com.google.common.base.Preconditions.checkState;
import static org.apache.jackrabbit.oak.plugins.segment.SegmentWriter.BLOCK_SIZE;
import java.io.IOException;
@@ -139,39 +139,46 @@ public class SegmentStream extends Input
if (inline != null) {
System.arraycopy(inline, (int) position, b, off, len);
- position += len;
- return len;
} else {
int blockIndex = (int) (position / BLOCK_SIZE);
int blockOffset = (int) (position % BLOCK_SIZE);
int blockCount =
- Math.min(MAX_SEGMENT_SIZE, blockOffset + len + BLOCK_SIZE - 1) // round up
+ (blockOffset + len + BLOCK_SIZE - 1) // round up
/ BLOCK_SIZE;
+ int remaining = len;
List<RecordId> ids = blocks.getEntries(blockIndex, blockCount);
RecordId first = ids.get(0); // guaranteed to contain at least one
- SegmentId segmentId = first.getSegmentId();
- int offset = first.getOffset();
int count = 1;
- while (count < ids.size()) {
- RecordId id = ids.get(count);
- if (id.getSegmentId() == segmentId
- && id.getOffset() == offset + count * BLOCK_SIZE) {
+ for (int i = 1; i <= ids.size(); i++) {
+ RecordId id = null;
+ if (i < ids.size()) {
+ id = ids.get(i);
+ }
+
+ if (id != null
+ && id.getSegmentId() == first.getSegmentId()
+ && id.getOffset() == first.getOffset() + count * BLOCK_SIZE) {
count++;
} else {
- break;
+ int blockSize = Math.min(
+ blockOffset + remaining, count * BLOCK_SIZE);
+ BlockRecord block = new BlockRecord(first, blockSize);
+ int n = blockSize - blockOffset;
+ checkState(block.read(blockOffset, b, off, n) == n);
+ off += n;
+ remaining -= n;
+
+ first = id;
+ count = 1;
+ blockOffset = 0;
}
}
-
- if (blockOffset + len > count * BLOCK_SIZE) {
- len = count * BLOCK_SIZE - blockOffset;
- }
-
- BlockRecord block = new BlockRecord(first, blockOffset + len);
- len = block.read(blockOffset, b, off, len);
- position += len;
- return len;
+ checkState(remaining == 0);
}
+
+ position += len;
+ return len;
}
@Override