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 md...@apache.org on 2016/05/23 12:59:23 UTC
svn commit: r1745182 [1/3] - in /jackrabbit/oak/trunk:
oak-run/src/main/java/org/apache/jackrabbit/oak/run/
oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/
oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/
oak-segme...
Author: mduerig
Date: Mon May 23 12:59:22 2016
New Revision: 1745182
URL: http://svn.apache.org/viewvc?rev=1745182&view=rev
Log:
OAK-4373: Refactor SegmentTracker
- Put SegmentTracker back to its original purpose: tracking and creating segment ids.
- Introduce a SegmentReader class for reading from segments as a dual to SegmentWriter and move the strings cache there
- Add (temporarily) getters for SegmentReader and SegmentWriter to the SegmentStore interface
- Make the segment cache an implementation detail of the FileStore
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java
- copied, changed from r1745165, jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FileStoreTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java
Modified:
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapEntry.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapRecord.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Record.java
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/RecordUsageAnalyser.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/SegmentBufferWriter.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterPool.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentGraph.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentIdTable.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.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/SegmentNodeStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentParser.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentPropertyState.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStore.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/SegmentTracker.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Template.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/http/HttpStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/memory/MemoryStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CompactionAndCleanupIT.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CompareAgainstBaseStateTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MapRecordTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/RecordTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/RecordUsageAnalyserTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCompactionIT.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentGraphTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentIdFactoryTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentIdTableBenchmark.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentIdTableTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentParserTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentSizeTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/TemplateTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/TestUtils.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ExternalBlobReferenceTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FileStoreIT.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FileStoreTest.java
Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentTarUtils.java Mon May 23 12:59:22 2016
@@ -84,13 +84,13 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
-class SegmentTarUtils {
+final class SegmentTarUtils {
private static final boolean TAR_STORAGE_MEMORY_MAPPED = Boolean.getBoolean("tar.memoryMapped");
private static final int TAR_SEGMENT_CACHE_SIZE = Integer.getInteger("cache", 256);
- private final static int MAX_CHAR_DISPLAY = Integer.getInteger("max.char.display", 60);
+ private static final int MAX_CHAR_DISPLAY = Integer.getInteger("max.char.display", 60);
private SegmentTarUtils() {
// Prevent instantiation
@@ -217,7 +217,7 @@ class SegmentTarUtils {
long bulkSize = 0;
((Logger) getLogger(SegmentTracker.class)).setLevel(Level.OFF);
- RecordUsageAnalyser analyser = new RecordUsageAnalyser();
+ RecordUsageAnalyser analyser = new RecordUsageAnalyser(store);
for (SegmentId id : store.getSegmentIds()) {
if (id.isDataSegmentId()) {
@@ -433,7 +433,7 @@ class SegmentTarUtils {
}
if (id2 == null) {
- NodeState node = new SegmentNodeState(id1);
+ NodeState node = new SegmentNodeState(store, id1);
System.out.println("/ (" + id1 + ") -> " + node);
for (String name : PathUtils.elements(path)) {
node = node.getChildNode(name);
@@ -445,8 +445,8 @@ class SegmentTarUtils {
+ node);
}
} else {
- NodeState node1 = new SegmentNodeState(id1);
- NodeState node2 = new SegmentNodeState(id2);
+ NodeState node1 = new SegmentNodeState(store, id1);
+ NodeState node2 = new SegmentNodeState(store, id2);
for (String name : PathUtils.elements(path)) {
node1 = node1.getChildNode(name);
node2 = node2.getChildNode(name);
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapEntry.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapEntry.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapEntry.java Mon May 23 12:59:22 2016
@@ -24,11 +24,12 @@ import static org.apache.jackrabbit.oak.
import java.util.Map;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
-
-import org.apache.jackrabbit.oak.spi.state.AbstractChildNodeEntry;
+import javax.annotation.Nullable;
import com.google.common.collect.ComparisonChain;
+import org.apache.jackrabbit.oak.spi.state.AbstractChildNodeEntry;
/**
* Representation of a single key-value entry in a map.
@@ -36,13 +37,21 @@ import com.google.common.collect.Compari
class MapEntry extends AbstractChildNodeEntry
implements Map.Entry<RecordId, RecordId>, Comparable<MapEntry> {
+ @Nonnull
+ private final SegmentStore store;
+
+ @Nonnull
private final String name;
+ @Nonnull
private final RecordId key;
+ @CheckForNull
private final RecordId value;
- MapEntry(String name, RecordId key, RecordId value) {
+ MapEntry(@Nonnull SegmentStore store, @Nonnull String name,
+ @Nonnull RecordId key, @Nullable RecordId value) {
+ this.store = checkNotNull(store);
this.name = checkNotNull(name);
this.key = checkNotNull(key);
this.value = value;
@@ -62,16 +71,18 @@ class MapEntry extends AbstractChildNode
@Override @Nonnull
public SegmentNodeState getNodeState() {
checkState(value != null);
- return new SegmentNodeState(value);
+ return new SegmentNodeState(store, value);
}
//---------------------------------------------------------< Map.Entry >--
+ @Nonnull
@Override
public RecordId getKey() {
return key;
}
+ @CheckForNull
@Override
public RecordId getValue() {
return value;
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapRecord.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapRecord.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapRecord.java Mon May 23 12:59:22 2016
@@ -30,6 +30,8 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.Nonnull;
+
import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
@@ -51,6 +53,9 @@ public class MapRecord extends Record {
private static final int A = 0xB;
static final long HASH_MASK = 0xFFFFFFFFL;
+ @Nonnull
+ private final SegmentStore store;
+
/**
* Generates a hash code for the value, using a random number generator
* to improve the distribution of the hash values.
@@ -93,8 +98,9 @@ public class MapRecord extends Record {
*/
protected static final int MAX_SIZE = (1 << SIZE_BITS) - 1; // ~268e6
- protected MapRecord(RecordId id) {
+ protected MapRecord(@Nonnull SegmentStore store, @Nonnull RecordId id) {
super(id);
+ this.store = checkNotNull(store);
}
boolean isLeaf() {
@@ -102,7 +108,7 @@ public class MapRecord extends Record {
int head = segment.readInt(getOffset(0));
if (isDiff(head)) {
RecordId base = segment.readRecordId(getOffset(8, 2));
- return new MapRecord(base).isLeaf();
+ return new MapRecord(store, base).isLeaf();
}
return !isBranch(head);
}
@@ -118,8 +124,7 @@ public class MapRecord extends Record {
int ids = 0;
for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
if ((bitmap & (1 << i)) != 0) {
- buckets[i] = new MapRecord(
- segment.readRecordId(getOffset(8, ids++)));
+ buckets[i] = new MapRecord(store, segment.readRecordId(getOffset(8, ids++)));
} else {
buckets[i] = null;
}
@@ -134,7 +139,7 @@ public class MapRecord extends Record {
for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
if ((bitmap & (1 << i)) != 0) {
RecordId id = segment.readRecordId(getOffset(8, ids++));
- buckets.add(new MapRecord(id));
+ buckets.add(new MapRecord(store, id));
}
}
return buckets;
@@ -145,7 +150,7 @@ public class MapRecord extends Record {
int head = segment.readInt(getOffset(0));
if (isDiff(head)) {
RecordId base = segment.readRecordId(getOffset(8, 2));
- return new MapRecord(base).size();
+ return new MapRecord(store, base).size();
}
return getSize(head);
}
@@ -159,13 +164,13 @@ public class MapRecord extends Record {
if (isDiff(head)) {
if (hash == segment.readInt(getOffset(4))) {
RecordId key = segment.readRecordId(getOffset(8));
- if (name.equals(Segment.readString(key))) {
+ if (name.equals(store.getReader().readString(key))) {
RecordId value = segment.readRecordId(getOffset(8, 1));
- return new MapEntry(name, key, value);
+ return new MapEntry(store, name, key, value);
}
}
RecordId base = segment.readRecordId(getOffset(8, 2));
- return new MapRecord(base).getEntry(name);
+ return new MapRecord(store, base).getEntry(name);
}
int size = getSize(head);
@@ -185,7 +190,7 @@ public class MapRecord extends Record {
if ((bitmap & bit) != 0) {
int ids = bitCount(bitmap & (bit - 1));
RecordId id = segment.readRecordId(getOffset(8, ids));
- return new MapRecord(id).getEntry(name);
+ return new MapRecord(store, id).getEntry(name);
} else {
return null;
}
@@ -214,9 +219,9 @@ public class MapRecord extends Record {
getOffset(4 + size * 4, i * 2));
RecordId valueId = segment.readRecordId(
getOffset(4 + size * 4, i * 2 + 1));
- diff = Segment.readString(keyId).compareTo(name);
+ diff = store.getReader().readString(keyId).compareTo(name);
if (diff == 0) {
- return new MapEntry(name, keyId, valueId);
+ return new MapEntry(store, name, keyId, valueId);
}
}
@@ -242,7 +247,7 @@ public class MapRecord extends Record {
return segment.readRecordId(getOffset(8, 1));
}
RecordId base = segment.readRecordId(getOffset(8, 2));
- return new MapRecord(base).getValue(hash, key);
+ return new MapRecord(store, base).getValue(hash, key);
}
int size = getSize(head);
@@ -262,7 +267,7 @@ public class MapRecord extends Record {
if ((bitmap & bit) != 0) {
int ids = bitCount(bitmap & (bit - 1));
RecordId id = segment.readRecordId(getOffset(8, ids));
- return new MapRecord(id).getValue(hash, key);
+ return new MapRecord(store, id).getValue(hash, key);
} else {
return null;
}
@@ -292,7 +297,7 @@ public class MapRecord extends Record {
int head = segment.readInt(getOffset(0));
if (isDiff(head)) {
RecordId base = segment.readRecordId(getOffset(8, 2));
- return new MapRecord(base).getKeys();
+ return new MapRecord(store, base).getKeys();
}
int size = getSize(head);
@@ -318,7 +323,7 @@ public class MapRecord extends Record {
String[] keys = new String[size];
for (int i = 0; i < size; i++) {
- keys[i] = Segment.readString(ids[i]);
+ keys[i] = store.getReader().readString(ids[i]);
}
return Arrays.asList(keys);
}
@@ -336,7 +341,7 @@ public class MapRecord extends Record {
RecordId key = segment.readRecordId(getOffset(8));
RecordId value = segment.readRecordId(getOffset(8, 1));
RecordId base = segment.readRecordId(getOffset(8, 2));
- return new MapRecord(base).getEntries(key, value);
+ return new MapRecord(store, base).getEntries(key, value);
}
int size = getSize(head);
@@ -369,8 +374,8 @@ public class MapRecord extends Record {
} else {
value = segment.readRecordId(getOffset(4 + size * 4, i * 2 + 1));
}
- String name = Segment.readString(key);
- entries[i] = new MapEntry(name, key, value);
+ String name = store.getReader().readString(key);
+ entries[i] = new MapEntry(store, name, key, value);
}
return Arrays.asList(entries);
}
@@ -385,9 +390,9 @@ public class MapRecord extends Record {
if (isDiff(head)) {
int hash = segment.readInt(getOffset(4));
RecordId keyId = segment.readRecordId(getOffset(8));
- final String key = Segment.readString(keyId);
+ final String key = store.getReader().readString(keyId);
final RecordId value = segment.readRecordId(getOffset(8, 1));
- MapRecord base = new MapRecord(segment.readRecordId(getOffset(8, 2)));
+ MapRecord base = new MapRecord(store, segment.readRecordId(getOffset(8, 2)));
boolean rv = base.compare(before, new DefaultNodeStateDiff() {
@Override
@@ -411,12 +416,12 @@ public class MapRecord extends Record {
if (beforeEntry == null) {
rv = diff.childNodeAdded(
key,
- new SegmentNodeState(value));
+ new SegmentNodeState(store, value));
} else if (!value.equals(beforeEntry.getValue())) {
rv = diff.childNodeChanged(
key,
beforeEntry.getNodeState(),
- new SegmentNodeState(value));
+ new SegmentNodeState(store, value));
}
}
return rv;
@@ -427,9 +432,9 @@ public class MapRecord extends Record {
if (isDiff(beforeHead)) {
int hash = beforeSegment.readInt(before.getOffset(4));
RecordId keyId = beforeSegment.readRecordId(before.getOffset(8));
- final String key = Segment.readString(keyId);
+ final String key = store.getReader().readString(keyId);
final RecordId value = beforeSegment.readRecordId(before.getOffset(8, 1));
- MapRecord base = new MapRecord(beforeSegment.readRecordId(before.getOffset(8, 2)));
+ MapRecord base = new MapRecord(store, beforeSegment.readRecordId(before.getOffset(8, 2)));
boolean rv = this.compare(base, new DefaultNodeStateDiff() {
@Override
@@ -453,11 +458,11 @@ public class MapRecord extends Record {
if (afterEntry == null) {
rv = diff.childNodeDeleted(
key,
- new SegmentNodeState(value));
+ new SegmentNodeState(store, value));
} else if (!value.equals(afterEntry.getValue())) {
rv = diff.childNodeChanged(
key,
- new SegmentNodeState(value),
+ new SegmentNodeState(store, value),
afterEntry.getNodeState());
}
}
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Record.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Record.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Record.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Record.java Mon May 23 12:59:22 2016
@@ -62,15 +62,6 @@ class Record {
}
/**
- * Returns the tracker of the segment that contains this record.
- *
- * @return segment tracker
- */
- protected SegmentTracker getTracker() {
- return segmentId.getTracker();
- }
-
- /**
* Returns the segment that contains this record.
*
* @return segment that contains this record
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=1745182&r1=1745181&r2=1745182&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 Mon May 23 12:59:22 2016
@@ -89,6 +89,7 @@ public final class RecordId implements C
return segmentId.asUUID();
}
+ @Nonnull
public Segment getSegment() {
return segmentId.getSegment();
}
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordUsageAnalyser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordUsageAnalyser.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordUsageAnalyser.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordUsageAnalyser.java Mon May 23 12:59:22 2016
@@ -25,6 +25,8 @@ import static org.apache.commons.io.File
import java.util.Formatter;
import java.util.Set;
+import javax.annotation.Nonnull;
+
/**
* This utility breaks down space usage per record type.
* It accounts for value sharing. That is, an instance
@@ -56,6 +58,10 @@ public class RecordUsageAnalyser extends
private long templateCount;
private long nodeCount;
+ public RecordUsageAnalyser(@Nonnull SegmentStore store) {
+ super(store);
+ }
+
/**
* @return number of bytes in {@link RecordType#LEAF leaf} and {@link RecordType#BRANCH branch}
* records.
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=1745182&r1=1745181&r2=1745182&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 Mon May 23 12:59:22 2016
@@ -26,28 +26,25 @@ import static com.google.common.collect.
import static com.google.common.collect.Maps.newConcurrentMap;
import static java.lang.Boolean.getBoolean;
import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
+import static org.apache.jackrabbit.oak.segment.SegmentBlob.readBlobId;
import static org.apache.jackrabbit.oak.segment.SegmentId.isDataSegmentId;
import static org.apache.jackrabbit.oak.segment.SegmentVersion.LATEST_VERSION;
import static org.apache.jackrabbit.oak.segment.SegmentVersion.isValid;
import static org.apache.jackrabbit.oak.segment.SegmentWriter.BLOCK_SIZE;
import java.io.IOException;
-import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
+import javax.annotation.Nonnull;
import com.google.common.base.Charsets;
-import com.google.common.base.Function;
import org.apache.commons.io.HexDump;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.jackrabbit.oak.api.PropertyState;
@@ -127,7 +124,7 @@ public class Segment {
public static final int GC_GENERATION_OFFSET = 10;
- private final SegmentTracker tracker;
+ private final SegmentStore store;
private final SegmentId id;
@@ -144,24 +141,12 @@ public class Segment {
*/
private final SegmentId[] refids;
- private final Function<Integer, String> loadString = new Function<Integer, String>() {
- @Nullable
- @Override
- public String apply(Integer offset) {
- return loadString(offset);
- }
- };
-
- /**
- * Cache for string records
- */
- private final StringCache stringCache;
-
/**
* Template records read from segment. Used to avoid duplicate
* copies and repeated parsing of the same templates.
+ * FIXME OAK-4373 move the template cache to the segment reader along side with the string cache
*/
- private final ConcurrentMap<Integer, Template> templates;
+ final ConcurrentMap<Integer, Template> templates;
private static final boolean DISABLE_TEMPLATE_CACHE = getBoolean("oak.segment.disableTemplateCache");
@@ -195,11 +180,12 @@ public class Segment {
return (address + boundary - 1) & ~(boundary - 1);
}
- public Segment(SegmentTracker tracker, final SegmentId id, final ByteBuffer data) {
- this.tracker = checkNotNull(tracker);
+ public Segment(@Nonnull SegmentStore store,
+ @Nonnull final SegmentId id,
+ @Nonnull final ByteBuffer data) {
+ this.store = checkNotNull(store);
this.id = checkNotNull(id);
- stringCache = tracker.getStringCache();
if (DISABLE_TEMPLATE_CACHE) {
templates = null;
} else {
@@ -240,11 +226,10 @@ public class Segment {
}
}
- Segment(SegmentTracker tracker, byte[] buffer, String info) {
- this.tracker = checkNotNull(tracker);
- this.id = tracker.newDataSegmentId();
- this.info = info;
- stringCache = tracker.getStringCache();
+ Segment(@Nonnull SegmentStore store, @Nonnull byte[] buffer, @Nonnull String info) {
+ this.store = checkNotNull(store);
+ this.id = store.getTracker().newDataSegmentId();
+ this.info = checkNotNull(info);
if (DISABLE_TEMPLATE_CACHE) {
templates = null;
} else {
@@ -255,7 +240,7 @@ public class Segment {
this.refids = new SegmentId[SEGMENT_REFERENCE_LIMIT + 1];
this.refids[0] = id;
this.version = SegmentVersion.fromByte(buffer[3]);
- this.id.setSegment(this);
+ id.loaded(this);
}
SegmentVersion getSegmentVersion() {
@@ -370,7 +355,7 @@ public class Segment {
int refpos = data.position() + index * 16;
long msb = data.getLong(refpos);
long lsb = data.getLong(refpos + 8);
- refid = tracker.getSegmentId(msb, lsb);
+ refid = store.getTracker().getSegmentId(msb, lsb);
refids[index] = refid;
}
}
@@ -391,31 +376,6 @@ public class Segment {
return data.remaining();
}
- public long getCacheSize() {
- int size = 1024;
- if (!data.isDirect()) {
- size += size();
- }
- if (id.isDataSegmentId()) {
- size += size();
- }
- return size;
- }
-
- /**
- * Writes this segment to the given output stream.
- *
- * @param stream stream to which this segment will be written
- * @throws IOException on an IO error
- */
- public void writeTo(OutputStream stream) throws IOException {
- ByteBuffer buffer = data.duplicate();
- WritableByteChannel channel = Channels.newChannel(stream);
- while (buffer.hasRemaining()) {
- channel.write(buffer);
- }
- }
-
public void collectBlobReferences(ReferenceCollector collector) {
int refcount = getRefCount();
int rootcount =
@@ -425,9 +385,8 @@ public class Segment {
int blobrefpos = data.position() + refcount * 16 + rootcount * 3;
for (int i = 0; i < blobrefcount; i++) {
- int offset = (data.getShort(blobrefpos + i * 2) & 0xffff) << 2;
- SegmentBlob blob = new SegmentBlob(new RecordId(id, offset));
- collector.addReference(blob.getBlobId(), null);
+ int offset = (data.getShort(blobrefpos + i * 2) & 0xffff) << RECORD_ALIGN_BITS;
+ collector.addReference(readBlobId(store, this, offset), null);
}
}
@@ -475,31 +434,8 @@ public class Segment {
return new RecordId(refid, offset << RECORD_ALIGN_BITS);
}
- static String readString(final RecordId id) {
- final SegmentId segmentId = id.getSegmentId();
- StringCache cache = segmentId.getTracker().getStringCache();
- if (cache == null) {
- return segmentId.getSegment().readString(id.getOffset());
- } else {
- long msb = segmentId.getMostSignificantBits();
- long lsb = segmentId.getLeastSignificantBits();
- return cache.getString(msb, lsb, id.getOffset(), new Function<Integer, String>() {
- @Nullable
- @Override
- public String apply(Integer offset) {
- return segmentId.getSegment().loadString(offset);
- }
- });
- }
- }
-
- private String readString(int offset) {
- long msb = id.getMostSignificantBits();
- long lsb = id.getLeastSignificantBits();
- return stringCache.getString(msb, lsb, offset, loadString);
- }
-
- private String loadString(int offset) {
+ @Nonnull
+ public String readString(int offset) {
int pos = pos(offset, 1);
long length = internalReadLength(pos);
if (length < SMALL_LIMIT) {
@@ -530,27 +466,8 @@ public class Segment {
}
}
- MapRecord readMap(RecordId id) {
- return new MapRecord(id);
- }
-
- Template readTemplate(final RecordId id) {
- return id.getSegment().readTemplate(id.getOffset());
- }
-
- private Template readTemplate(int offset) {
- if (templates == null) {
- return loadTemplate(offset);
- }
- Template template = templates.get(offset);
- if (template == null) {
- template = loadTemplate(offset);
- templates.putIfAbsent(offset, template); // only keep the first copy
- }
- return template;
- }
-
- private Template loadTemplate(int offset) {
+ @Nonnull
+ Template readTemplate(int offset) {
int head = readInt(offset);
boolean hasPrimaryType = (head & (1 << 31)) != 0;
boolean hasMixinTypes = (head & (1 << 30)) != 0;
@@ -564,7 +481,7 @@ public class Segment {
if (hasPrimaryType) {
RecordId primaryId = readRecordId(offset);
primaryType = PropertyStates.createProperty(
- "jcr:primaryType", readString(primaryId), Type.NAME);
+ "jcr:primaryType", store.getReader().readString(primaryId), Type.NAME);
offset += RECORD_ID_BYTES;
}
@@ -573,7 +490,7 @@ public class Segment {
String[] mixins = new String[mixinCount];
for (int i = 0; i < mixins.length; i++) {
RecordId mixinId = readRecordId(offset);
- mixins[i] = readString(mixinId);
+ mixins[i] = store.getReader().readString(mixinId);
offset += RECORD_ID_BYTES;
}
mixinTypes = PropertyStates.createProperty(
@@ -585,13 +502,13 @@ public class Segment {
childName = Template.MANY_CHILD_NODES;
} else if (!zeroChildNodes) {
RecordId childNameId = readRecordId(offset);
- childName = readString(childNameId);
+ childName = store.getReader().readString(childNameId);
offset += RECORD_ID_BYTES;
}
PropertyTemplate[] properties;
properties = readProps(propertyCount, offset);
- return new Template(primaryType, mixinTypes, properties, childName);
+ return new Template(store, primaryType, mixinTypes, properties, childName);
}
private PropertyTemplate[] readProps(int propertyCount, int offset) {
@@ -603,7 +520,7 @@ public class Segment {
for (int i = 0; i < propertyCount; i++) {
byte type = readByte(offset++);
properties[i] = new PropertyTemplate(i,
- readString(propertyNames.getEntry(i)), Type.fromTag(
+ store.getReader().readString(propertyNames.getEntry(i)), Type.fromTag(
Math.abs(type), type < 0));
}
}
@@ -671,11 +588,9 @@ public class Segment {
pos += rootcount * 3;
for (int blobrefid = 0; blobrefid < blobrefcount; blobrefid++) {
int offset = data.getShort(pos + blobrefid * 2) & 0xffff;
- SegmentBlob blob = new SegmentBlob(
- new RecordId(id, offset << RECORD_ALIGN_BITS));
writer.format(
"blobref %d: %s at %04x%n", blobrefid,
- blob.getBlobId(), offset);
+ readBlobId(store, this, offset << RECORD_ALIGN_BITS), offset);
}
}
writer.println("--------------------------------------------------------------------------");
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=1745182&r1=1745181&r2=1745182&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 Mon May 23 12:59:22 2016
@@ -19,6 +19,7 @@
package org.apache.jackrabbit.oak.segment;
import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Collections.emptySet;
import static org.apache.jackrabbit.oak.segment.Segment.MEDIUM_LIMIT;
@@ -41,6 +42,9 @@ import org.apache.jackrabbit.oak.spi.blo
*/
public class SegmentBlob extends Record implements Blob {
+ @Nonnull
+ private final SegmentStore store;
+
public static Iterable<SegmentId> getBulkSegmentIds(Blob blob) {
if (blob instanceof SegmentBlob) {
return ((SegmentBlob) blob).getBulkSegmentIds();
@@ -49,8 +53,9 @@ public class SegmentBlob extends Record
}
}
- SegmentBlob(RecordId id) {
+ SegmentBlob(@Nonnull SegmentStore store, @Nonnull RecordId id) {
super(id);
+ this.store = checkNotNull(store);
}
private InputStream getInlineStream(
@@ -84,7 +89,7 @@ public class SegmentBlob extends Record
return getNewStream(readShortBlobId(segment, offset, head));
} else if ((head & 0xf8) == 0xf0) {
// 1111 0xxx: external value, long blob ID
- return getNewStream(readLongBlobId(segment, offset));
+ return getNewStream(readLongBlobId(store, segment, offset));
} else {
throw new IllegalStateException(String.format(
"Unexpected value record type: %02x", head & 0xff));
@@ -110,7 +115,7 @@ public class SegmentBlob extends Record
return getLength(readShortBlobId(segment, offset, head));
} else if ((head & 0xf8) == 0xf0) {
// 1111 0xxx: external value, long blob ID
- return getLength(readLongBlobId(segment, offset));
+ return getLength(readLongBlobId(store, segment, offset));
} else {
throw new IllegalStateException(String.format(
"Unexpected value record type: %02x", head & 0xff));
@@ -122,8 +127,7 @@ public class SegmentBlob extends Record
public String getReference() {
String blobId = getBlobId();
if (blobId != null) {
- BlobStore blobStore = getSegment().getSegmentId().getTracker().
- getStore().getBlobStore();
+ BlobStore blobStore = store.getBlobStore();
if (blobStore != null) {
return blobStore.getReference(blobId);
} else {
@@ -152,16 +156,20 @@ public class SegmentBlob extends Record
return (head & 0xf0) == 0xe0 || (head & 0xf8) == 0xf0;
}
+ @CheckForNull
public String getBlobId() {
- Segment segment = getSegment();
- int offset = getOffset();
+ return readBlobId(store, getSegment(), getOffset());
+ }
+
+ @CheckForNull
+ static String readBlobId(@Nonnull SegmentStore store, @Nonnull Segment segment, int offset) {
byte head = segment.readByte(offset);
if ((head & 0xf0) == 0xe0) {
// 1110 xxxx: external value, small blob ID
return readShortBlobId(segment, offset, head);
} else if ((head & 0xf8) == 0xf0) {
// 1111 0xxx: external value, long blob ID
- return readLongBlobId(segment, offset);
+ return readLongBlobId(store, segment, offset);
} else {
return null;
}
@@ -204,9 +212,9 @@ public class SegmentBlob extends Record
return new String(bytes, UTF_8);
}
- private static String readLongBlobId(Segment segment, int offset) {
+ private static String readLongBlobId(SegmentStore store, Segment segment, int offset) {
RecordId blobIdRecordId = segment.readRecordId(offset + 1);
- return Segment.readString(blobIdRecordId);
+ return store.getReader().readString(blobIdRecordId);
}
private List<RecordId> getBulkRecordIds() {
@@ -239,7 +247,7 @@ public class SegmentBlob extends Record
}
private Blob getBlob(String blobId) {
- return getSegment().getSegmentId().getTracker().getStore().readBlob(blobId);
+ return store.readBlob(blobId);
}
private InputStream getNewStream(String blobId) {
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriter.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriter.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriter.java Mon May 23 12:59:22 2016
@@ -88,8 +88,6 @@ public class SegmentBufferWriter impleme
*/
private final String wid;
- private final SegmentTracker tracker;
-
private final int generation;
/**
@@ -119,15 +117,10 @@ public class SegmentBufferWriter impleme
? "w-" + identityHashCode(this)
: wid);
- this.tracker = store.getTracker();
this.generation = generation;
newSegment();
}
- public SegmentBufferWriter(SegmentStore store, SegmentVersion version, String wid) {
- this(store, version, wid, store.getTracker().getGcGeneration());
- }
-
@Override
public RecordId execute(WriteOperation writeOperation) throws IOException {
return writeOperation.execute(this);
@@ -169,10 +162,10 @@ public class SegmentBufferWriter impleme
String metaInfo =
"{\"wid\":\"" + wid + '"' +
- ",\"sno\":" + tracker.getSegmentCount() +
+ ",\"sno\":" + store.getTracker().getSegmentCount() +
",\"t\":" + currentTimeMillis() + "}";
try {
- segment = new Segment(tracker, buffer, metaInfo);
+ segment = new Segment(store, buffer, metaInfo);
byte[] data = metaInfo.getBytes(UTF_8);
RecordWriters.newValueWriter(data.length, data).write(this);
} catch (IOException e) {
@@ -328,25 +321,8 @@ public class SegmentBufferWriter impleme
}
SegmentId segmentId = segment.getSegmentId();
- int segmentOffset = buffer.length - length;
-
LOG.debug("Writing data segment {} ({} bytes)", segmentId, length);
- store.writeSegment(segmentId, buffer, segmentOffset, length);
-
- // Keep this segment in memory as it's likely to be accessed soon
- ByteBuffer data;
- if (segmentOffset > 4096) {
- data = ByteBuffer.allocate(length);
- data.put(buffer, segmentOffset, length);
- data.rewind();
- } else {
- data = ByteBuffer.wrap(buffer, segmentOffset, length);
- }
-
- // It is important to put the segment into the cache only *after* it has been
- // written to the store since as soon as it is in the cache it becomes eligible
- // for eviction, which might lead to SNFEs when it is not yet in the store at that point.
- tracker.setSegment(segmentId, new Segment(tracker, segmentId, data));
+ store.writeSegment(segmentId, buffer, buffer.length - length, length);
newSegment();
}
}
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterPool.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterPool.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterPool.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterPool.java Mon May 23 12:59:22 2016
@@ -19,6 +19,7 @@
package org.apache.jackrabbit.oak.segment;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
@@ -30,26 +31,52 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+
/**
* This {@link WriteOperationHandler} uses a pool of {@link SegmentBufferWriter}s,
* which it passes to its {@link #execute(WriteOperation) execute} method.
*/
-class SegmentBufferWriterPool implements WriteOperationHandler {
+public class SegmentBufferWriterPool implements WriteOperationHandler {
private final Map<Object, SegmentBufferWriter> writers = newHashMap();
private final Set<SegmentBufferWriter> borrowed = newHashSet();
private final Set<SegmentBufferWriter> disposed = newHashSet();
+
+ @Nonnull
private final SegmentStore store;
+
+ @Nonnull
+ private final Supplier<Integer> gcGeneration;
+
+ @Nonnull
private final SegmentVersion version;
+
+ @Nonnull
private final String wid;
private short writerId = -1;
- SegmentBufferWriterPool(SegmentStore store, SegmentVersion version, String wid) {
- this.store = store;
- this.version = version;
- this.wid = wid;
+ public SegmentBufferWriterPool(
+ @Nonnull SegmentStore store,
+ @Nonnull SegmentVersion version,
+ @Nonnull String wid,
+ @Nonnull Supplier<Integer> gcGeneration) {
+ this.store = checkNotNull(store);
+ this.version = checkNotNull(version);
+ this.wid = checkNotNull(wid);
+ this.gcGeneration = checkNotNull(gcGeneration);
}
+ public SegmentBufferWriterPool(
+ @Nonnull SegmentStore store,
+ @Nonnull SegmentVersion version,
+ @Nonnull String wid) {
+ this(store, version, wid, Suppliers.ofInstance(0));
+ }
+
@Override
public RecordId execute(WriteOperation writeOperation) throws IOException {
SegmentBufferWriter writer = borrowWriter(currentThread());
@@ -80,10 +107,10 @@ class SegmentBufferWriterPool implements
private synchronized SegmentBufferWriter borrowWriter(Object key) {
SegmentBufferWriter writer = writers.remove(key);
if (writer == null) {
- writer = new SegmentBufferWriter(store, version, getWriterId(wid));
- } else if (writer.getGeneration() != store.getTracker().getGcGeneration()) {
+ writer = new SegmentBufferWriter(store, version, getWriterId(wid), gcGeneration.get());
+ } else if (writer.getGeneration() != gcGeneration.get()) {
disposed.add(writer);
- writer = new SegmentBufferWriter(store, version, getWriterId(wid));
+ writer = new SegmentBufferWriter(store, version, getWriterId(wid), gcGeneration.get());
}
borrowed.add(writer);
return writer;
Added: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java?rev=1745182&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java Mon May 23 12:59:22 2016
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.segment;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import com.google.common.cache.RemovalCause;
+import org.apache.jackrabbit.oak.cache.CacheLIRS;
+import org.apache.jackrabbit.oak.cache.CacheLIRS.EvictionCallback;
+import org.apache.jackrabbit.oak.cache.CacheStats;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * FIXME OAK-4373 document, add monitoring, management, tests, logging
+ */
+public class SegmentCache {
+ private static final Logger LOG = LoggerFactory.getLogger(SegmentCache.class);
+
+ /**
+ * Cache of recently accessed segments
+ */
+ @Nonnull
+ private final CacheLIRS<SegmentId, Segment> cache;
+
+ public SegmentCache(long cacheSizeMB) {
+ this.cache = CacheLIRS.<SegmentId, Segment>newBuilder()
+ .module("SegmentCache")
+ .maximumWeight(cacheSizeMB * 1024 * 1024)
+ .averageWeight(Segment.MAX_SEGMENT_SIZE/2)
+ .evictionCallback(new EvictionCallback<SegmentId, Segment>() {
+ @Override
+ public void evicted(SegmentId id, Segment segment, RemovalCause cause) {
+ if (segment != null) {
+ id.unloaded();
+ }
+ } })
+ .build();
+ }
+
+ /**
+ * Get a segment from the cache
+ * @param id segment id
+ * @return segment with the given {@code id} or {@code null} if not in the cache
+ */
+ @CheckForNull
+ public Segment geSegment(@Nonnull SegmentId id) {
+ try {
+ return cache.get(id);
+ } catch (ExecutionException e) {
+ LOG.error("Error loading segment {} from cache", id, e);
+ return null;
+ }
+ }
+
+ @Nonnull
+ public Segment geSegment(@Nonnull SegmentId id, @Nonnull Callable<Segment> loader)
+ throws ExecutionException {
+ return cache.get(id, loader);
+ }
+
+ public void putSegment(@Nonnull Segment segment) {
+ cache.put(segment.getSegmentId(), segment, segment.size());
+ segment.getSegmentId().loaded(segment);
+ }
+
+ public void clear() {
+ cache.invalidateAll();
+ }
+
+ @Nonnull
+ public CacheStats getCacheStats() {
+ return new CacheStats(cache, "Segment Cache", null, -1);
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentGraph.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentGraph.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentGraph.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentGraph.java Mon May 23 12:59:22 2016
@@ -166,7 +166,7 @@ public final class SegmentGraph {
? Predicates.<UUID>alwaysTrue()
: createRegExpFilter(pattern, fileStore.getTracker());
Graph<UUID> segmentGraph = parseSegmentGraph(fileStore, filter);
- Graph<UUID> headGraph = parseHeadGraph(root.getRecordId());
+ Graph<UUID> headGraph = parseHeadGraph(fileStore, root.getRecordId());
writer.write("nodedef>name VARCHAR, label VARCHAR, type VARCHAR, wid VARCHAR, gc INT, t INT, size INT, head BOOLEAN\n");
for (UUID segment : segmentGraph.vertices()) {
@@ -349,17 +349,18 @@ public final class SegmentGraph {
}
/**
- * Parser the head graph. The head graph is the sub graph of the segment
+ * Parser the head graph of a {@code store}. The head graph is the sub graph of the segment
* graph containing the {@code root}.
+ * @param store
* @param root
* @return the head graph of {@code root}.
*/
@Nonnull
- public static Graph<UUID> parseHeadGraph(@Nonnull RecordId root) {
+ public static Graph<UUID> parseHeadGraph(@Nonnull SegmentStore store, @Nonnull RecordId root) {
final Graph<UUID> graph = new Graph<UUID>();
try {
- new SegmentParser() {
+ new SegmentParser(store) {
private void addEdge(RecordId from, RecordId to) {
graph.addVertex(from.asUUID());
graph.addVertex(to.asUUID());
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java Mon May 23 12:59:22 2016
@@ -18,11 +18,10 @@
*/
package org.apache.jackrabbit.oak.segment;
-import static java.lang.Integer.getInteger;
-import static java.lang.Integer.rotateLeft;
-
import java.util.UUID;
+import javax.annotation.Nonnull;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,21 +36,6 @@ public class SegmentId implements Compar
private static final Logger log = LoggerFactory.getLogger(SegmentId.class);
/**
- * Sample rate bit mask of {@link SegmentTracker#segmentCache}. Lower values
- * will cause more frequent accesses to that cache instead of the short
- * circuit through {@link SegmentId#segment}. Access to that cache is slower
- * but allows tracking access statistics. Should be 2^x - 1 (for example
- * 1023, 255, 15,...).
- */
- private static final int SEGMENT_CACHE_SAMPLE_MASK = getInteger("SegmentCacheSampleRate", 1023);
-
- /**
- * The initial random value for the pseudo random number generator. Initial
- * values of 0 - 0xffff will ensure a long period, but other values don't.
- */
- private static volatile int random = (int) (System.currentTimeMillis() & 0xffff);
-
- /**
* Checks whether this is a data segment identifier.
*
* @return {@code true} for a data segment, {@code false} otherwise
@@ -60,7 +44,8 @@ public class SegmentId implements Compar
return (lsb >>> 60) == 0xAL;
}
- private final SegmentTracker tracker;
+ @Nonnull
+ private final SegmentStore store;
private final long msb;
@@ -70,15 +55,12 @@ public class SegmentId implements Compar
/**
* A reference to the segment object, if it is available in memory. It is
- * used for fast lookup. The segment tracker will set or reset this field.
- * <p>
- * Needs to be volatile so {@link #setSegment(Segment)} doesn't need to
- * be synchronized as this would lead to deadlocks.
+ * used for fast lookup.
*/
private volatile Segment segment;
- public SegmentId(SegmentTracker tracker, long msb, long lsb) {
- this.tracker = tracker;
+ public SegmentId(@Nonnull SegmentStore store, long msb, long lsb) {
+ this.store = store;
this.msb = msb;
this.lsb = lsb;
this.creationTime = System.currentTimeMillis();
@@ -110,47 +92,37 @@ public class SegmentId implements Compar
return lsb;
}
- /**
- * Get a random integer. A fast, but lower quality pseudo random number
- * generator is used.
- *
- * @return a random value.
- */
- private static int randomInt() {
- // There is a race here on concurrent access. However, given the usage the resulting
- // bias seems preferable to the performance penalty of synchronization
- return random = 0xc3e157c1 - rotateLeft(random, 19);
- }
-
public Segment getSegment() {
- // Sample the segment cache once in a while to get some cache hit/miss statistics
- if ((randomInt() & SEGMENT_CACHE_SAMPLE_MASK) == 0) {
- Segment segment = tracker.getCachedSegment(this);
- if (segment != null) {
- return segment;
- }
- }
-
- // Fall back to short circuit via this.segment if not in the cache
Segment segment = this.segment;
if (segment == null) {
synchronized (this) {
segment = this.segment;
if (segment == null) {
- log.debug("Loading segment {}", this);
- segment = tracker.readSegment(this);
+ try {
+ log.debug("Loading segment {}", this);
+ segment = store.readSegment(this);
+ } catch (SegmentNotFoundException snfe) {
+ long delta = System.currentTimeMillis() - creationTime;
+ log.error("Segment not found: {}. Creation date delta is {} ms.",
+ this, delta, snfe);
+ throw snfe;
+ }
}
}
}
return segment;
}
- void setSegment(Segment segment) {
+ void loaded(@Nonnull Segment segment) {
this.segment = segment;
}
- public SegmentTracker getTracker() {
- return tracker;
+ void unloaded() {
+ this.segment = null;
+ }
+
+ public boolean sameStore(@Nonnull SegmentStore store) {
+ return this.store == store;
}
public long getCreationTime() {
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentIdTable.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentIdTable.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentIdTable.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentIdTable.java Mon May 23 12:59:22 2016
@@ -18,6 +18,7 @@
*/
package org.apache.jackrabbit.oak.segment;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMapWithExpectedSize;
import static java.util.Collections.nCopies;
@@ -28,6 +29,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nonnull;
+
import com.google.common.base.Predicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,8 +63,9 @@ public class SegmentIdTable {
private final ArrayList<WeakReference<SegmentId>> references =
newArrayList(nCopies(1024, (WeakReference<SegmentId>) null));
- private final SegmentTracker tracker;
-
+ @Nonnull
+ private final SegmentStore store;
+
private static final Logger LOG = LoggerFactory.getLogger(SegmentIdTable.class);
@@ -75,8 +79,8 @@ public class SegmentIdTable {
*/
private int entryCount;
- SegmentIdTable(SegmentTracker tracker) {
- this.tracker = tracker;
+ SegmentIdTable(@Nonnull SegmentStore store) {
+ this.store = checkNotNull(store);
}
/**
@@ -106,7 +110,7 @@ public class SegmentIdTable {
reference = references.get(index);
}
- SegmentId id = new SegmentId(tracker, msb, lsb);
+ SegmentId id = new SegmentId(store, msb, lsb);
references.set(index, new WeakReference<SegmentId>(id));
entryCount++;
if (entryCount > references.size() * 0.75) {
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeBuilder.java Mon May 23 12:59:22 2016
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.segment;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.io.IOException;
import java.io.InputStream;
@@ -45,6 +47,7 @@ public class SegmentNodeBuilder extends
private static final int UPDATE_LIMIT =
Integer.getInteger("update.limit", 10000);
+ @Nonnull
private final SegmentWriter writer;
/**
@@ -61,20 +64,15 @@ public class SegmentNodeBuilder extends
*/
private long updateCount;
- SegmentNodeBuilder(SegmentNodeState base) {
- this(base, base.getTracker().getWriter());
- }
-
- SegmentNodeBuilder(SegmentNodeState base, SegmentWriter writer) {
+ SegmentNodeBuilder(@Nonnull SegmentNodeState base, @Nonnull SegmentWriter writer) {
super(base);
- this.writer = writer;
+ this.writer = checkNotNull(writer);
this.updateCount = 0;
}
- private SegmentNodeBuilder(SegmentNodeBuilder parent, String name,
- SegmentWriter writer) {
+ private SegmentNodeBuilder(SegmentNodeBuilder parent, String name, @Nonnull SegmentWriter writer) {
super(parent, name);
- this.writer = writer;
+ this.writer = checkNotNull(writer);
this.updateCount = -1;
}
@@ -129,8 +127,7 @@ public class SegmentNodeBuilder extends
@Override
public Blob createBlob(InputStream stream) throws IOException {
- SegmentNodeState sns = getNodeState();
- return sns.getTracker().getWriter().writeStream(stream);
+ return writer.writeStream(stream);
}
}
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=1745182&r1=1745181&r2=1745182&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 Mon May 23 12:59:22 2016
@@ -33,7 +33,6 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.api.Type.STRINGS;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;
-import static org.apache.jackrabbit.oak.segment.Segment.readString;
import static org.apache.jackrabbit.oak.segment.Segment.unpack;
import static org.apache.jackrabbit.oak.spi.state.AbstractNodeState.checkValidName;
@@ -58,13 +57,16 @@ import org.apache.jackrabbit.oak.spi.sta
* currently doesn't cache data (but the template is fully loaded).
*/
public class SegmentNodeState extends Record implements NodeState {
+ @Nonnull
+ private final SegmentStore store;
private volatile RecordId templateId = null;
private volatile Template template = null;
- public SegmentNodeState(RecordId id) {
+ public SegmentNodeState(@Nonnull SegmentStore store, @Nonnull RecordId id) {
super(id);
+ this.store = checkNotNull(store);
}
RecordId getTemplateId() {
@@ -80,14 +82,14 @@ public class SegmentNodeState extends Re
if (template == null) {
// no problem if updated concurrently,
// as each concurrent thread will just get the same value
- template = getSegment().readTemplate(getTemplateId());
+ template = store.getReader().readTemplate(store, getTemplateId());
}
return template;
}
MapRecord getChildNodeMap() {
Segment segment = getSegment();
- return segment.readMap(segment.readRecordId(getOffset(0, 2)));
+ return store.getReader().readMap(store, segment.readRecordId(getOffset(0, 2)));
}
/**
@@ -161,7 +163,7 @@ public class SegmentNodeState extends Re
if (propertyTemplate != null) {
Segment segment = getSegment();
RecordId id = getRecordId(segment, template, propertyTemplate);
- return new SegmentPropertyState(id, propertyTemplate);
+ return new SegmentPropertyState(store, id, propertyTemplate);
} else {
return null;
}
@@ -208,8 +210,7 @@ public class SegmentNodeState extends Re
propertyTemplates.length);
for (int i = 0; i < propertyTemplates.length; i++) {
RecordId propertyId = pIds.getEntry(i);
- list.add(new SegmentPropertyState(propertyId,
- propertyTemplates[i]));
+ list.add(new SegmentPropertyState(store, propertyId, propertyTemplates[i]));
}
}
@@ -288,7 +289,7 @@ public class SegmentNodeState extends Re
Segment segment = getSegment();
RecordId id = getRecordId(segment, template, propertyTemplate);
- return readString(id);
+ return store.getReader().readString(id);
}
/**
@@ -334,13 +335,13 @@ public class SegmentNodeState extends Re
id = segment.readRecordId(id.getOffset() + 4);
if (size == 1) {
- return singletonList(readString(id));
+ return singletonList(store.getReader().readString(id));
}
List<String> values = newArrayListWithCapacity(size);
ListRecord list = new ListRecord(id, size);
for (RecordId value : list.getEntries()) {
- values.add(readString(value));
+ values.add(store.getReader().readString(value));
}
return values;
}
@@ -381,7 +382,7 @@ public class SegmentNodeState extends Re
&& childName.equals(name)) {
Segment segment = getSegment();
RecordId childNodeId = segment.readRecordId(getOffset(0, 2));
- return new SegmentNodeState(childNodeId);
+ return new SegmentNodeState(store, childNodeId);
}
checkValidName(name);
return MISSING_NODE;
@@ -410,13 +411,13 @@ public class SegmentNodeState extends Re
Segment segment = getSegment();
RecordId childNodeId = segment.readRecordId(getOffset(0, 2));
return Collections.singletonList(new MemoryChildNodeEntry(
- childName, new SegmentNodeState(childNodeId)));
+ childName, new SegmentNodeState(store, childNodeId)));
}
}
@Override @Nonnull
public SegmentNodeBuilder builder() {
- return new SegmentNodeBuilder(this);
+ return new SegmentNodeBuilder(this, store.getWriter());
}
@Override
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStore.java Mon May 23 12:59:22 2016
@@ -291,7 +291,7 @@ public class SegmentNodeStore implements
@Override
public Blob createBlob(InputStream stream) throws IOException {
- return store.getTracker().getWriter().writeStream(stream);
+ return store.getWriter().writeStream(stream);
}
@Override
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java Mon May 23 12:59:22 2016
@@ -360,9 +360,8 @@ public class SegmentNodeStoreService ext
// Expose stats about the segment cache
- CacheStats segmentCacheStats = store.getTracker().getSegmentCacheStats();
-
- segmentCacheMBean = registerMBean(
+ CacheStats segmentCacheStats = store.getSegmentCacheStats();
+ segmentCacheMBean = registerMBean(
whiteboard,
CacheStatsMBean.class,
segmentCacheStats,
@@ -372,16 +371,13 @@ public class SegmentNodeStoreService ext
// Expose stats about the string cache, if available
- CacheStats stringCacheStats = store.getTracker().getStringCacheStats();
-
- if (stringCacheStats != null) {
- stringCacheMBean = registerMBean(
- whiteboard,
- CacheStatsMBean.class,
- stringCacheStats,CacheStats.TYPE,
- stringCacheStats.getName()
- );
- }
+ CacheStats stringCacheStats = store.getReader().getStringCacheStats();
+ stringCacheMBean = registerMBean(
+ whiteboard,
+ CacheStatsMBean.class,
+ stringCacheStats,CacheStats.TYPE,
+ stringCacheStats.getName()
+ );
// Listen for Executor services on the whiteboard
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentParser.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentParser.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentParser.java Mon May 23 12:59:22 2016
@@ -20,6 +20,7 @@
package org.apache.jackrabbit.oak.segment;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newArrayListWithCapacity;
import static java.util.Collections.singletonList;
@@ -34,6 +35,8 @@ import static org.apache.jackrabbit.oak.
import java.util.List;
+import javax.annotation.Nonnull;
+
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
@@ -254,6 +257,13 @@ public class SegmentParser {
}
}
+ @Nonnull
+ private final SegmentStore store;
+
+ public SegmentParser(@Nonnull SegmentStore store) {
+ this.store = checkNotNull(store);
+ }
+
/**
* Callback called by {@link #parseNode(RecordId)} upon encountering
* a child node.
@@ -413,22 +423,22 @@ public class SegmentParser {
Segment segment = nodeId.getSegment();
int offset = nodeId.getOffset();
- String stableId = new SegmentNodeState(nodeId).getStableId();
+ String stableId = new SegmentNodeState(store, nodeId).getStableId();
offset += RECORD_ID_BYTES;
RecordId templateId = segment.readRecordId(offset);
onTemplate(nodeId, templateId);
- Template template = segment.readTemplate(templateId);
+ Template template = store.getReader().readTemplate(store, templateId);
// Recurses into child nodes in this segment
if (template.getChildName() == MANY_CHILD_NODES) {
RecordId childMapId = segment.readRecordId(offset + RECORD_ID_BYTES);
- MapRecord childMap = segment.readMap(childMapId);
+ MapRecord childMap = store.getReader().readMap(store, childMapId);
onMap(nodeId, childMapId, childMap);
for (ChildNodeEntry childNodeEntry : childMap.getEntries()) {
NodeState child = childNodeEntry.getNodeState();
if (child instanceof SegmentNodeState) {
- RecordId childId = ((SegmentNodeState) child).getRecordId();
+ RecordId childId = ((Record) child).getRecordId();
onNode(nodeId, childId);
nodeCount++;
}
@@ -548,7 +558,7 @@ public class SegmentParser {
RecordId baseId = mapId.getSegment()
.readRecordId(mapId.getOffset() + 8 + 2 * RECORD_ID_BYTES);
- onMap(mapId, baseId, new MapRecord(baseId));
+ onMap(mapId, baseId, new MapRecord(store, baseId));
return new MapInfo(mapId, size);
}
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentPropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentPropertyState.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentPropertyState.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentPropertyState.java Mon May 23 12:59:22 2016
@@ -61,18 +61,26 @@ import org.apache.jackrabbit.oak.plugins
* of type "LIST" (for arrays).
*/
public class SegmentPropertyState extends Record implements PropertyState {
+ @Nonnull
+ private final SegmentStore store;
+ @Nonnull
private final String name;
+
+ @Nonnull
private final Type<?> type;
- SegmentPropertyState(RecordId id, String name, Type<?> type) {
+ SegmentPropertyState(@Nonnull SegmentStore store, @Nonnull RecordId id,
+ @Nonnull String name, @Nonnull Type<?> type) {
super(id);
+ this.store = checkNotNull(store);
this.name = checkNotNull(name);
this.type = checkNotNull(type);
}
- SegmentPropertyState(RecordId id, PropertyTemplate template) {
- this(id, template.getName(), template.getType());
+ SegmentPropertyState(@Nonnull SegmentStore store, @Nonnull RecordId id,
+ @Nonnull PropertyTemplate template) {
+ this(store, id, template.getName(), template.getType());
}
private ListRecord getValueList(Segment segment) {
@@ -98,7 +106,7 @@ public class SegmentPropertyState extend
ListRecord values = getValueList(segment);
for (int i = 0; i < values.size(); i++) {
RecordId valueId = values.getEntry(i);
- String value = Segment.readString(valueId);
+ String value = store.getReader().readString(valueId);
map.put(value, valueId);
}
@@ -110,6 +118,7 @@ public class SegmentPropertyState extend
return name;
}
+ @Nonnull
@Override
public Type<?> getType() {
return type;
@@ -138,13 +147,12 @@ public class SegmentPropertyState extend
if (values.size() == 0) {
return (T) emptyList();
} else if (values.size() == 1) {
- return (T) singletonList(getValue(
- segment, values.getEntry(0), type.getBaseType()));
+ return (T) singletonList(getValue(values.getEntry(0), type.getBaseType()));
} else {
Type<?> base = type.getBaseType();
List<Object> list = newArrayListWithCapacity(values.size());
for (RecordId id : values.getEntries()) {
- list.add(getValue(segment, id, base));
+ list.add(getValue(id, base));
}
return (T) list;
}
@@ -152,9 +160,9 @@ public class SegmentPropertyState extend
RecordId id = getRecordId();
if (type.isArray()) {
return (T) singletonList(
- getValue(segment, id, type.getBaseType()));
+ getValue(id, type.getBaseType()));
} else {
- return getValue(segment, id, type);
+ return getValue(id, type);
}
}
}
@@ -172,16 +180,16 @@ public class SegmentPropertyState extend
Segment segment = getSegment();
ListRecord values = getValueList(segment);
checkElementIndex(index, values.size());
- return getValue(segment, values.getEntry(index), type);
+ return getValue(values.getEntry(index), type);
}
@SuppressWarnings("unchecked")
- private <T> T getValue(Segment segment, RecordId id, Type<T> type) {
+ private <T> T getValue(RecordId id, Type<T> type) {
if (type == BINARY) {
- return (T) new SegmentBlob(id); // load binaries lazily
+ return (T) new SegmentBlob(store, id); // load binaries lazily
}
- String value = Segment.readString(id);
+ String value = store.getReader().readString(id);
if (type == STRING || type == URI || type == DATE
|| type == NAME || type == PATH
|| type == REFERENCE || type == WEAKREFERENCE) {
@@ -214,7 +222,7 @@ public class SegmentPropertyState extend
RecordId entry = values.getEntry(index);
if (getType().equals(BINARY) || getType().equals(BINARIES)) {
- return new SegmentBlob(entry).length();
+ return new SegmentBlob(store, entry).length();
}
return getSegment().readLength(entry);
Copied: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java (from r1745165, jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FileStoreTest.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java?p2=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java&p1=jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FileStoreTest.java&r1=1745165&r2=1745182&rev=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FileStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java Mon May 23 12:59:22 2016
@@ -17,36 +17,23 @@
* under the License.
*/
-package org.apache.jackrabbit.oak.segment.file;
+package org.apache.jackrabbit.oak.segment;
-import java.io.File;
-import java.io.IOException;
+import javax.annotation.Nonnull;
-import org.apache.jackrabbit.oak.segment.SegmentId;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-public class FileStoreTest {
-
- @Rule
- public TemporaryFolder folder = new TemporaryFolder();
-
- private File getFileStoreFolder() {
- return folder.getRoot();
- }
-
- @Test
- public void containsSegment() throws IOException {
- FileStore fileStore = FileStore.builder(getFileStoreFolder()).build();
- try {
- SegmentId id = new SegmentId(fileStore.getTracker(), 0, 0);
- if (fileStore.containsSegment(id)) {
- fileStore.readSegment(id);
- }
- } finally {
- fileStore.close();
- }
- }
+import org.apache.jackrabbit.oak.cache.CacheStats;
+public interface SegmentReader {
+ @Nonnull
+ String readString(@Nonnull RecordId id);
+
+ @Nonnull
+ MapRecord readMap(@Nonnull SegmentStore store, @Nonnull RecordId id);
+
+ @Nonnull
+ Template readTemplate(@Nonnull SegmentStore store, @Nonnull RecordId id);
+
+ // FIXME OAK-4373 remove from this interface
+ @Nonnull
+ CacheStats getStringCacheStats();
}
Added: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java?rev=1745182&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java Mon May 23 12:59:22 2016
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.segment;
+
+import static java.lang.Long.getLong;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.google.common.base.Function;
+import org.apache.jackrabbit.oak.cache.CacheStats;
+
+/*
+ * FIXME OAK-4373 implement invalidation through GCMonitor listener
+ * FIXME OAK-4373 implement monitoring, management, logging, tests
+ */
+public class SegmentReaderImpl implements SegmentReader {
+ public static final int DEFAULT_STRING_CACHE_MB = 256;
+
+ public static final String STRING_CACHE_MB = "oak.segment.stringCacheMB";
+
+ /**
+ * Cache for string records
+ */
+ private final StringCache stringCache;
+
+ public SegmentReaderImpl(long stringCacheMB) {
+ stringCache = new StringCache(getLong(STRING_CACHE_MB, stringCacheMB) * 1024 * 1024);
+ }
+
+ public SegmentReaderImpl() {
+ this(DEFAULT_STRING_CACHE_MB);
+ }
+
+ @Nonnull
+ @Override
+ public String readString(@Nonnull RecordId id) {
+ final SegmentId segmentId = id.getSegmentId();
+ long msb = segmentId.getMostSignificantBits();
+ long lsb = segmentId.getLeastSignificantBits();
+ return stringCache.getString(msb, lsb, id.getOffset(), new Function<Integer, String>() {
+ @Nullable
+ @Override
+ public String apply(Integer offset) {
+ return segmentId.getSegment().readString(offset);
+ }
+ });
+ }
+
+ @Nonnull
+ @Override
+ public MapRecord readMap(@Nonnull SegmentStore store, @Nonnull RecordId id) {
+ return new MapRecord(store, id);
+ }
+
+ @Nonnull
+ @Override
+ public Template readTemplate(@Nonnull SegmentStore store, @Nonnull RecordId id) {
+ int offset = id.getOffset();
+ if (id.getSegment().templates == null) {
+ return id.getSegment().readTemplate(offset);
+ }
+ Template template = id.getSegment().templates.get(offset);
+ if (template == null) {
+ template = id.getSegment().readTemplate(offset);
+ id.getSegment().templates.putIfAbsent(offset, template); // only keep the first copy
+ }
+ return template;
+ }
+
+ @Nonnull
+ @Override
+ public CacheStats getStringCacheStats() {
+ return stringCache.getStats();
+ }
+}
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStore.java?rev=1745182&r1=1745181&r2=1745182&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStore.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentStore.java Mon May 23 12:59:22 2016
@@ -33,6 +33,10 @@ public interface SegmentStore {
SegmentTracker getTracker();
+ SegmentWriter getWriter();
+
+ SegmentReader getReader();
+
/**
* Returns the head state.
*
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=1745182&r1=1745181&r2=1745182&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 Mon May 23 12:59:22 2016
@@ -44,7 +44,7 @@ public class SegmentStream extends Input
if (stream instanceof SegmentStream) {
SegmentStream sstream = (SegmentStream) stream;
RecordId id = sstream.recordId;
- if (sstream.position == 0 && store.getTracker().isTracking(id.getSegmentId())) {
+ if (sstream.position == 0 && id.getSegmentId().sameStore(store)) {
return id;
}
}