Author: jukka
Date: Sat Mar 15 01:25:12 2014
New Revision: 1577772
URL: http://svn.apache.org/r1577772
Log:
OAK-1526: Lock contention in SegmentIdFactory
Rename SegmentIdFactory to SegmentTracker and move the segment cache to it.
Make SegmentId.getSegment() unsynhronized for the common case
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
(contents, props changed)
- copied, changed from r1577651,
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java
Removed:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.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/SegmentBlob.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentId.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeBuilder.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/http/HttpStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/MapRecordTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java
Sat Mar 15 01:25:12 2014
@@ -25,7 +25,7 @@ public final class RecordId implements C
public static RecordId[] EMPTY_ARRAY = new RecordId[0];
- public static RecordId fromString(SegmentIdFactory factory, String id) {
+ public static RecordId fromString(SegmentTracker factory, String id) {
int colon = id.indexOf(':');
if (colon != -1) {
UUID uuid = UUID.fromString(id.substring(0, colon));
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=1577772&r1=1577771&r2=1577772&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
Sat Mar 15 01:25:12 2014
@@ -34,8 +34,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
-import javax.annotation.Nonnull;
-
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
@@ -98,7 +96,7 @@ public class Segment {
static int ROOT_COUNT_OFFSET = 6;
- private final SegmentStore store;
+ private final SegmentTracker tracker;
private final SegmentId id;
@@ -116,19 +114,12 @@ public class Segment {
*/
private final ConcurrentMap<Integer, Template> templates =
newConcurrentMap();
- public Segment(SegmentStore store, SegmentId id, ByteBuffer data) {
- this.store = checkNotNull(store);
+ public Segment(SegmentTracker tracker, SegmentId id, ByteBuffer data) {
+ this.tracker = checkNotNull(tracker);
this.id = checkNotNull(id);
this.data = checkNotNull(data);
}
- public Segment(SegmentStore store, ByteBuffer data) {
- this.store = checkNotNull(store);
- this.id = store.getFactory().newDataSegmentId();
- this.data = checkNotNull(data);
- id.setSegment(this);
- }
-
/**
* Maps the given record offset to the respective position within the
* internal {@link #data} array. The validity of a record with the given
@@ -145,16 +136,6 @@ public class Segment {
return pos;
}
- /**
- * Returns the store that contains this segment.
- *
- * @return containing segment store
- */
- @Nonnull
- SegmentStore getStore() {
- return store;
- }
-
public SegmentId getSegmentId() {
return id;
}
@@ -170,7 +151,7 @@ public class Segment {
int refpos = data.position() + refid * 16;
long msb = data.getLong(refpos);
long lsb = data.getLong(refpos + 8);
- return store.getFactory().getSegmentId(msb, lsb);
+ return tracker.getSegmentId(msb, lsb);
}
}
@@ -187,6 +168,14 @@ public class Segment {
return data.remaining();
}
+ public long getCacheSize() {
+ if (data.isDirect()) {
+ return 1024 + data.remaining();
+ } else {
+ return 1024 + 2 * data.remaining();
+ }
+ }
+
/**
* Writes this segment to the given output stream.
*
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=1577772&r1=1577771&r2=1577772&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
Sat Mar 15 01:25:12 2014
@@ -67,7 +67,7 @@ class SegmentBlob extends Record impleme
byte[] bytes = new byte[length];
segment.readBytes(offset + 10, bytes, 0, length);
String refererence = new String(bytes, UTF_8);
- return segment.getStore().readBlob(refererence).getNewStream();
+ return
segment.getSegmentId().getTracker().getStore().readBlob(refererence).getNewStream();
} 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/SegmentId.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentId.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentId.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentId.java
Sat Mar 15 01:25:12 2014
@@ -16,9 +16,6 @@
*/
package org.apache.jackrabbit.oak.plugins.segment;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.lang.ref.SoftReference;
import java.util.UUID;
/**
@@ -26,40 +23,23 @@ import java.util.UUID;
*/
public class SegmentId implements Comparable<SegmentId> {
- private static final long MSB_MASK = ~(0xfL << 12);
-
- private static final long VERSION = (0x4L << 12);
-
- private static final long LSB_MASK = ~(0xfL << 60);
-
- private static final long DATA = 0xAL << 60;
-
- private static final long BULK = 0xBL << 60;
-
- private final SegmentStore store;
+ private final SegmentTracker tracker;
private final long msb;
private final long lsb;
- private SoftReference<Segment> reference = null;
-
- SegmentId(SegmentStore store, long msb, long lsb, Segment segment) {
- this.store = store;
- this.msb = msb;
- this.lsb = lsb;
- this.reference = new SoftReference<Segment>(segment);
- }
+ private volatile Segment segment;
- SegmentId(SegmentStore store, long msb, long lsb) {
- this.store = store;
+ SegmentId(SegmentTracker tracker, long msb, long lsb, Segment segment) {
+ this.tracker = tracker;
this.msb = msb;
this.lsb = lsb;
- this.reference = null;
+ this.segment = segment;
}
- public SegmentStore getStore() {
- return store;
+ SegmentId(SegmentTracker tracker, long msb, long lsb) {
+ this(tracker, msb, lsb, null);
}
/**
@@ -68,7 +48,7 @@ public class SegmentId implements Compar
* @return {@code true} for a data segment, {@code false} otherwise
*/
public boolean isDataSegmentId() {
- return (lsb & ~LSB_MASK) == DATA;
+ return (lsb >>> 60) == 0xAL;
}
/**
@@ -77,7 +57,7 @@ public class SegmentId implements Compar
* @return {@code true} for a bulk segment, {@code false} otherwise
*/
public boolean isBulkSegmentId() {
- return (lsb & ~LSB_MASK) == BULK;
+ return (lsb >>> 60) == 0xBL;
}
public boolean equals(long msb, long lsb) {
@@ -92,28 +72,36 @@ public class SegmentId implements Compar
return lsb;
}
- public synchronized Segment getSegment() {
- Segment segment = null;
- if (reference != null) {
- segment = reference.get();
- }
+ public Segment getSegment() {
+ Segment segment = this.segment;
if (segment == null) {
- segment = store.readSegment(this);
- checkState(segment != null);
- reference = new SoftReference<Segment>(segment);
+ synchronized (this) {
+ segment = this.segment;
+ if (segment == null) {
+ segment = tracker.getSegment(this);
+ }
+ }
}
return segment;
}
synchronized void setSegment(Segment segment) {
- reference = new SoftReference<Segment>(segment);
+ this.segment = segment;
+ }
+
+ public SegmentTracker getTracker() {
+ return tracker;
}
//--------------------------------------------------------< Comparable >--
@Override
- public int compareTo(SegmentId o) {
- return 0;
+ public int compareTo(SegmentId that) {
+ int d = Long.valueOf(this.msb).compareTo(Long.valueOf(that.msb));
+ if (d == 0) {
+ d = Long.valueOf(this.lsb).compareTo(Long.valueOf(that.lsb));
+ }
+ return d;
}
//------------------------------------------------------------< Object >--
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeBuilder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeBuilder.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeBuilder.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeBuilder.java
Sat Mar 15 01:25:12 2014
@@ -32,9 +32,9 @@ public class SegmentNodeBuilder extends
private long updateCount = 0;
- SegmentNodeBuilder(SegmentNodeState base, SegmentWriter writer) {
+ SegmentNodeBuilder(SegmentNodeState base) {
super(base);
- this.writer = writer;
+ this.writer =
base.getRecordId().getSegmentId().getTracker().getWriter();
}
//-------------------------------------------------< MemoryNodeBuilder >--
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
Sat Mar 15 01:25:12 2014
@@ -374,7 +374,7 @@ public class SegmentNodeState extends Re
@Override @Nonnull
public SegmentNodeBuilder builder() {
- return new SegmentNodeBuilder(this,
getSegment().getStore().getWriter());
+ return new SegmentNodeBuilder(this);
}
@Override
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
Sat Mar 15 01:25:12 2014
@@ -171,7 +171,7 @@ public class SegmentNodeStore implements
@Override
public Blob createBlob(InputStream stream) throws IOException {
- return store.getWriter().writeStream(stream);
+ return store.getTracker().getWriter().writeStream(stream);
}
@Override
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
Sat Mar 15 01:25:12 2014
@@ -24,9 +24,7 @@ import org.apache.jackrabbit.oak.spi.blo
public interface SegmentStore {
- SegmentIdFactory getFactory();
-
- SegmentWriter getWriter();
+ SegmentTracker getTracker();
/**
* Returns the head state.
Copied:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
(from r1577651,
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java)
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java?p2=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java&p1=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java&r1=1577651&r2=1577772&rev=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactory.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
Sat Mar 15 01:25:12 2014
@@ -25,15 +25,15 @@ import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
- * Factory for creating the UUID objects used to identify segments.
- * Weak references are used to keep track of all currently referenced
- * UUIDs, so that we can avoid garbage-collecting those segments.
+ * Tracker of references to segment identifiers and segment instances
+ * that are currently kept in memory.
*/
-public class SegmentIdFactory {
+public class SegmentTracker {
private static final long MSB_MASK = ~(0xfL << 12);
@@ -45,6 +45,10 @@ public class SegmentIdFactory {
private static final long BULK = 0xBL << 60;
+ private static final int MB = 1024 * 1024;
+
+ private static final int DEFAULT_MEMORY_CACHE_SIZE = 256;
+
/**
* The random number source for generating new segment identifiers.
*/
@@ -62,12 +66,52 @@ public class SegmentIdFactory {
private final ArrayList<List<WeakReference<SegmentId>>> uuids =
newArrayList(
Collections.<List<WeakReference<SegmentId>>>nCopies(1024, null));
+ private final LinkedList<Segment> segments = newLinkedList();
+
private final SegmentStore store;
- public SegmentIdFactory(SegmentStore store) {
+ private final SegmentWriter writer;
+
+ private final long cacheSize;
+
+ private long currentSize = 0;
+
+ public SegmentTracker(SegmentStore store, int cacheSizeMB) {
this.store = store;
+ this.writer = new SegmentWriter(store, this);
+ this.cacheSize = cacheSizeMB * MB;
+ }
+
+ public SegmentTracker(SegmentStore store) {
+ this(store, DEFAULT_MEMORY_CACHE_SIZE);
+ }
+
+ public SegmentWriter getWriter() {
+ return writer;
}
+ public SegmentStore getStore() {
+ return store;
+ }
+
+ Segment getSegment(SegmentId id) {
+ Segment segment = store.readSegment(id);
+ id.setSegment(segment);
+
+ synchronized (this) {
+ segments.addFirst(segment);
+ currentSize += segment.getCacheSize();
+ while (currentSize > cacheSize && segments.size() > 1) {
+ Segment remove = segments.removeLast();
+ remove.getSegmentId().setSegment(null);
+ currentSize -= remove.getCacheSize();
+ }
+ }
+
+ return segment;
+ }
+
+
/**
* Returns all segment identifiers that are currently referenced in memory.
*
@@ -122,7 +166,7 @@ public class SegmentIdFactory {
}
}
- SegmentId id = new SegmentId(store, msb, lsb);
+ SegmentId id = new SegmentId(this, msb, lsb);
list.add(new WeakReference<SegmentId>(id));
if (list.size() > 5) {
Propchange:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
------------------------------------------------------------------------------
svn:eol-style = native
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=1577772&r1=1577771&r2=1577772&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
Sat Mar 15 01:25:12 2014
@@ -95,6 +95,8 @@ public class SegmentWriter {
return buffer;
}
+ private final SegmentTracker tracker;
+
private final SegmentStore store;
/**
@@ -136,9 +138,12 @@ public class SegmentWriter {
private Segment segment;
- public SegmentWriter(SegmentStore store) {
+ public SegmentWriter(SegmentStore store, SegmentTracker tracker) {
this.store = store;
- this.segment = new Segment(store, ByteBuffer.wrap(buffer));
+ this.tracker = tracker;
+ this.segment = new Segment(
+ tracker, tracker.newDataSegmentId(), ByteBuffer.wrap(buffer));
+ segment.getSegmentId().setSegment(segment);
}
public synchronized Segment getCurrentSegment(SegmentId id) {
@@ -178,12 +183,16 @@ public class SegmentWriter {
store.writeSegment(
segment.getSegmentId(),
buffer, buffer.length - length, length);
+ segment.getSegmentId().setSegment(null);
buffer = createNewBuffer();
roots.clear();
length = 0;
position = buffer.length;
- segment = new Segment(store, ByteBuffer.wrap(buffer));
+ segment = new Segment(
+ tracker, tracker.newDataSegmentId(),
+ ByteBuffer.wrap(buffer));
+ segment.getSegmentId().setSegment(segment);
}
}
@@ -640,7 +649,7 @@ public class SegmentWriter {
// write as many full bulk segments as possible
while (pos + MAX_SEGMENT_SIZE <= data.length) {
- SegmentId bulkId = store.getFactory().newBulkSegmentId();
+ SegmentId bulkId = store.getTracker().newBulkSegmentId();
store.writeSegment(bulkId, data, pos, MAX_SEGMENT_SIZE);
for (int i = 0; i < MAX_SEGMENT_SIZE; i += BLOCK_SIZE) {
blockIds.add(new RecordId(bulkId, i));
@@ -716,7 +725,7 @@ public class SegmentWriter {
// Write the data to bulk segments and collect the list of block ids
while (n != 0) {
- SegmentId bulkId = store.getFactory().newBulkSegmentId();
+ SegmentId bulkId = store.getTracker().newBulkSegmentId();
int len = align(n);
store.writeSegment(bulkId, data, 0, len);
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
Sat Mar 15 01:25:12 2014
@@ -38,10 +38,9 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.segment.RecordId;
import org.apache.jackrabbit.oak.plugins.segment.Segment;
import org.apache.jackrabbit.oak.plugins.segment.SegmentId;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentTracker;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentWriter;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -54,15 +53,11 @@ public class FileStore implements Segmen
private static final int MB = 1024 * 1024;
- private static final int DEFAULT_MEMORY_CACHE_SIZE = 256;
-
private static final String FILE_NAME_FORMAT = "%s%05d.tar";
private static final String JOURNAL_FILE_NAME = "journal.log";
- private final SegmentIdFactory factory = new SegmentIdFactory(this);
-
- private final SegmentWriter writer = new SegmentWriter(this);
+ private final SegmentTracker tracker;
private final File directory;
@@ -103,23 +98,29 @@ public class FileStore implements Segmen
public FileStore(BlobStore blobStore, File directory, int maxFileSizeMB,
boolean memoryMapping)
throws IOException {
- this(blobStore, directory, EMPTY_NODE, maxFileSizeMB,
DEFAULT_MEMORY_CACHE_SIZE, memoryMapping);
+ this(blobStore, directory, EMPTY_NODE, maxFileSizeMB, 0,
memoryMapping);
}
public FileStore(File directory, int maxFileSizeMB, boolean memoryMapping)
throws IOException {
- this(null, directory, EMPTY_NODE, maxFileSizeMB,
DEFAULT_MEMORY_CACHE_SIZE, memoryMapping);
+ this(null, directory, maxFileSizeMB, memoryMapping);
}
public FileStore(File directory, int maxFileSizeMB, int cacheSizeMB,
boolean memoryMapping) throws IOException {
- this(null,directory, EMPTY_NODE, maxFileSizeMB, cacheSizeMB,
memoryMapping);
+ this(null, directory, EMPTY_NODE, maxFileSizeMB, cacheSizeMB,
memoryMapping);
}
public FileStore(
- final BlobStore blobStore, final File directory, NodeState
initial, int maxFileSizeMB,
- int cacheSizeMB, boolean memoryMapping) throws IOException {
+ BlobStore blobStore, final File directory, NodeState initial,
+ int maxFileSizeMB, int cacheSizeMB, boolean memoryMapping)
+ throws IOException {
checkNotNull(directory).mkdirs();
+ if (cacheSizeMB > 0) {
+ this.tracker = new SegmentTracker(this, cacheSizeMB);
+ } else {
+ this.tracker = new SegmentTracker(this);
+ }
this.blobStore = blobStore;
this.directory = directory;
this.maxFileSize = maxFileSizeMB * MB;
@@ -153,7 +154,7 @@ public class FileStore implements Segmen
while (line != null) {
int space = line.indexOf(' ');
if (space != -1) {
- id = RecordId.fromString(factory, line.substring(0, space));
+ id = RecordId.fromString(tracker, line.substring(0, space));
}
line = journalFile.readLine();
}
@@ -164,8 +165,8 @@ public class FileStore implements Segmen
} else {
NodeBuilder builder = EMPTY_NODE.builder();
builder.setChildNode("root", initial);
- head = new AtomicReference<RecordId>(
-
getWriter().writeNode(builder.getNodeState()).getRecordId());
+ head = new AtomicReference<RecordId>(tracker.getWriter().writeNode(
+ builder.getNodeState()).getRecordId());
persistedHead = new AtomicReference<RecordId>(null);
}
@@ -201,7 +202,7 @@ public class FileStore implements Segmen
if (!after.equals(before)) {
// needs to happen outside the synchronization block below to
// avoid a deadlock with another thread flushing the writer
- getWriter().flush();
+ tracker.getWriter().flush();
synchronized (this) {
for (TarFile file : bulkFiles) {
@@ -222,14 +223,14 @@ public class FileStore implements Segmen
List<SegmentId> ids = newArrayList();
for (TarFile file : dataFiles) {
for (UUID uuid : file.getUUIDs()) {
- ids.add(factory.getSegmentId(
+ ids.add(tracker.getSegmentId(
uuid.getMostSignificantBits(),
uuid.getLeastSignificantBits()));
}
}
for (TarFile file : bulkFiles) {
for (UUID uuid : file.getUUIDs()) {
- ids.add(factory.getSegmentId(
+ ids.add(tracker.getSegmentId(
uuid.getMostSignificantBits(),
uuid.getLeastSignificantBits()));
}
@@ -238,13 +239,8 @@ public class FileStore implements Segmen
}
@Override
- public SegmentIdFactory getFactory() {
- return factory;
- }
-
- @Override
- public SegmentWriter getWriter() {
- return writer;
+ public SegmentTracker getTracker() {
+ return tracker;
}
@Override
@@ -295,7 +291,7 @@ public class FileStore implements Segmen
@Override
public boolean containsSegment(SegmentId id) {
- if (id.getStore() == this) {
+ if (id.getTracker() == tracker) {
return true;
} else if (id.isDataSegmentId()) {
return containsSegment(id, dataFiles);
@@ -308,13 +304,9 @@ public class FileStore implements Segmen
public Segment readSegment(SegmentId id) {
if (id.isBulkSegmentId()) {
return loadSegment(id, bulkFiles);
+ } else {
+ return loadSegment(id, dataFiles);
}
-
- Segment segment = getWriter().getCurrentSegment(id);
- if (segment == null) {
- segment = loadSegment(id, dataFiles);
- }
- return segment;
}
private boolean containsSegment(SegmentId id, List<TarFile> files) {
@@ -343,7 +335,7 @@ public class FileStore implements Segmen
try {
ByteBuffer buffer = file.readEntry(uuid);
if (buffer != null) {
- return new Segment(this, id, buffer);
+ return new Segment(tracker, id, buffer);
}
} catch (IOException e) {
throw new RuntimeException(
@@ -399,7 +391,7 @@ public class FileStore implements Segmen
@Override
public void gc() {
System.gc();
- Set<SegmentId> ids = factory.getReferencedSegmentIds();
+ Set<SegmentId> ids = tracker.getReferencedSegmentIds();
// TODO reclaim unreferenced segments
}
}
\ No newline at end of file
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/http/HttpStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/http/HttpStore.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/http/HttpStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/http/HttpStore.java
Sat Mar 15 01:25:12 2014
@@ -34,19 +34,16 @@ import org.apache.jackrabbit.oak.api.Blo
import org.apache.jackrabbit.oak.plugins.segment.RecordId;
import org.apache.jackrabbit.oak.plugins.segment.Segment;
import org.apache.jackrabbit.oak.plugins.segment.SegmentId;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentTracker;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentWriter;
import com.google.common.io.ByteStreams;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
public class HttpStore implements SegmentStore {
- private final SegmentIdFactory factory = new SegmentIdFactory(this);
-
- private final SegmentWriter writer = new SegmentWriter(this);
+ private final SegmentTracker tracker = new SegmentTracker(this);
private final URL base;
@@ -60,13 +57,8 @@ public class HttpStore implements Segmen
}
@Override
- public SegmentIdFactory getFactory() {
- return factory;
- }
-
- @Override
- public SegmentWriter getWriter() {
- return writer;
+ public SegmentTracker getTracker() {
+ return tracker;
}
@Override
@@ -78,7 +70,7 @@ public class HttpStore implements Segmen
BufferedReader reader = new BufferedReader(
new InputStreamReader(stream, UTF_8));
return new SegmentNodeState(
- RecordId.fromString(factory, reader.readLine()));
+ RecordId.fromString(tracker, reader.readLine()));
} finally {
stream.close();
}
@@ -99,31 +91,18 @@ public class HttpStore implements Segmen
@Override
public boolean containsSegment(SegmentId id) {
- return id.getStore() == this
- || loadSegment(id) != null;
+ return id.getTracker() == tracker || readSegment(id) != null;
}
@Override
public Segment readSegment(SegmentId id) {
- if (id.isBulkSegmentId()) {
- return loadSegment(id);
- }
-
- Segment segment = getWriter().getCurrentSegment(id);
- if (segment == null) {
- segment = loadSegment(id);
- }
- return segment;
- }
-
- private Segment loadSegment(SegmentId id) {
try {
URLConnection connection =
new URL(base, id.toString()).openConnection();
InputStream stream = connection.getInputStream();
try {
byte[] data = ByteStreams.toByteArray(stream);
- return new Segment(this, id, ByteBuffer.wrap(data));
+ return new Segment(tracker, id, ByteBuffer.wrap(data));
} finally {
stream.close();
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
Sat Mar 15 01:25:12 2014
@@ -26,7 +26,7 @@ import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.plugins.segment.Segment;
import org.apache.jackrabbit.oak.plugins.segment.SegmentId;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentTracker;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
import org.apache.jackrabbit.oak.plugins.segment.SegmentWriter;
@@ -38,9 +38,7 @@ import com.google.common.collect.Maps;
public class MemoryStore implements SegmentStore {
- private final SegmentIdFactory factory = new SegmentIdFactory(this);
-
- private final SegmentWriter writer = new SegmentWriter(this);
+ private final SegmentTracker tracker = new SegmentTracker(this);
private SegmentNodeState head;
@@ -51,7 +49,7 @@ public class MemoryStore implements Segm
NodeBuilder builder = EMPTY_NODE.builder();
builder.setChildNode("root", root);
- SegmentWriter writer = getWriter();
+ SegmentWriter writer = tracker.getWriter();
this.head = writer.writeNode(builder.getNodeState());
writer.flush();
}
@@ -61,13 +59,8 @@ public class MemoryStore implements Segm
}
@Override
- public SegmentIdFactory getFactory() {
- return factory;
- }
-
- @Override
- public SegmentWriter getWriter() {
- return writer;
+ public SegmentTracker getTracker() {
+ return tracker;
}
@Override
@@ -87,15 +80,12 @@ public class MemoryStore implements Segm
@Override
public boolean containsSegment(SegmentId id) {
- return id.getStore() == this;
+ return id.getTracker() == tracker || segments.containsKey(id);
}
@Override @Nonnull
public Segment readSegment(SegmentId id) {
- Segment segment = writer.getCurrentSegment(id);
- if (segment == null) {
- segment = segments.get(id);
- }
+ Segment segment = segments.get(id);
if (segment != null) {
return segment;
} else {
@@ -109,7 +99,7 @@ public class MemoryStore implements Segm
ByteBuffer buffer = ByteBuffer.allocate(length);
buffer.put(data, offset, length);
buffer.rewind();
- Segment segment = new Segment(this, id, buffer);
+ Segment segment = new Segment(tracker, id, buffer);
if (segments.putIfAbsent(id, segment) != null) {
throw new IllegalStateException("Segment override: " + id);
}
@@ -132,7 +122,7 @@ public class MemoryStore implements Segm
@Override
public void gc() {
System.gc();
- segments.keySet().retainAll(factory.getReferencedSegmentIds());
+ segments.keySet().retainAll(tracker.getReferencedSegmentIds());
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
Sat Mar 15 01:25:12 2014
@@ -38,7 +38,7 @@ public class CompareAgainstBaseStateTest
createControl().createMock("diff", NodeStateDiff.class);
private NodeBuilder builder =
- new MemoryStore().getWriter().writeNode(EMPTY_NODE).builder();
+ new
MemoryStore().getTracker().getWriter().writeNode(EMPTY_NODE).builder();
@Before
public void setUp() {
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/MapRecordTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/MapRecordTest.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/MapRecordTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/MapRecordTest.java
Sat Mar 15 01:25:12 2014
@@ -43,7 +43,7 @@ public class MapRecordTest {
createControl().createMock("diff", NodeStateDiff.class);
private NodeBuilder builder =
- new MemoryStore().getWriter().writeNode(EMPTY_NODE).builder();
+ new
MemoryStore().getTracker().getWriter().writeNode(EMPTY_NODE).builder();
@Test
public void testOak1104() {
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=1577772&r1=1577771&r2=1577772&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
Sat Mar 15 01:25:12 2014
@@ -54,7 +54,7 @@ public class RecordTest {
private SegmentStore store = new MemoryStore();
- private SegmentWriter writer = store.getWriter();
+ private SegmentWriter writer = store.getTracker().getWriter();
private final Random random = new Random(0xcafefaceL);
@@ -123,7 +123,7 @@ public class RecordTest {
@Test
public void testListWithLotsOfReferences() { // OAK-1184
- SegmentIdFactory factory = store.getFactory();
+ SegmentTracker factory = store.getTracker();
List<RecordId> list = newArrayList();
for (int i = 0; i < 1000; i++) {
list.add(new RecordId(factory.newBulkSegmentId(), 0));
@@ -181,7 +181,7 @@ public class RecordTest {
}
RecordId large = writer.writeString(builder.toString());
- Segment segment = store.readSegment(large.getSegmentId());
+ Segment segment = large.getSegmentId().getSegment();
assertEquals("", segment.readString(empty));
assertEquals(" ", segment.readString(space));
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentIdFactoryTest.java
Sat Mar 15 01:25:12 2014
@@ -27,7 +27,7 @@ import org.junit.Test;
public class SegmentIdFactoryTest {
- private final SegmentIdFactory factory = new MemoryStore().getFactory();
+ private final SegmentTracker factory = new MemoryStore().getTracker();
@Test
public void segmentIdType() {
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
Sat Mar 15 01:25:12 2014
@@ -146,7 +146,7 @@ public class SegmentSizeTest {
@Test
public void testFlatNodeUpdate() {
SegmentStore store = new MemoryStore();
- SegmentWriter writer = store.getWriter();
+ SegmentWriter writer = store.getTracker().getWriter();
NodeBuilder builder = EMPTY_NODE.builder();
for (int i = 0; i < 1000; i++) {
@@ -170,7 +170,7 @@ public class SegmentSizeTest {
private int getSize(NodeBuilder builder) {
SegmentStore store = new MemoryStore();
- SegmentWriter writer = store.getWriter();
+ SegmentWriter writer = store.getTracker().getWriter();
RecordId id = writer.writeNode(builder.getNodeState()).getRecordId();
writer.flush();
Segment segment = store.readSegment(id.getSegmentId());
@@ -179,7 +179,7 @@ public class SegmentSizeTest {
private int getAmortizedSize(NodeBuilder builder) {
SegmentStore store = new MemoryStore();
- SegmentWriter writer = store.getWriter();
+ SegmentWriter writer = store.getTracker().getWriter();
NodeState state = builder.getNodeState();
RecordId id = writer.writeNode(state).getRecordId();
writer.flush();
@@ -187,7 +187,7 @@ public class SegmentSizeTest {
int base = segment.size();
store = new MemoryStore(); // avoid cross-segment caching
- writer = store.getWriter();
+ writer = store.getTracker().getWriter();
writer.writeNode(state);
id = writer.writeNode(state).getRecordId();
writer.flush();
Modified:
jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java
(original)
+++
jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java
Sat Mar 15 01:25:12 2014
@@ -40,7 +40,7 @@ public abstract class SegmentServlet ext
private SegmentId getSegmentId(String info) {
try {
UUID uuid = UUID.fromString(info);
- return getSegmentStore().getFactory().getSegmentId(
+ return getSegmentStore().getTracker().getSegmentId(
uuid.getMostSignificantBits(),
uuid.getLeastSignificantBits());
} catch (IllegalArgumentException e) {
@@ -51,7 +51,7 @@ public abstract class SegmentServlet ext
private RecordId getRecordId(BufferedReader reader) throws IOException {
try {
return RecordId.fromString(
- getSegmentStore().getFactory(), reader.readLine());
+ getSegmentStore().getTracker(), reader.readLine());
} catch (IllegalArgumentException e) {
return null;
}
Modified:
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java?rev=1577772&r1=1577771&r2=1577772&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
(original)
+++
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
Sat Mar 15 01:25:12 2014
@@ -214,7 +214,7 @@ public class Main {
} else {
for (int i = 1; i < args.length; i++) {
UUID uuid = UUID.fromString(args[i]);
- SegmentId id = store.getFactory().getSegmentId(
+ SegmentId id = store.getTracker().getSegmentId(
uuid.getMostSignificantBits(),
uuid.getLeastSignificantBits());
System.out.println(id.getSegment());