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 2013/03/06 15:13:15 UTC
svn commit: r1453336 -
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
Author: jukka
Date: Wed Mar 6 14:13:15 2013
New Revision: 1453336
URL: http://svn.apache.org/r1453336
Log:
OAK-593: Segment-based MK
Each new session starts a new SegmentWriter, so we need to keep the default memory use down. Use an automatically growing byte buffer to achieve that.
Modified:
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/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=1453336&r1=1453335&r2=1453336&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 Wed Mar 6 14:13:15 2013
@@ -23,6 +23,7 @@ import static com.google.common.base.Pre
import static com.google.common.base.Preconditions.checkPositionIndexes;
import static com.google.common.base.Preconditions.checkState;
import static org.apache.jackrabbit.oak.plugins.segment.MapRecord.BUCKETS_PER_LEVEL;
+import static org.apache.jackrabbit.oak.plugins.segment.Segment.MAX_SEGMENT_SIZE;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -55,6 +56,8 @@ import com.google.common.io.ByteStreams;
public class SegmentWriter {
+ private static final byte[] EMPTY_BUFFER = new byte[0];
+
static final int BLOCK_SIZE = 1 << 12; // 4kB
private final SegmentStore store;
@@ -74,12 +77,10 @@ public class SegmentWriter {
/**
* The segment write buffer, filled from the end to the beginning
- * (see OAK-629). Note that we currently allocate the entire buffer
- * right from the beginning. It might turn out that a better approach
- * would be to start with a smaller buffer that grows automatically,
- * or to use a pool of pre-allocated buffers.
+ * (see OAK-629). The buffer grows automatically up to
+ * {@link Segment#MAX_SEGMENT_SIZE}.
*/
- private final byte[] buffer = new byte[Segment.MAX_SEGMENT_SIZE];
+ private byte[] buffer = EMPTY_BUFFER;
/**
* The number of bytes already written (or allocated). Counted from
@@ -102,14 +103,15 @@ public class SegmentWriter {
byte[] data = buffer;
if (length < buffer.length) {
data = new byte[length];
- int start = buffer.length - length;
- System.arraycopy(buffer, start, data, 0, data.length);
+ System.arraycopy(
+ buffer, buffer.length - length, data, 0, data.length);
}
store.createSegment(new Segment(
store, uuid, data, uuids.keySet(), strings, templates));
uuid = UUID.randomUUID();
+ buffer = EMPTY_BUFFER;
length = 0;
uuids.clear();
strings.clear();
@@ -137,14 +139,26 @@ public class SegmentWriter {
int alignment = Segment.RECORD_ALIGN_BYTES - 1;
int alignedSize = (fullSize + alignment) & ~alignment;
- if (length + alignedSize > buffer.length
+ if (length + alignedSize > MAX_SEGMENT_SIZE
|| uuids.size() + segmentIds.size() > 0x100) {
flush();
}
+ if (length + alignedSize > buffer.length) {
+ int newBufferLength = Math.max(2 * buffer.length, 4096);
+ while (length + alignedSize > newBufferLength) {
+ newBufferLength *= 2;
+ }
+ byte[] newBuffer = new byte[newBufferLength];
+ System.arraycopy(
+ buffer, buffer.length - length,
+ newBuffer, newBuffer.length - length, length);
+ buffer = newBuffer;
+ }
length += alignedSize;
+ checkState(length <= MAX_SEGMENT_SIZE);
position = buffer.length - length;
- return new RecordId(uuid, position);
+ return new RecordId(uuid, MAX_SEGMENT_SIZE - length);
}
private synchronized void writeRecordId(RecordId id) {
@@ -159,7 +173,7 @@ public class SegmentWriter {
}
int offset = id.getOffset();
- checkState(0 <= offset && offset < buffer.length);
+ checkState(0 <= offset && offset < MAX_SEGMENT_SIZE);
checkState((offset & (Segment.RECORD_ALIGN_BYTES - 1)) == 0);
buffer[position++] = segmentIndex.byteValue();