Author: mduerig
Date: Wed Jun  1 07:48:51 2016
New Revision: 1746410

URL: http://svn.apache.org/viewvc?rev=1746410&view=rev
Log:
OAK-4373: Refactor SegmentTracker
Introduce Revisions for setting and getting the head revisions. Remove those 
methods from SegmentStore
Remove getters for BlobStore, SegmentTracker, SegmentReader and SegmentWriter 
from SegmentStore
Rename SegmentReaderImpl to CachedSegmentReader

Added:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CachingSegmentReader.java
      - copied, changed from r1746408, 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Revisions.java
      - copied, changed from r1746408, 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreBuilders.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaders.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriters.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarRevisions.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/http/HttpStoreRevisions.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/memory/MemoryStoreRevisions.java
Removed:
    
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/checkpoint/SegmentTarCheckpoints.java
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/console/SegmentTarFixture.java
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/SegmentTarExplorerBackend.java
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/fixture/SegmentTarFixture.java
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/SegmentTarUtils.java
    
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/backup/FileStoreBackup.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.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/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/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/SegmentReader.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/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/file/tooling/ConsistencyChecker.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tooling/RevisionHistory.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/backup/FileStoreBackupTest.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CheckpointTest.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/CompactorTest.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/ExternalBlobIT.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/HeavyWriteIT.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/InitializerTest.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MergeTest.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/SegmentDataStoreBlobGCIT.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/SegmentOverflowExceptionIT.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/file/CompactionEstimatorTest.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/JournalEntryTest.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/LargeNumberOfPropertiesTestIT.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/SegmentReferenceLimitTestIT.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/fixture/SegmentTarFixture.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/DepthFirstNodeIteratorTest.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/ExternalToExternalMigrationTest.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/SegmentToExternalMigrationTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentTarFactory.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/AbstractRepositoryUpgradeTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/BrokenVersionableTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/UpgradeFromTwoSourcesTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/UpgradeOldSegmentTest.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentTarNodeStoreContainer.java
    
jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentTarCheckpoints.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentTarCheckpoints.java?rev=1746410&r1=1746409&r2=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentTarCheckpoints.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentTarCheckpoints.java
 Wed Jun  1 07:48:51 2016
@@ -44,7 +44,7 @@ class SegmentTarCheckpoints extends Chec
     @Override
     public List<CP> list() {
         List<CP> list = Lists.newArrayList();
-        NodeState ns = store.getHead().getChildNode("checkpoints");
+        NodeState ns = 
store.getReader().readHeadState().getChildNode("checkpoints");
         for (ChildNodeEntry cne : ns.getChildNodeEntries()) {
             NodeState cneNs = cne.getNodeState();
             list.add(new CP(cne.getName(),
@@ -55,13 +55,13 @@ class SegmentTarCheckpoints extends Chec
 
     @Override
     public long removeAll() {
-        SegmentNodeState head = store.getHead();
+        SegmentNodeState head = store.getReader().readHeadState();
         NodeBuilder builder = head.builder();
 
         NodeBuilder cps = builder.getChildNode("checkpoints");
         long cnt = cps.getChildNodeCount(Integer.MAX_VALUE);
         builder.setChildNode("checkpoints");
-        if (store.setHead(head, asSegmentNodeState(builder))) {
+        if (store.getRevisions().setHead(head.getRecordId(), 
asSegmentNodeState(builder).getRecordId())) {
             return cnt;
         } else {
             return -1;
@@ -70,7 +70,7 @@ class SegmentTarCheckpoints extends Chec
 
     @Override
     public long removeUnreferenced() {
-        SegmentNodeState head = store.getHead();
+        SegmentNodeState head = store.getReader().readHeadState();
 
         String ref = getReferenceCheckpoint(head.getChildNode("root"));
 
@@ -85,7 +85,7 @@ class SegmentTarCheckpoints extends Chec
             cnt++;
         }
 
-        if (store.setHead(head, asSegmentNodeState(builder))) {
+        if (store.getRevisions().setHead(head.getRecordId(), 
asSegmentNodeState(builder).getRecordId())) {
             return cnt;
         } else {
             return -1;
@@ -94,14 +94,14 @@ class SegmentTarCheckpoints extends Chec
 
     @Override
     public int remove(String cp) {
-        SegmentNodeState head = store.getHead();
+        SegmentNodeState head = store.getReader().readHeadState();
         NodeBuilder builder = head.builder();
 
         NodeBuilder cpn = builder.getChildNode("checkpoints")
                 .getChildNode(cp);
         if (cpn.exists()) {
             cpn.remove();
-            if (store.setHead(head, asSegmentNodeState(builder))) {
+            if (store.getRevisions().setHead(head.getRecordId(), 
asSegmentNodeState(builder).getRecordId())) {
                 return 1;
             } else {
                 return -1;

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/console/SegmentTarFixture.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/console/SegmentTarFixture.java?rev=1746410&r1=1746409&r2=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/console/SegmentTarFixture.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/console/SegmentTarFixture.java
 Wed Jun  1 07:48:51 2016
@@ -21,6 +21,7 @@ import java.io.File;
 import java.io.IOException;
 
 import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -51,7 +52,7 @@ class SegmentTarFixture implements NodeS
 
     private SegmentTarFixture(FileStore fileStore) {
         this.fileStore = fileStore;
-        this.segmentNodeStore = SegmentNodeStore.builder(fileStore).build();
+        this.segmentNodeStore = 
SegmentNodeStoreBuilders.builder(fileStore).build();
     }
 
     @Override

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/SegmentTarExplorerBackend.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/SegmentTarExplorerBackend.java?rev=1746410&r1=1746409&r2=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/SegmentTarExplorerBackend.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/SegmentTarExplorerBackend.java
 Wed Jun  1 07:48:51 2016
@@ -169,12 +169,12 @@ class SegmentTarExplorerBackend implemen
 
     @Override
     public NodeState getHead() {
-        return store.getHead();
+        return store.getReader().readHeadState();
     }
 
     @Override
     public NodeState readNodeState(String recordId) {
-        return new SegmentNodeState(store, 
RecordId.fromString(store.getTracker(), recordId));
+        return 
store.getReader().readNode(RecordId.fromString(store.getTracker(), recordId));
     }
 
     @Override

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/fixture/SegmentTarFixture.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/fixture/SegmentTarFixture.java?rev=1746410&r1=1746409&r2=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/fixture/SegmentTarFixture.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/fixture/SegmentTarFixture.java
 Wed Jun  1 07:48:51 2016
@@ -21,9 +21,7 @@ import java.io.File;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.Oak;
-import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
-import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
-import org.apache.jackrabbit.oak.segment.SegmentStore;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 
@@ -59,7 +57,7 @@ class SegmentTarFixture extends OakFixtu
                 .withCacheSize(cacheSizeMB)
                 .withMemoryMapping(memoryMapping)
                 .build();
-        return newOak(SegmentNodeStore.builder(fs).build());
+        return newOak(SegmentNodeStoreBuilders.builder(fs).build());
     }
 
     @Override
@@ -81,19 +79,19 @@ class SegmentTarFixture extends OakFixtu
             if (blobStore != null) {
                 builder.withBlobStore(blobStore);
             }
-            stores[i] = builder.withRoot(EmptyNodeState.EMPTY_NODE)
+            stores[i] = builder
                     .withMaxFileSize(maxFileSizeMB)
                     .withCacheSize(cacheSizeMB)
                     .withMemoryMapping(memoryMapping)
                     .build();
-            cluster[i] = newOak(SegmentNodeStore.builder(stores[i]).build());
+            cluster[i] = 
newOak(SegmentNodeStoreBuilders.builder(stores[i]).build());
         }
         return cluster;
     }
 
     @Override
     public void tearDownCluster() {
-        for (SegmentStore store : stores) {
+        for (FileStore store : stores) {
             store.close();
         }
         for (BlobStoreFixture blobStore : blobStoreFixtures) {

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/SegmentTarUtils.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/SegmentTarUtils.java?rev=1746410&r1=1746409&r2=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/SegmentTarUtils.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/SegmentTarUtils.java
 Wed Jun  1 07:48:51 2016
@@ -21,7 +21,7 @@ import java.io.File;
 import java.io.IOException;
 
 import com.google.common.io.Closer;
-import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -33,7 +33,7 @@ class SegmentTarUtils {
     }
 
     static NodeStore bootstrap(String path, BlobStore store, Closer closer) 
throws IOException {
-        return SegmentNodeStore.builder(fileStore(path, store, 
closer)).build();
+        return SegmentNodeStoreBuilders.builder(fileStore(path, store, 
closer)).build();
     }
 
     private static FileStore fileStore(String path, BlobStore store, Closer 
closer) throws IOException {

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -79,9 +79,10 @@ import org.apache.jackrabbit.oak.segment
 import org.apache.jackrabbit.oak.segment.SegmentBlobReferenceRetriever;
 import org.apache.jackrabbit.oak.segment.SegmentId;
 import org.apache.jackrabbit.oak.segment.SegmentNodeState;
-import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
 import org.apache.jackrabbit.oak.segment.SegmentNotFoundException;
 import org.apache.jackrabbit.oak.segment.SegmentPropertyState;
+import org.apache.jackrabbit.oak.segment.SegmentReader;
 import org.apache.jackrabbit.oak.segment.SegmentTracker;
 import org.apache.jackrabbit.oak.segment.SegmentVersion;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
@@ -106,7 +107,7 @@ final class SegmentTarUtils {
     }
 
     static NodeStore bootstrapNodeStore(String path, Closer closer) throws 
IOException {
-        return SegmentNodeStore.builder(bootstrapFileStore(path, 
closer)).build();
+        return SegmentNodeStoreBuilders.builder(bootstrapFileStore(path, 
closer)).build();
     }
 
     static BlobReferenceRetriever newBlobReferenceRetriever(String path, 
Closer closer) throws IOException {
@@ -123,7 +124,7 @@ final class SegmentTarUtils {
                 fs = openReadOnlyFileStore(source);
             }
             closer.register(fs);
-            NodeStore store = SegmentNodeStore.builder(fs).build();
+            NodeStore store = SegmentNodeStoreBuilders.builder(fs).build();
             FileStoreBackup.backup(store, target);
         } catch (Throwable e) {
             throw closer.rethrow(e);
@@ -302,12 +303,12 @@ final class SegmentTarUtils {
         RecordId idR = null;
         try {
             if (tokens[0].equalsIgnoreCase("head")) {
-                idL = store.getHead().getRecordId();
+                idL = store.getRevisions().getHead();
             } else {
                 idL = fromString(store.getTracker(), tokens[0]);
             }
             if (tokens[1].equalsIgnoreCase("head")) {
-                idR = store.getHead().getRecordId();
+                idR = store.getRevisions().getHead();
             } else {
                 idR = fromString(store.getTracker(), tokens[1]);
             }
@@ -363,8 +364,8 @@ final class SegmentTarUtils {
     private static boolean diff(ReadOnlyStore store, RecordId idL, RecordId 
idR, String filter, PrintWriter pw) throws IOException {
         pw.println("rev " + idL + ".." + idR);
         try {
-            NodeState before = new SegmentNodeState(store, 
idL).getChildNode("root");
-            NodeState after = new SegmentNodeState(store, 
idR).getChildNode("root");
+            NodeState before = 
store.getReader().readNode(idL).getChildNode("root");
+            NodeState after = 
store.getReader().readNode(idR).getChildNode("root");
             for (String name : elements(filter)) {
                 before = before.getChildNode(name);
                 after = after.getChildNode(name);
@@ -386,7 +387,7 @@ final class SegmentTarUtils {
         long bulkSize = 0;
 
         ((Logger) getLogger(SegmentTracker.class)).setLevel(Level.OFF);
-        RecordUsageAnalyser analyser = new RecordUsageAnalyser(store);
+        RecordUsageAnalyser analyser = new 
RecordUsageAnalyser(store.getReader());
 
         for (SegmentId id : store.getSegmentIds()) {
             if (id.isDataSegmentId()) {
@@ -412,7 +413,7 @@ final class SegmentTarUtils {
 
         Set<SegmentId> garbage = newHashSet(idmap.keySet());
         Queue<SegmentId> queue = Queues.newArrayDeque();
-        queue.add(store.getHead().getRecordId().getSegmentId());
+        queue.add(store.getRevisions().getHead().getSegmentId());
         while (!queue.isEmpty()) {
             SegmentId id = queue.remove();
             if (garbage.remove(id)) {
@@ -479,8 +480,7 @@ final class SegmentTarUtils {
             if (hasrefs) {
                 System.out.println("SegmentNodeState references to " + f);
                 List<String> paths = new ArrayList<String>();
-                filterNodeStates(uuids, paths, store.getHead(),
-                        "/");
+                filterNodeStates(uuids, paths, 
store.getReader().readHeadState(), "/");
                 for (String p : paths) {
                     System.out.println("  " + p);
                 }
@@ -573,6 +573,7 @@ final class SegmentTarUtils {
     }
 
     private static void debugSegment(FileStore store, String[] args) {
+        SegmentReader reader = store.getReader();
         Pattern pattern = Pattern
                 
.compile("([0-9a-f-]+)|(([0-9a-f-]+:[0-9a-f]+)(-([0-9a-f-]+:[0-9a-f]+))?)?(/.*)?");
         for (int i = 1; i < args.length; i++) {
@@ -586,7 +587,7 @@ final class SegmentTarUtils {
                         uuid.getLeastSignificantBits());
                 System.out.println(id.getSegment());
             } else {
-                RecordId id1 = store.getHead().getRecordId();
+                RecordId id1 = store.getRevisions().getHead();
                 RecordId id2 = null;
                 if (matcher.group(2) != null) {
                     id1 = fromString(store.getTracker(),
@@ -602,7 +603,7 @@ final class SegmentTarUtils {
                 }
 
                 if (id2 == null) {
-                    NodeState node = new SegmentNodeState(store, id1);
+                    NodeState node = reader.readNode(id1);
                     System.out.println("/ (" + id1 + ") -> " + node);
                     for (String name : PathUtils.elements(path)) {
                         node = node.getChildNode(name);
@@ -614,8 +615,8 @@ final class SegmentTarUtils {
                                 + node);
                     }
                 } else {
-                    NodeState node1 = new SegmentNodeState(store, id1);
-                    NodeState node2 = new SegmentNodeState(store, id2);
+                    NodeState node1 = reader.readNode(id1);
+                    NodeState node2 = reader.readNode(id2);
                     for (String name : PathUtils.elements(path)) {
                         node1 = node1.getChildNode(name);
                         node2 = node2.getChildNode(name);
@@ -670,7 +671,7 @@ final class SegmentTarUtils {
     }
 
     private static SegmentVersion getSegmentVersion(FileStore fileStore) {
-        return 
fileStore.getHead().getRecordId().getSegment().getSegmentVersion();
+        return 
fileStore.getRevisions().getHead().getSegment().getSegmentVersion();
     }
 
 }

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java?rev=1746410&r1=1746409&r2=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java
 Wed Jun  1 07:48:51 2016
@@ -25,11 +25,10 @@ import java.io.File;
 import java.io.IOException;
 
 import com.google.common.base.Stopwatch;
-import org.apache.jackrabbit.oak.segment.SegmentNodeState;
 import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
-import org.apache.jackrabbit.oak.segment.file.tooling.BasicReadOnlyBlobStore;
 import org.apache.jackrabbit.oak.segment.file.FileStore.Builder;
+import org.apache.jackrabbit.oak.segment.file.tooling.BasicReadOnlyBlobStore;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.slf4j.Logger;
@@ -54,8 +53,8 @@ public class FileStoreBackup {
         }
         FileStore backup = builder.build();
         try {
-            SegmentNodeState state = backup.getHead();
             // FIXME OAK-4278: Fix backup and restore
+//            SegmentNodeState state = backup.getRevisions().getHead();
             // Use dedicated implementation instead of compactor.
             // This is allows us to decouple and fix problems for online 
compaction independent
             // of backup / restore.

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java?rev=1746410&r1=1746409&r2=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java
 Wed Jun  1 07:48:51 2016
@@ -23,7 +23,6 @@ import java.io.File;
 import java.io.IOException;
 
 import com.google.common.base.Stopwatch;
-import org.apache.jackrabbit.oak.segment.SegmentNodeState;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.slf4j.Logger;
@@ -49,9 +48,9 @@ public class FileStoreRestore {
         Stopwatch watch = Stopwatch.createStarted();
 
         FileStore store = FileStore.builder(destination).build();
-        SegmentNodeState current = store.getHead();
+        // FIXME OAK-4278: Fix backup and restore
+//        SegmentNodeState current = store.getRevisions().getHead();
         try {
-            // FIXME OAK-4278: Fix backup and restore
             // Use dedicated implementation instead of compactor.
             // This is allows us to decouple and fix problems for online 
compaction independent
             // of backup / restore.

Copied: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CachingSegmentReader.java
 (from r1746408, 
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/CachingSegmentReader.java?p2=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CachingSegmentReader.java&p1=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java&r1=1746408&r2=1746410&rev=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReaderImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CachingSegmentReader.java
 Wed Jun  1 07:48:51 2016
@@ -22,23 +22,28 @@ package org.apache.jackrabbit.oak.segmen
 import static com.google.common.base.Preconditions.checkNotNull;
 import static java.lang.Long.getLong;
 
+import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import com.google.common.base.Function;
+import com.google.common.base.Supplier;
 import org.apache.jackrabbit.oak.cache.CacheStats;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 
-/*
- * FIXME OAK-4373 implement invalidation through GCMonitor listener
- * FIXME OAK-4373 implement monitoring, management, logging, tests
- */
-public class SegmentReaderImpl implements SegmentReader {
+public class CachingSegmentReader implements SegmentReader {
     public static final int DEFAULT_STRING_CACHE_MB = 256;
 
     public static final String STRING_CACHE_MB = "oak.segment.stringCacheMB";
 
     @Nonnull
-    private final SegmentStore store;
+    private final Supplier<SegmentWriter> writer;
+
+    @Nonnull
+    private final Revisions revisions;
+
+    @CheckForNull
+    private final BlobStore blobStore;
 
     /**
      * Cache for string records
@@ -46,15 +51,17 @@ public class SegmentReaderImpl implement
     @Nonnull
     private final StringCache stringCache;
 
-    public SegmentReaderImpl(@Nonnull SegmentStore store, long stringCacheMB) {
-        this.store = checkNotNull(store);
+    public CachingSegmentReader(
+            @Nonnull Supplier<SegmentWriter> writer,
+            @Nonnull Revisions revisions,
+            @Nullable BlobStore blobStore,
+            long stringCacheMB) {
+        this.writer = checkNotNull(writer);
+        this.revisions = checkNotNull(revisions);
+        this.blobStore = blobStore;
         stringCache = new StringCache(getLong(STRING_CACHE_MB, stringCacheMB) 
* 1024 * 1024);
     }
 
-    public SegmentReaderImpl(@Nonnull SegmentStore store) {
-        this(store, DEFAULT_STRING_CACHE_MB);
-    }
-
     @Nonnull
     @Override
     public String readString(@Nonnull RecordId id) {
@@ -73,7 +80,7 @@ public class SegmentReaderImpl implement
     @Nonnull
     @Override
     public MapRecord readMap(@Nonnull RecordId id) {
-        return new MapRecord(store, id);
+        return new MapRecord(this, id);
     }
 
     @Nonnull
@@ -93,6 +100,30 @@ public class SegmentReaderImpl implement
 
     @Nonnull
     @Override
+    public SegmentNodeState readNode(@Nonnull RecordId id) {
+        return new SegmentNodeState(this, writer, id);
+    }
+
+    @Nonnull
+    @Override
+    public SegmentNodeState readHeadState() {
+        return readNode(revisions.getHead());
+    }
+
+    @Nonnull
+    @Override
+    public SegmentPropertyState readProperty(
+            @Nonnull RecordId id, @Nonnull PropertyTemplate template) {
+        return new SegmentPropertyState(this, id, template);
+    }
+
+    @Nonnull
+    @Override
+    public SegmentBlob readBlob(@Nonnull RecordId id) {
+        return new SegmentBlob(blobStore, id);
+    }
+
+    @Nonnull
     public CacheStats getStringCacheStats() {
         return stringCache.getStats();
     }

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -38,7 +38,7 @@ class MapEntry extends AbstractChildNode
         implements Map.Entry<RecordId, RecordId>, Comparable<MapEntry> {
 
     @Nonnull
-    private final SegmentStore store;
+    private final SegmentReader reader;
 
     @Nonnull
     private final String name;
@@ -49,9 +49,9 @@ class MapEntry extends AbstractChildNode
     @CheckForNull
     private final RecordId value;
 
-    MapEntry(@Nonnull SegmentStore store, @Nonnull String name,
+    MapEntry(@Nonnull SegmentReader reader, @Nonnull String name,
              @Nonnull RecordId key, @Nullable RecordId value) {
-        this.store = checkNotNull(store);
+        this.reader = checkNotNull(reader);
         this.name = checkNotNull(name);
         this.key = checkNotNull(key);
         this.value = value;
@@ -71,7 +71,7 @@ class MapEntry extends AbstractChildNode
     @Override @Nonnull
     public SegmentNodeState getNodeState() {
         checkState(value != null);
-        return new SegmentNodeState(store, value);
+        return reader.readNode(value);
     }
 
     //---------------------------------------------------------< Map.Entry >--

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -32,13 +32,12 @@ import java.util.List;
 
 import javax.annotation.Nonnull;
 
+import com.google.common.base.Objects;
+import com.google.common.collect.ComparisonChain;
 import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
 
-import com.google.common.base.Objects;
-import com.google.common.collect.ComparisonChain;
-
 /**
  * A map. The top level record is either a record of type "BRANCH" or "LEAF"
  * (depending on the data).
@@ -54,7 +53,7 @@ public class MapRecord extends Record {
     static final long HASH_MASK = 0xFFFFFFFFL;
 
     @Nonnull
-    private final SegmentStore store;
+    private final SegmentReader reader;
 
     /**
      * Generates a hash code for the value, using a random number generator
@@ -98,9 +97,9 @@ public class MapRecord extends Record {
      */
     protected static final int MAX_SIZE = (1 << SIZE_BITS) - 1; // ~268e6
 
-    MapRecord(@Nonnull SegmentStore store, @Nonnull RecordId id) {
+    MapRecord(@Nonnull SegmentReader reader, @Nonnull RecordId id) {
         super(id);
-        this.store = checkNotNull(store);
+        this.reader = checkNotNull(reader);
     }
 
     boolean isLeaf() {
@@ -108,7 +107,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(store, base).isLeaf();
+            return reader.readMap(base).isLeaf();
         }
         return !isBranch(head);
     }
@@ -124,7 +123,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(store, 
segment.readRecordId(getOffset(8, ids++)));
+                buckets[i] = reader.readMap(segment.readRecordId(getOffset(8, 
ids++)));
             } else {
                 buckets[i] = null;
             }
@@ -139,7 +138,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(store, id));
+                buckets.add(reader.readMap(id));
             }
         }
         return buckets;
@@ -150,7 +149,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(store, base).size();
+            return reader.readMap(base).size();
         }
         return getSize(head);
     }
@@ -164,13 +163,13 @@ public class MapRecord extends Record {
         if (isDiff(head)) {
             if (hash == segment.readInt(getOffset(4))) {
                 RecordId key = segment.readRecordId(getOffset(8));
-                if (name.equals(store.getReader().readString(key))) {
+                if (name.equals(reader.readString(key))) {
                     RecordId value = segment.readRecordId(getOffset(8, 1));
-                    return new MapEntry(store, name, key, value);
+                    return new MapEntry(reader, name, key, value);
                 }
             }
             RecordId base = segment.readRecordId(getOffset(8, 2));
-            return new MapRecord(store, base).getEntry(name);
+            return reader.readMap(base).getEntry(name);
         }
 
         int size = getSize(head);
@@ -190,7 +189,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(store, id).getEntry(name);
+                return reader.readMap(id).getEntry(name);
             } else {
                 return null;
             }
@@ -219,9 +218,9 @@ public class MapRecord extends Record {
                         getOffset(4 + size * 4, i * 2));
                 RecordId valueId = segment.readRecordId(
                         getOffset(4 + size * 4, i * 2 + 1));
-                diff = store.getReader().readString(keyId).compareTo(name);
+                diff = reader.readString(keyId).compareTo(name);
                 if (diff == 0) {
-                    return new MapEntry(store, name, keyId, valueId);
+                    return new MapEntry(reader, name, keyId, valueId);
                 }
             }
 
@@ -247,7 +246,7 @@ public class MapRecord extends Record {
                 return segment.readRecordId(getOffset(8, 1));
             }
             RecordId base = segment.readRecordId(getOffset(8, 2));
-            return new MapRecord(store, base).getValue(hash, key);
+            return reader.readMap(base).getValue(hash, key);
         }
 
         int size = getSize(head);
@@ -267,7 +266,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(store, id).getValue(hash, key);
+                return reader.readMap(id).getValue(hash, key);
             } else {
                 return null;
             }
@@ -297,7 +296,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(store, base).getKeys();
+            return reader.readMap(base).getKeys();
         }
 
         int size = getSize(head);
@@ -323,7 +322,7 @@ public class MapRecord extends Record {
 
         String[] keys = new String[size];
         for (int i = 0; i < size; i++) {
-            keys[i] = store.getReader().readString(ids[i]);
+            keys[i] = reader.readString(ids[i]);
         }
         return Arrays.asList(keys);
     }
@@ -341,7 +340,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(store, base).getEntries(key, value);
+            return reader.readMap(base).getEntries(key, value);
         }
 
         int size = getSize(head);
@@ -374,8 +373,8 @@ public class MapRecord extends Record {
             } else {
                 value = segment.readRecordId(getOffset(4 + size * 4, i * 2 + 
1));
             }
-            String name = store.getReader().readString(key);
-            entries[i] = new MapEntry(store, name, key, value);
+            String name = reader.readString(key);
+            entries[i] = new MapEntry(reader, name, key, value);
         }
         return Arrays.asList(entries);
     }
@@ -390,9 +389,9 @@ public class MapRecord extends Record {
         if (isDiff(head)) {
             int hash = segment.readInt(getOffset(4));
             RecordId keyId = segment.readRecordId(getOffset(8));
-            final String key = store.getReader().readString(keyId);
+            final String key = reader.readString(keyId);
             final RecordId value = segment.readRecordId(getOffset(8, 1));
-            MapRecord base = new MapRecord(store, 
segment.readRecordId(getOffset(8, 2)));
+            MapRecord base = reader.readMap(segment.readRecordId(getOffset(8, 
2)));
 
             boolean rv = base.compare(before, new DefaultNodeStateDiff() {
                 @Override
@@ -416,12 +415,12 @@ public class MapRecord extends Record {
                 if (beforeEntry == null) {
                     rv = diff.childNodeAdded(
                             key,
-                            new SegmentNodeState(store, value));
+                            reader.readNode(value));
                 } else if (!value.equals(beforeEntry.getValue())) {
                     rv = diff.childNodeChanged(
                             key,
                             beforeEntry.getNodeState(),
-                            new SegmentNodeState(store, value));
+                            reader.readNode(value));
                 }
             }
             return rv;
@@ -432,9 +431,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 = store.getReader().readString(keyId);
+            final String key = reader.readString(keyId);
             final RecordId value = 
beforeSegment.readRecordId(before.getOffset(8, 1));
-            MapRecord base = new MapRecord(store, 
beforeSegment.readRecordId(before.getOffset(8, 2)));
+            MapRecord base = 
reader.readMap(beforeSegment.readRecordId(before.getOffset(8, 2)));
 
             boolean rv = this.compare(base, new DefaultNodeStateDiff() {
                 @Override
@@ -458,11 +457,11 @@ public class MapRecord extends Record {
                 if (afterEntry == null) {
                     rv = diff.childNodeDeleted(
                             key,
-                            new SegmentNodeState(store, value));
+                            reader.readNode(value));
                 } else if (!value.equals(afterEntry.getValue())) {
                     rv = diff.childNodeChanged(
                             key,
-                            new SegmentNodeState(store, value),
+                            reader.readNode(value),
                             afterEntry.getNodeState());
                 }
             }

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -58,8 +58,8 @@ public class RecordUsageAnalyser extends
     private long templateCount;
     private long nodeCount;
 
-    public RecordUsageAnalyser(@Nonnull SegmentStore store) {
-        super(store);
+    public RecordUsageAnalyser(@Nonnull SegmentReader reader) {
+        super(reader);
     }
 
     /**

Copied: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Revisions.java
 (from r1746408, 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java)
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Revisions.java?p2=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Revisions.java&p1=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java&r1=1746408&r2=1746410&rev=1746410&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentReader.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Revisions.java
 Wed Jun  1 07:48:51 2016
@@ -21,19 +21,25 @@ package org.apache.jackrabbit.oak.segmen
 
 import javax.annotation.Nonnull;
 
-import org.apache.jackrabbit.oak.cache.CacheStats;
+import com.google.common.base.Function;
 
-public interface SegmentReader {
-    @Nonnull
-    String readString(@Nonnull RecordId id);
-
-    @Nonnull
-    MapRecord readMap(@Nonnull RecordId id);
+public interface Revisions {
+    interface Option {}
 
+    /**
+     * Returns the record id of the head state.
+     * @return od of the head state
+     */
     @Nonnull
-    Template readTemplate(@Nonnull RecordId id);
+    RecordId getHead();
 
-    // FIXME OAK-4373 remove from this interface
-    @Nonnull
-    CacheStats getStringCacheStats();
+    boolean setHead(@Nonnull RecordId base,
+                    @Nonnull RecordId head,
+                    @Nonnull Option... options);
+
+    boolean setHead(@Nonnull Function<RecordId, RecordId> newHead,
+                    @Nonnull Option... options)
+    throws InterruptedException;
 }
+
+

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -125,7 +125,10 @@ public class Segment {
     public static final int GC_GENERATION_OFFSET = 10;
 
     @Nonnull
-    private final SegmentStore store;
+    private final SegmentTracker tracker;
+
+    @Nonnull
+    private final SegmentReader reader;
 
     @Nonnull
     private final SegmentId id;
@@ -186,10 +189,12 @@ public class Segment {
         return (address + boundary - 1) & ~(boundary - 1);
     }
 
-    public Segment(@Nonnull SegmentStore store,
+    public Segment(@Nonnull SegmentTracker tracker,
+                   @Nonnull SegmentReader reader,
                    @Nonnull final SegmentId id,
                    @Nonnull final ByteBuffer data) {
-        this.store = checkNotNull(store);
+        this.tracker = checkNotNull(tracker);
+        this.reader = checkNotNull(reader);
         this.id = checkNotNull(id);
 
         if (DISABLE_TEMPLATE_CACHE) {
@@ -232,9 +237,13 @@ public class Segment {
         }
     }
 
-    Segment(@Nonnull SegmentStore store, @Nonnull byte[] buffer, @Nonnull 
String info) {
-        this.store = checkNotNull(store);
-        this.id = store.getTracker().newDataSegmentId();
+    Segment(@Nonnull SegmentTracker tracker,
+            @Nonnull SegmentReader reader,
+            @Nonnull byte[] buffer,
+            @Nonnull String info) {
+        this.tracker = checkNotNull(tracker);
+        this.reader = checkNotNull(reader);
+        this.id = tracker.newDataSegmentId();
         this.info = checkNotNull(info);
         if (DISABLE_TEMPLATE_CACHE) {
             templates = null;
@@ -361,7 +370,7 @@ public class Segment {
                     int refpos = data.position() + index * 16;
                     long msb = data.getLong(refpos);
                     long lsb = data.getLong(refpos + 8);
-                    refid = store.getTracker().getSegmentId(msb, lsb);
+                    refid = tracker.getSegmentId(msb, lsb);
                     refids[index] = refid;
                 }
             }
@@ -392,7 +401,7 @@ public class Segment {
 
         for (int i = 0; i < blobrefcount; i++) {
             int offset = (data.getShort(blobrefpos + i * 2) & 0xffff) << 
RECORD_ALIGN_BITS;
-            collector.addReference(readBlobId(store, this, offset), null);
+            collector.addReference(readBlobId(this, offset), null);
         }
     }
 
@@ -482,7 +491,7 @@ public class Segment {
         if (hasPrimaryType) {
             RecordId primaryId = readRecordId(offset);
             primaryType = PropertyStates.createProperty(
-                    "jcr:primaryType", 
store.getReader().readString(primaryId), Type.NAME);
+                    "jcr:primaryType", reader.readString(primaryId), 
Type.NAME);
             offset += RECORD_ID_BYTES;
         }
 
@@ -491,7 +500,7 @@ public class Segment {
             String[] mixins = new String[mixinCount];
             for (int i = 0; i < mixins.length; i++) {
                 RecordId mixinId = readRecordId(offset);
-                mixins[i] =  store.getReader().readString(mixinId);
+                mixins[i] =  reader.readString(mixinId);
                 offset += RECORD_ID_BYTES;
             }
             mixinTypes = PropertyStates.createProperty(
@@ -503,13 +512,13 @@ public class Segment {
             childName = Template.MANY_CHILD_NODES;
         } else if (!zeroChildNodes) {
             RecordId childNameId = readRecordId(offset);
-            childName = store.getReader().readString(childNameId);
+            childName = reader.readString(childNameId);
             offset += RECORD_ID_BYTES;
         }
 
         PropertyTemplate[] properties;
         properties = readProps(propertyCount, offset);
-        return new Template(store, primaryType, mixinTypes, properties, 
childName);
+        return new Template(reader, primaryType, mixinTypes, properties, 
childName);
     }
 
     private PropertyTemplate[] readProps(int propertyCount, int offset) {
@@ -521,7 +530,7 @@ public class Segment {
             for (int i = 0; i < propertyCount; i++) {
                 byte type = readByte(offset++);
                 properties[i] = new PropertyTemplate(i,
-                        
store.getReader().readString(propertyNames.getEntry(i)), Type.fromTag(
+                        reader.readString(propertyNames.getEntry(i)), 
Type.fromTag(
                                 Math.abs(type), type < 0));
             }
         }
@@ -590,7 +599,7 @@ public class Segment {
                     int offset = data.getShort(pos + blobrefid * 2) & 0xffff;
                     writer.format(
                             "blobref %d: %s at %04x%n", blobrefid,
-                            readBlobId(store, this, offset << 
RECORD_ALIGN_BITS), offset);
+                            readBlobId(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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -19,7 +19,6 @@
 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;
@@ -32,8 +31,10 @@ import java.util.Set;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.plugins.blob.BlobStoreBlob;
 import org.apache.jackrabbit.oak.plugins.memory.AbstractBlob;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 
@@ -42,8 +43,8 @@ import org.apache.jackrabbit.oak.spi.blo
  */
 public class SegmentBlob extends Record implements Blob {
 
-    @Nonnull
-    private final SegmentStore store;
+    @CheckForNull
+    private final BlobStore blobStore;
 
     public static Iterable<SegmentId> getBulkSegmentIds(Blob blob) {
         if (blob instanceof SegmentBlob) {
@@ -53,9 +54,9 @@ public class SegmentBlob extends Record
         }
     }
 
-    SegmentBlob(@Nonnull SegmentStore store, @Nonnull RecordId id) {
+    SegmentBlob(@Nullable BlobStore blobStore, @Nonnull RecordId id) {
         super(id);
-        this.store = checkNotNull(store);
+        this.blobStore = blobStore;
     }
 
     private InputStream getInlineStream(
@@ -89,7 +90,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(store, segment, offset));
+            return getNewStream(readLongBlobId(segment, offset));
         } else {
             throw new IllegalStateException(String.format(
                     "Unexpected value record type: %02x", head & 0xff));
@@ -115,7 +116,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(store, segment, offset));
+            return getLength(readLongBlobId(segment, offset));
         } else {
             throw new IllegalStateException(String.format(
                     "Unexpected value record type: %02x", head & 0xff));
@@ -127,7 +128,6 @@ public class SegmentBlob extends Record
     public String getReference() {
         String blobId = getBlobId();
         if (blobId != null) {
-            BlobStore blobStore = store.getBlobStore();
             if (blobStore != null) {
                 return blobStore.getReference(blobId);
             } else {
@@ -158,18 +158,18 @@ public class SegmentBlob extends Record
 
     @CheckForNull
     public String getBlobId() {
-        return readBlobId(store, getSegment(), getOffset());
+        return readBlobId(getSegment(), getOffset());
     }
 
     @CheckForNull
-    static String readBlobId(@Nonnull SegmentStore store, @Nonnull Segment 
segment, int offset) {
+    static String readBlobId(@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(store, segment, offset);
+            return readLongBlobId(segment, offset);
         } else {
             return null;
         }
@@ -212,9 +212,9 @@ public class SegmentBlob extends Record
         return new String(bytes, UTF_8);
     }
 
-    private static String readLongBlobId(SegmentStore store, Segment segment, 
int offset) {
-        RecordId blobIdRecordId = segment.readRecordId(offset + 1);
-        return store.getReader().readString(blobIdRecordId);
+    private static String readLongBlobId(Segment segment, int offset) {
+        RecordId blobId = segment.readRecordId(offset + 1);
+        return blobId.getSegment().readString(blobId.getOffset());
     }
 
     private List<RecordId> getBulkRecordIds() {
@@ -247,7 +247,11 @@ public class SegmentBlob extends Record
     }
 
     private Blob getBlob(String blobId) {
-        return store.readBlob(blobId);
+        if (blobStore != null) {
+            return new BlobStoreBlob(blobStore, blobId);
+        }
+        throw new IllegalStateException("Attempt to read external blob with 
blobId [" + blobId + "] " +
+                "without specifying BlobStore");
     }
 
     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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -44,6 +44,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,16 +79,25 @@ public class SegmentBufferWriter impleme
      */
     private final List<RecordId> blobrefs = newArrayList();
 
+    @Nonnull
     private final SegmentStore store;
 
+    @Nonnull
+    private final SegmentTracker tracker;
+
+    @Nonnull
+    private final SegmentReader reader;
+
     /**
      * Version of the segment storage format.
      */
+    @Nonnull
     private final SegmentVersion version;
 
     /**
      * Id of this writer.
      */
+    @Nonnull
     private final String wid;
 
     private final int generation;
@@ -110,9 +122,16 @@ public class SegmentBufferWriter impleme
      */
     private int position;
 
-    public SegmentBufferWriter(SegmentStore store, SegmentVersion version, 
String wid, int generation) {
-        this.store = store;
-        this.version = version;
+    public SegmentBufferWriter(@Nonnull SegmentStore store,
+                               @Nonnull SegmentTracker tracker,
+                               @Nonnull SegmentReader reader,
+                               @Nonnull SegmentVersion version,
+                               @CheckForNull String wid,
+                               int generation) {
+        this.store = checkNotNull(store);
+        this.tracker = checkNotNull(tracker);
+        this.reader = checkNotNull(reader);
+        this.version = checkNotNull(version);
         this.wid = (wid == null
                 ? "w-" + identityHashCode(this)
                 : wid);
@@ -162,10 +181,10 @@ public class SegmentBufferWriter impleme
 
         String metaInfo =
             "{\"wid\":\"" + wid + '"' +
-            ",\"sno\":" + store.getTracker().getSegmentCount() +
+            ",\"sno\":" + tracker.getSegmentCount() +
             ",\"t\":" + currentTimeMillis() + "}";
         try {
-            segment = new Segment(store, buffer, metaInfo);
+            segment = new Segment(tracker, reader, buffer, metaInfo);
             byte[] data = metaInfo.getBytes(UTF_8);
             RecordWriters.newValueWriter(data.length, data).write(this);
         } catch (IOException e) {

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -34,7 +34,6 @@ 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,
@@ -49,6 +48,12 @@ public class SegmentBufferWriterPool imp
     private final SegmentStore store;
 
     @Nonnull
+    private final SegmentTracker tracker;
+
+    @Nonnull
+    private final SegmentReader reader;
+
+    @Nonnull
     private final Supplier<Integer> gcGeneration;
 
     @Nonnull
@@ -61,22 +66,19 @@ public class SegmentBufferWriterPool imp
 
     public SegmentBufferWriterPool(
             @Nonnull SegmentStore store,
+            @Nonnull SegmentTracker tracker,
+            @Nonnull SegmentReader reader,
             @Nonnull SegmentVersion version,
             @Nonnull String wid,
             @Nonnull Supplier<Integer> gcGeneration) {
         this.store = checkNotNull(store);
+        this.tracker = checkNotNull(tracker);
+        this.reader = checkNotNull(reader);
         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());
@@ -107,10 +109,10 @@ public class SegmentBufferWriterPool imp
     private synchronized SegmentBufferWriter borrowWriter(Object key) {
         SegmentBufferWriter writer = writers.remove(key);
         if (writer == null) {
-            writer = new SegmentBufferWriter(store, version, getWriterId(wid), 
gcGeneration.get());
+            writer = new SegmentBufferWriter(store, tracker, reader, version, 
getWriterId(wid), gcGeneration.get());
         } else if (writer.getGeneration() != gcGeneration.get()) {
             disposed.add(writer);
-            writer = new SegmentBufferWriter(store, version, getWriterId(wid), 
gcGeneration.get());
+            writer = new SegmentBufferWriter(store, tracker, reader, version, 
getWriterId(wid), gcGeneration.get());
         }
         borrowed.add(writer);
         return writer;

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -160,13 +160,12 @@ public final class SegmentGraph {
         checkNotNull(epoch);
         PrintWriter writer = new PrintWriter(checkNotNull(out));
         try {
-            SegmentNodeState root = checkNotNull(fileStore).getHead();
-
+            SegmentNodeState root = 
checkNotNull(fileStore).getReader().readHeadState();
             Predicate<UUID> filter = pattern == null
                 ? Predicates.<UUID>alwaysTrue()
                 : createRegExpFilter(pattern, fileStore.getTracker());
             Graph<UUID> segmentGraph = parseSegmentGraph(fileStore, filter);
-            Graph<UUID> headGraph = parseHeadGraph(fileStore, 
root.getRecordId());
+            Graph<UUID> headGraph = parseHeadGraph(fileStore.getReader(), 
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()) {
@@ -233,7 +232,7 @@ public final class SegmentGraph {
     public static Graph<UUID> parseSegmentGraph(
             @Nonnull ReadOnlyStore fileStore,
             @Nonnull Predicate<UUID> filter) throws IOException {
-        SegmentNodeState root = checkNotNull(fileStore).getHead();
+        SegmentNodeState root = 
checkNotNull(fileStore).getReader().readHeadState();
         HashSet<UUID> roots = newHashSet(root.getRecordId().asUUID());
         return parseSegmentGraph(fileStore, roots, filter, 
Functions.<UUID>identity());
     }
@@ -286,7 +285,7 @@ public final class SegmentGraph {
     @Nonnull
     public static Graph<String> parseGCGraph(@Nonnull final ReadOnlyStore 
fileStore)
             throws IOException {
-        SegmentNodeState root = checkNotNull(fileStore).getHead();
+        SegmentNodeState root = 
checkNotNull(fileStore).getReader().readHeadState();
         HashSet<UUID> roots = newHashSet(root.getRecordId().asUUID());
         return parseSegmentGraph(fileStore, roots, 
Predicates.<UUID>alwaysTrue(), new Function<UUID, String>() {
             @Override @Nullable
@@ -349,18 +348,20 @@ public final class SegmentGraph {
     }
 
     /**
-     * Parser the head graph of a {@code store}. The head graph is the sub 
graph of the segment
+     * Parser the head graph of segment store. The head graph is the sub graph 
of the segment
      * graph containing the {@code root}.
-     * @param store
+     * @param reader  segment reader for the store to parse
      * @param root
      * @return  the head graph of {@code root}.
      */
     @Nonnull
-    public static Graph<UUID> parseHeadGraph(@Nonnull SegmentStore store, 
@Nonnull RecordId root) {
+    public static Graph<UUID> parseHeadGraph(
+            @Nonnull SegmentReader reader,
+            @Nonnull RecordId root) {
         final Graph<UUID> graph = new Graph<UUID>();
 
         try {
-            new SegmentParser(store) {
+            new SegmentParser(reader) {
                 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/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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.segmen
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Suppliers.memoize;
 import static com.google.common.collect.Lists.newArrayListWithCapacity;
 import static java.util.Collections.emptyList;
 import static java.util.Collections.singletonList;
@@ -43,6 +44,8 @@ import java.util.UUID;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
@@ -58,15 +61,29 @@ import org.apache.jackrabbit.oak.spi.sta
  */
 public class SegmentNodeState extends Record implements NodeState {
     @Nonnull
-    private final SegmentStore store;
+    private final SegmentReader reader;
+
+    @Nonnull
+    private final Supplier<SegmentWriter> writer;
 
     private volatile RecordId templateId = null;
 
     private volatile Template template = null;
 
-    public SegmentNodeState(@Nonnull SegmentStore store, @Nonnull RecordId id) 
{
+    SegmentNodeState(
+            @Nonnull SegmentReader reader,
+            @Nonnull Supplier<SegmentWriter> writer,
+            @Nonnull RecordId id) {
         super(id);
-        this.store = checkNotNull(store);
+        this.reader = checkNotNull(reader);
+        this.writer = checkNotNull(memoize(writer));
+    }
+
+    SegmentNodeState(
+            @Nonnull SegmentReader reader,
+            @Nonnull SegmentWriter writer,
+            @Nonnull RecordId id) {
+        this(reader, Suppliers.ofInstance(writer), id);
     }
 
     RecordId getTemplateId() {
@@ -82,14 +99,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 = store.getReader().readTemplate(getTemplateId());
+            template = reader.readTemplate(getTemplateId());
         }
         return template;
     }
 
     MapRecord getChildNodeMap() {
         Segment segment = getSegment();
-        return store.getReader().readMap(segment.readRecordId(getOffset(0, 
2)));
+        return reader.readMap(segment.readRecordId(getOffset(0, 2)));
     }
 
     /**
@@ -163,7 +180,7 @@ public class SegmentNodeState extends Re
         if (propertyTemplate != null) {
             Segment segment = getSegment();
             RecordId id = getRecordId(segment, template, propertyTemplate);
-            return new SegmentPropertyState(store, id, propertyTemplate);
+            return reader.readProperty(id, propertyTemplate);
         } else {
             return null;
         }
@@ -210,7 +227,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(store, propertyId, 
propertyTemplates[i]));
+                list.add(reader.readProperty(propertyId, 
propertyTemplates[i]));
             }
         }
 
@@ -289,7 +306,7 @@ public class SegmentNodeState extends Re
 
         Segment segment = getSegment();
         RecordId id = getRecordId(segment, template, propertyTemplate);
-        return store.getReader().readString(id);
+        return reader.readString(id);
     }
 
     /**
@@ -335,13 +352,13 @@ public class SegmentNodeState extends Re
 
         id = segment.readRecordId(id.getOffset() + 4);
         if (size == 1) {
-            return singletonList(store.getReader().readString(id));
+            return singletonList(reader.readString(id));
         }
 
         List<String> values = newArrayListWithCapacity(size);
         ListRecord list = new ListRecord(id, size);
         for (RecordId value : list.getEntries()) {
-            values.add(store.getReader().readString(value));
+            values.add(reader.readString(value));
         }
         return values;
     }
@@ -382,7 +399,7 @@ public class SegmentNodeState extends Re
                 && childName.equals(name)) {
             Segment segment = getSegment();
             RecordId childNodeId = segment.readRecordId(getOffset(0, 2));
-            return new SegmentNodeState(store, childNodeId);
+            return reader.readNode(childNodeId);
         }
         checkValidName(name);
         return MISSING_NODE;
@@ -411,13 +428,13 @@ public class SegmentNodeState extends Re
             Segment segment = getSegment();
             RecordId childNodeId = segment.readRecordId(getOffset(0, 2));
             return Collections.singletonList(new MemoryChildNodeEntry(
-                    childName, new SegmentNodeState(store, childNodeId)));
+                    childName, reader.readNode(childNodeId)));
         }
     }
 
     @Override @Nonnull
     public SegmentNodeBuilder builder() {
-        return new SegmentNodeBuilder(this, store.getWriter());
+        return new SegmentNodeBuilder(this, writer.get());
     }
 
     @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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -45,10 +45,12 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.blob.BlobStoreBlob;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.commit.ChangeDispatcher;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
@@ -71,11 +73,30 @@ import org.slf4j.LoggerFactory;
 public class SegmentNodeStore implements NodeStore, Observable {
 
     public static class SegmentNodeStoreBuilder {
-        private final SegmentStore store;
+
+        @Nonnull
+        private final Revisions revisions;
+
+        @Nonnull
+        private final SegmentReader reader;
+
+        @Nonnull
+        private final SegmentWriter writer;
+
+        @CheckForNull
+        private final BlobStore blobStore;
+
         private boolean isCreated;
 
-        private SegmentNodeStoreBuilder(@Nonnull SegmentStore store) {
-            this.store = store;
+        private SegmentNodeStoreBuilder(
+                @Nonnull Revisions revisions,
+                @Nonnull SegmentReader reader,
+                @Nonnull SegmentWriter writer,
+                @Nullable BlobStore blobStore) {
+            this.revisions = revisions;
+            this.reader = reader;
+            this.writer = writer;
+            this.blobStore = blobStore;
         }
 
         @Nonnull
@@ -87,8 +108,13 @@ public class SegmentNodeStore implements
     }
 
     @Nonnull
-    public static SegmentNodeStoreBuilder builder(@Nonnull SegmentStore store) 
{
-        return new SegmentNodeStoreBuilder(checkNotNull(store));
+    public static SegmentNodeStoreBuilder builder(
+            @Nonnull Revisions revisions,
+            @Nonnull SegmentReader reader,
+            @Nonnull SegmentWriter writer,
+            @Nullable BlobStore blobStore) {
+        return new SegmentNodeStoreBuilder(checkNotNull(revisions),
+                checkNotNull(reader), checkNotNull(writer), blobStore);
     }
 
     private static final Logger log = 
LoggerFactory.getLogger(SegmentNodeStore.class);
@@ -97,7 +123,17 @@ public class SegmentNodeStore implements
 
     public static final String CHECKPOINTS = "checkpoints";
 
-    private final SegmentStore store;
+    @Nonnull
+    private final SegmentReader reader;
+
+    @Nonnull
+    private final SegmentWriter writer;
+
+    @Nonnull
+    private final Revisions revisions;
+
+    @CheckForNull
+    private final BlobStore blobStore;
 
     private final ChangeDispatcher changeDispatcher;
 
@@ -133,8 +169,11 @@ public class SegmentNodeStore implements
             log.info("initializing SegmentNodeStore with the commitFairLock 
option enabled.");
         }
         this.commitSemaphore = new Semaphore(1, COMMIT_FAIR_LOCK);
-        this.store = builder.store;
-        this.head = new AtomicReference<SegmentNodeState>(store.getHead());
+        this.revisions = builder.revisions;
+        this.reader = builder.reader;
+        this.writer = builder.writer;
+        this.blobStore = builder.blobStore;
+        this.head = new 
AtomicReference<SegmentNodeState>(reader.readHeadState());
         this.changeDispatcher = new ChangeDispatcher(getRoot());
     }
 
@@ -194,7 +233,7 @@ public class SegmentNodeStore implements
      * permit from the {@link #commitSemaphore}.
      */
     private void refreshHead() {
-        SegmentNodeState state = store.getHead();
+        SegmentNodeState state = reader.readHeadState();
         if (!state.getRecordId().equals(head.get().getRecordId())) {
             head.set(state);
             changeDispatcher.contentChanged(state.getChildNode(ROOT), null);
@@ -291,7 +330,7 @@ public class SegmentNodeStore implements
 
     @Override
     public Blob createBlob(InputStream stream) throws IOException {
-        return store.getWriter().writeStream(stream);
+        return writer.writeStream(stream);
     }
 
     @Override
@@ -300,11 +339,10 @@ public class SegmentNodeStore implements
         //a blob reference refers to the secure reference obtained from 
Blob#getReference()
         //However in SegmentStore terminology a blob is referred via 'external 
reference'
         //That 'external reference' would map to blobId obtained from 
BlobStore#getBlobId
-        BlobStore blobStore = store.getBlobStore();
         if (blobStore != null) {
             String blobId = blobStore.getBlobId(reference);
             if (blobId != null) {
-                return store.readBlob(blobId);
+                return new BlobStoreBlob(blobStore, blobId);
             }
             return null;
         }
@@ -376,7 +414,7 @@ public class SegmentNodeStore implements
             cp.setChildNode(ROOT, state.getChildNode(ROOT));
 
             SegmentNodeState newState = builder.getNodeState();
-            if (store.setHead(state, newState)) {
+            if (revisions.setHead(state.getRecordId(), 
newState.getRecordId())) {
                 refreshHead();
                 return true;
             } else {
@@ -438,7 +476,7 @@ public class SegmentNodeStore implements
                     if (cp.exists()) {
                         cp.remove();
                         SegmentNodeState newState = builder.getNodeState();
-                        if (store.setHead(state, newState)) {
+                        if (revisions.setHead(state.getRecordId(), 
newState.getRecordId())) {
                             refreshHead();
                             return true;
                         }
@@ -479,7 +517,7 @@ public class SegmentNodeStore implements
 
         private boolean setHead(SegmentNodeState before, SegmentNodeState 
after) {
             refreshHead();
-            if (store.setHead(before, after)) {
+            if (revisions.setHead(before.getRecordId(), after.getRecordId())) {
                 head.set(after);
                 changeDispatcher.contentChanged(after.getChildNode(ROOT), 
info);
                 refreshHead();

Added: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreBuilders.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreBuilders.java?rev=1746410&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreBuilders.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreBuilders.java
 Wed Jun  1 07:48:51 2016
@@ -0,0 +1,49 @@
+/*
+ * 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 javax.annotation.Nonnull;
+
+import 
org.apache.jackrabbit.oak.segment.SegmentNodeStore.SegmentNodeStoreBuilder;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.segment.http.HttpStore;
+import org.apache.jackrabbit.oak.segment.memory.MemoryStore;
+
+public final class SegmentNodeStoreBuilders {
+    private SegmentNodeStoreBuilders() {}
+
+    @Nonnull
+    public static SegmentNodeStoreBuilder builder(@Nonnull FileStore store) {
+        return SegmentNodeStore.builder(store.getRevisions(),
+                store.getReader(), store.getWriter(), store.getBlobStore());
+    }
+
+    @Nonnull
+    public static SegmentNodeStoreBuilder builder(@Nonnull MemoryStore store) {
+        return SegmentNodeStore.builder(store.getRevisions(),
+                store.getReader(), store.getWriter(), store.getBlobStore());
+    }
+
+    @Nonnull
+    public static SegmentNodeStoreBuilder builder(@Nonnull HttpStore store) {
+        return SegmentNodeStore.builder(store.getRevisions(),
+                store.getReader(), store.getWriter(), store.getBlobStore());
+    }
+}

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -371,7 +371,7 @@ public class SegmentNodeStoreService ext
 
         // Expose stats about the string cache, if available
 
-        CacheStats stringCacheStats = store.getReader().getStringCacheStats();
+        CacheStats stringCacheStats = store.getStringCacheStats();
         stringCacheMBean = registerMBean(
                 whiteboard,
                 CacheStatsMBean.class,
@@ -459,7 +459,7 @@ public class SegmentNodeStoreService ext
 
         OsgiWhiteboard whiteboard = new 
OsgiWhiteboard(context.getBundleContext());
 
-        segmentNodeStore = SegmentNodeStore.builder(store).build();
+        segmentNodeStore = SegmentNodeStoreBuilders.builder(store).build();
 
         observerTracker = new ObserverTracker(segmentNodeStore);
         observerTracker.start(context.getBundleContext());

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=1746410&r1=1746409&r2=1746410&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
 Wed Jun  1 07:48:51 2016
@@ -258,10 +258,10 @@ public class SegmentParser {
     }
 
     @Nonnull
-    private final SegmentStore store;
+    private final SegmentReader reader;
 
-    public SegmentParser(@Nonnull SegmentStore store) {
-        this.store = checkNotNull(store);
+    public SegmentParser(@Nonnull SegmentReader reader) {
+        this.reader = checkNotNull(reader);
     }
 
     /**
@@ -423,17 +423,17 @@ public class SegmentParser {
 
         Segment segment = nodeId.getSegment();
         int offset = nodeId.getOffset();
-        String stableId = new SegmentNodeState(store, nodeId).getStableId();
+        String stableId = reader.readNode(nodeId).getStableId();
         offset += RECORD_ID_BYTES;
         RecordId templateId = segment.readRecordId(offset);
         onTemplate(nodeId, templateId);
 
-        Template template = store.getReader().readTemplate(templateId);
+        Template template = reader.readTemplate(templateId);
 
         // Recurses into child nodes in this segment
         if (template.getChildName() == MANY_CHILD_NODES) {
             RecordId childMapId = segment.readRecordId(offset + 
RECORD_ID_BYTES);
-            MapRecord childMap = store.getReader().readMap(childMapId);
+            MapRecord childMap = reader.readMap(childMapId);
             onMap(nodeId, childMapId, childMap);
             for (ChildNodeEntry childNodeEntry : childMap.getEntries()) {
                 NodeState child = childNodeEntry.getNodeState();
@@ -558,7 +558,7 @@ public class SegmentParser {
 
         RecordId baseId = mapId.getSegment()
                 .readRecordId(mapId.getOffset() + 8 + 2 * RECORD_ID_BYTES);
-        onMap(mapId, baseId, store.getReader().readMap(baseId));
+        onMap(mapId, baseId, reader.readMap(baseId));
 
         return new MapInfo(mapId, size);
     }



Reply via email to