Author: tomekr
Date: Sun Aug 27 16:58:21 2017
New Revision: 1806378

URL: http://svn.apache.org/viewvc?rev=1806378&view=rev
Log:
OAK-6560: Sidegrade uses too much memory

Added:
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/plugins/segment/
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointAccessor.java
      - copied, changed from r1806367, 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/segment/
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/segment/CheckpointAccessor.java
      - copied, changed from r1806367, 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistingDiff.java
Removed:
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
Modified:
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/checkpoint/CheckpointRetriever.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
    
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentTarFactory.java

Copied: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointAccessor.java
 (from r1806367, 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java)
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointAccessor.java?p2=jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointAccessor.java&p1=jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java&r1=1806367&r2=1806378&rev=1806378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointAccessor.java
 Sun Aug 27 16:58:21 2017
@@ -14,35 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.oak.upgrade.cli.node;
+package org.apache.jackrabbit.oak.plugins.segment;
 
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.apache.jackrabbit.oak.spi.state.ProxyNodeStore;
 
-public class TarNodeStore extends ProxyNodeStore {
+public final class CheckpointAccessor {
 
-    private final NodeStore ns;
-
-    private final SuperRootProvider superRootProvider;
-
-    public TarNodeStore(NodeStore ns, SuperRootProvider superRootProvider) {
-        this.ns = ns;
-        this.superRootProvider = superRootProvider;
-    }
-
-    public NodeState getSuperRoot() {
-        return superRootProvider.getSuperRoot();
+    private CheckpointAccessor() {
     }
 
-    @Override
-    protected NodeStore getNodeStore() {
-        return ns;
+    public static NodeState getCheckpointsRoot(SegmentNodeStore 
segmentNodeStore) {
+        return segmentNodeStore.getCheckpoints();
     }
 
-    interface SuperRootProvider {
-
-        NodeState getSuperRoot();
-
-    }
 }

Copied: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/segment/CheckpointAccessor.java
 (from r1806367, 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java)
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/segment/CheckpointAccessor.java?p2=jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/segment/CheckpointAccessor.java&p1=jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java&r1=1806367&r2=1806378&rev=1806378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/segment/CheckpointAccessor.java
 Sun Aug 27 16:58:21 2017
@@ -14,35 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.oak.upgrade.cli.node;
+package org.apache.jackrabbit.oak.segment;
 
 import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.apache.jackrabbit.oak.spi.state.ProxyNodeStore;
 
-public class TarNodeStore extends ProxyNodeStore {
+public final class CheckpointAccessor {
 
-    private final NodeStore ns;
-
-    private final SuperRootProvider superRootProvider;
-
-    public TarNodeStore(NodeStore ns, SuperRootProvider superRootProvider) {
-        this.ns = ns;
-        this.superRootProvider = superRootProvider;
-    }
-
-    public NodeState getSuperRoot() {
-        return superRootProvider.getSuperRoot();
+    private CheckpointAccessor() {
     }
 
-    @Override
-    protected NodeStore getNodeStore() {
-        return ns;
+    public static NodeState getCheckpointsRoot(SegmentNodeStore 
segmentNodeStore) {
+        return segmentNodeStore.getCheckpoints();
     }
 
-    interface SuperRootProvider {
-
-        NodeState getSuperRoot();
-
-    }
 }

Added: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistingDiff.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistingDiff.java?rev=1806378&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistingDiff.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/PersistingDiff.java
 Sun Aug 27 16:58:21 2017
@@ -0,0 +1,187 @@
+/*
+ * 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.upgrade;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
+import org.apache.jackrabbit.oak.segment.RecordId;
+import org.apache.jackrabbit.oak.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.segment.SegmentReader;
+import org.apache.jackrabbit.oak.segment.SegmentWriter;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static 
org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+
+public class PersistingDiff implements NodeStateDiff {
+
+    /**
+     * Number of content updates that need to happen before the updates
+     * are automatically purged to the underlying segments.
+     */
+    private static final int UPDATE_LIMIT =
+            Integer.getInteger("upgrade.update.limit", 10000);
+
+    private final SegmentWriter writer;
+
+    private final SegmentReader reader;
+
+    private final BlobStore blobStore;
+
+    @Nonnull
+    private MemoryNodeBuilder builder;
+
+    @Nonnull
+    private final NodeState base;
+
+    @CheckForNull
+    private IOException exception;
+
+    private long modCount;
+
+    private PersistingDiff(SegmentWriter writer, SegmentReader reader, 
BlobStore blobStore, @Nonnull NodeState base) {
+        this.writer = writer;
+        this.reader = reader;
+        this.blobStore = blobStore;
+        this.builder = new MemoryNodeBuilder(checkNotNull(base));
+        this.base = base;
+    }
+
+    public static SegmentNodeState applyDiffOnNodeState(
+            FileStore fileStore,
+            @Nonnull NodeState before,
+            @Nonnull NodeState after,
+            @Nonnull NodeState onto) throws IOException {
+        return new PersistingDiff(fileStore.getWriter(), 
fileStore.getReader(), fileStore.getBlobStore(), onto).diff(before, after);
+    }
+
+    private SegmentNodeState copyToSegmentNodeState(NodeState state) throws 
IOException {
+        return applyDiffOnNodeState(EMPTY_NODE, state, EMPTY_NODE);
+    }
+
+    private SegmentNodeState applyDiffOnNodeState(
+            @Nonnull NodeState before,
+            @Nonnull NodeState after,
+            @Nonnull NodeState onto) throws IOException {
+        return new PersistingDiff(writer, reader, blobStore, 
onto).diff(before, after);
+    }
+
+    private void updated() throws IOException {
+        if (++modCount % UPDATE_LIMIT == 0) {
+            RecordId newBaseId = writer.writeNode(builder.getNodeState(), 
null);
+            SegmentNodeState newBase = new SegmentNodeState(reader, writer, 
blobStore, newBaseId);
+            builder = new MemoryNodeBuilder(newBase);
+        }
+    }
+
+    @CheckForNull
+    SegmentNodeState diff(@Nonnull NodeState before, @Nonnull NodeState after) 
throws IOException {
+        boolean success = after.compareAgainstBaseState(before, this);
+        if (exception != null) {
+            throw new IOException(exception);
+        } else if (success) {
+            NodeState nodeState = builder.getNodeState();
+            checkState(modCount == 0 || !(nodeState instanceof 
SegmentNodeState));
+            RecordId nodeId = writer.writeNode(nodeState, 
getStableIdBytes(after));
+            return new SegmentNodeState(reader, writer, blobStore, nodeId);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean propertyAdded(@Nonnull PropertyState after) {
+        builder.setProperty(after);
+        return true;
+    }
+
+    @Override
+    public boolean propertyChanged(@Nonnull PropertyState before, @Nonnull 
PropertyState after) {
+        builder.setProperty(after);
+        return true;
+    }
+
+    @Override
+    public boolean propertyDeleted(PropertyState before) {
+        builder.removeProperty(before.getName());
+        return true;
+    }
+
+    @Override
+    public boolean childNodeAdded(@Nonnull String name, @Nonnull NodeState 
after) {
+        try {
+            SegmentNodeState segmentNodeState = copyToSegmentNodeState(after);
+            if (segmentNodeState != null) {
+                updated();
+                builder.setChildNode(name, segmentNodeState);
+                return true;
+            } else {
+                return false;
+            }
+        } catch (IOException e) {
+            exception = e;
+            return false;
+        }
+    }
+
+    @Override
+    public boolean childNodeChanged(@Nonnull String name, @Nonnull NodeState 
before, @Nonnull NodeState after) {
+        try {
+            SegmentNodeState compacted = applyDiffOnNodeState(before, after, 
base.getChildNode(name));
+            if (compacted != null) {
+                updated();
+                builder.setChildNode(name, compacted);
+                return true;
+            } else {
+                return false;
+            }
+        } catch (IOException e) {
+            exception = e;
+            return false;
+        }
+    }
+
+    @Override
+    public boolean childNodeDeleted(String name, NodeState before) {
+        try {
+            updated();
+            builder.getChildNode(name).remove();
+            return true;
+        } catch (IOException e) {
+            exception = e;
+            return false;
+        }
+    }
+
+    @CheckForNull
+    private static ByteBuffer getStableIdBytes(NodeState state) {
+        if (state instanceof SegmentNodeState) {
+            return ((SegmentNodeState) state).getStableIdBytes();
+        } else {
+            return null;
+        }
+    }
+}

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java?rev=1806378&r1=1806377&r2=1806378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
 Sun Aug 27 16:58:21 2017
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.upgrade;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.LinkedHashMap;
@@ -31,6 +32,8 @@ import org.apache.commons.lang.StringUti
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
@@ -43,7 +46,7 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import 
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.LoggingCompositeHook;
 import org.apache.jackrabbit.oak.upgrade.checkpoint.CheckpointRetriever;
-import org.apache.jackrabbit.oak.upgrade.cli.node.TarNodeStore;
+import org.apache.jackrabbit.oak.upgrade.cli.node.SegmentTarFactory;
 import org.apache.jackrabbit.oak.upgrade.nodestate.FilteringNodeState;
 import org.apache.jackrabbit.oak.upgrade.nodestate.MetadataExposingNodeState;
 import org.apache.jackrabbit.oak.upgrade.nodestate.NameFilteringNodeState;
@@ -89,6 +92,8 @@ public class RepositorySidegrade {
      */
     private final NodeStore target;
 
+    private final FileStore targetFileStore;
+
     private final NodeStore source;
 
     /**
@@ -180,6 +185,12 @@ public class RepositorySidegrade {
     public RepositorySidegrade(NodeStore source, NodeStore target) {
         this.source = source;
         this.target = target;
+
+        FileStore fs = null;
+        if (target instanceof SegmentTarFactory.NodeStoreWithFileStore) {
+            fs = ((SegmentTarFactory.NodeStoreWithFileStore) 
target).getFileStore();
+        }
+        this.targetFileStore = fs;
     }
 
     /**
@@ -315,7 +326,7 @@ public class RepositorySidegrade {
         builder.setChildNode(":async");
     }
 
-    private void copyState() throws CommitFailedException, RepositoryException 
{
+    private void copyState() throws CommitFailedException, 
RepositoryException, IOException {
         boolean migrateCheckpoints = true;
         if (!isCompleteMigration() && !forceCheckpoints) {
             LOG.info("Checkpoints won't be migrated because of the specified 
paths");
@@ -341,7 +352,7 @@ public class RepositorySidegrade {
         }
     }
 
-    private boolean migrateWithCheckpoints() throws CommitFailedException {
+    private boolean migrateWithCheckpoints() throws CommitFailedException, 
IOException {
         List<CheckpointRetriever.Checkpoint> checkpoints = 
CheckpointRetriever.getCheckpoints(source);
         if (checkpoints == null) {
             return false;
@@ -351,8 +362,8 @@ public class RepositorySidegrade {
         Map<String, String> checkpointSegmentToDoc = new LinkedHashMap<>();
 
         NodeState initialRoot = target.getRoot();
+        NodeState targetRoot = initialRoot;
         NodeState previousRoot = initialRoot;
-        NodeBuilder targetRoot = previousRoot.builder();
         for (CheckpointRetriever.Checkpoint checkpoint : checkpoints) {
             NodeState checkpointRoot = source.retrieve(checkpoint.getName());
             Map<String, String> checkpointInfo = 
source.checkpointInfo(checkpoint.getName());
@@ -367,11 +378,7 @@ public class RepositorySidegrade {
             }
             LOG.info("Checkpoint expiry time: {}, metadata: {}", 
checkpoint.getExpiryTime(), checkpointInfo);
 
-            NodeState currentRoot = wrapNodeState(checkpointRoot, tracePaths, 
true);
-            NodeState baseRoot = wrapNodeState(previousRoot, false, true);
-            currentRoot.compareAgainstBaseState(baseRoot, new 
ApplyDiff(targetRoot));
-
-            target.merge(targetRoot, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+            targetRoot = copyDiffToTarget(previousRoot, checkpointRoot, 
targetRoot, tracePaths);
             previousRoot = checkpointRoot;
 
             String newCheckpointName = 
target.checkpoint(checkpoint.getExpiryTime() - System.currentTimeMillis(), 
checkpointInfo);
@@ -390,13 +397,12 @@ public class RepositorySidegrade {
             LOG.info("Applying diff to head");
             tracePaths = false;
         }
-        
-        NodeState currentRoot = wrapNodeState(sourceRoot, tracePaths, true);
-        NodeState baseRoot = wrapNodeState(previousRoot, false, true);
-        currentRoot.compareAgainstBaseState(baseRoot, new 
ApplyDiff(targetRoot));
+
+        targetRoot = copyDiffToTarget(previousRoot, sourceRoot, targetRoot, 
tracePaths);
 
         LOG.info("Rewriting checkpoint names in /:async {}", nameToRevision);
-        NodeBuilder async = targetRoot.getChildNode(":async");
+        NodeBuilder targetBuilder = targetRoot.builder();
+        NodeBuilder async = targetBuilder.getChildNode(":async");
         for (Map.Entry<String, String> e : nameToRevision.entrySet()) {
             async.setProperty(e.getKey(), e.getValue(), Type.STRING);
 
@@ -412,11 +418,24 @@ public class RepositorySidegrade {
             }
             async.setProperty(e.getKey() + "-temp", tempValues, Type.STRINGS);
         }
-
-        target.merge(targetRoot, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        target.merge(targetBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
         return true;
     }
 
+    private NodeState copyDiffToTarget(NodeState before, NodeState after, 
NodeState targetRoot, boolean tracePaths) throws IOException, 
CommitFailedException {
+        NodeState currentRoot = wrapNodeState(after, tracePaths, true);
+        NodeState baseRoot = wrapNodeState(before, false, true);
+
+        NodeBuilder targetBuilder = targetRoot.builder();
+        if (targetFileStore == null) {
+            currentRoot.compareAgainstBaseState(baseRoot, new 
ApplyDiff(targetBuilder));
+        } else {
+            SegmentNodeState state = 
PersistingDiff.applyDiffOnNodeState(targetFileStore, baseRoot, currentRoot, 
targetRoot);
+            state.compareAgainstBaseState(targetRoot, new 
ApplyDiff(targetBuilder));
+        }
+        return target.merge(targetBuilder, EmptyHook.INSTANCE, 
CommitInfo.EMPTY);
+    }
+
     private void migrateWithoutCheckpoints() throws CommitFailedException, 
RepositoryException {
         final List<CommitHook> hooks = new ArrayList<>();
         if (customCommitHooks != null) {
@@ -512,16 +531,8 @@ public class RepositorySidegrade {
     }
 
     private void verify() {
-        final NodeState sourceRoot;
-        final NodeState targetRoot;
-
-        if (source instanceof TarNodeStore && target instanceof TarNodeStore) {
-            sourceRoot = ((TarNodeStore) source).getSuperRoot();
-            targetRoot = ((TarNodeStore) target).getSuperRoot();
-        } else {
-            sourceRoot = source.getRoot();
-            targetRoot = target.getRoot();
-        }
+        final NodeState sourceRoot = source.getRoot();
+        final NodeState targetRoot = target.getRoot();
 
         final NodeState reportingSource = ReportingNodeState.wrap(sourceRoot, 
new LoggingReporter(LOG, "Verifying", LOG_NODE_COPY, -1));
 
@@ -553,4 +564,5 @@ public class RepositorySidegrade {
     private boolean targetExists() {
         return target.getRoot().getChildNodeEntries().iterator().hasNext();
     }
+
 }

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/checkpoint/CheckpointRetriever.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/checkpoint/CheckpointRetriever.java?rev=1806378&r1=1806377&r2=1806378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/checkpoint/CheckpointRetriever.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/checkpoint/CheckpointRetriever.java
 Sun Aug 27 16:58:21 2017
@@ -23,10 +23,12 @@ import com.google.common.collect.Iterabl
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.oak.plugins.document.DocumentCheckpointRetriever;
 import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
+import org.apache.jackrabbit.oak.segment.CheckpointAccessor;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.apache.jackrabbit.oak.upgrade.cli.node.TarNodeStore;
+import org.apache.jackrabbit.oak.upgrade.cli.node.SegmentTarFactory;
 
 import javax.annotation.Nullable;
 import java.util.Collections;
@@ -71,10 +73,14 @@ public final class CheckpointRetriever {
 
     public static List<Checkpoint> getCheckpoints(NodeStore nodeStore) {
         List<Checkpoint> result;
-        if (nodeStore instanceof TarNodeStore) {
-            result = getCheckpoints((TarNodeStore) nodeStore);
+        if (nodeStore instanceof SegmentNodeStore) {
+            result = 
getCheckpoints(CheckpointAccessor.getCheckpointsRoot((SegmentNodeStore) 
nodeStore));
+        } else if (nodeStore instanceof 
org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore) {
+            result = 
getCheckpoints(org.apache.jackrabbit.oak.plugins.segment.CheckpointAccessor.getCheckpointsRoot((org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore)
 nodeStore));
         } else if (nodeStore instanceof DocumentNodeStore) {
             result = 
DocumentCheckpointRetriever.getCheckpoints((DocumentNodeStore) nodeStore);
+        } else if (nodeStore instanceof 
SegmentTarFactory.NodeStoreWithFileStore) {
+            result = 
getCheckpoints(CheckpointAccessor.getCheckpointsRoot(((SegmentTarFactory.NodeStoreWithFileStore)
 nodeStore).getNodeStore()));
         } else {
             return null;
         }
@@ -82,8 +88,8 @@ public final class CheckpointRetriever {
         return result;
     }
 
-    private static List<Checkpoint> getCheckpoints(TarNodeStore nodeStore) {
-        return 
Lists.newArrayList(Iterables.transform(nodeStore.getSuperRoot().getChildNode("checkpoints").getChildNodeEntries(),
 new Function<ChildNodeEntry, Checkpoint>() {
+    private static List<Checkpoint> getCheckpoints(NodeState checkpointRoot) {
+        return 
Lists.newArrayList(Iterables.transform(checkpointRoot.getChildNodeEntries(), 
new Function<ChildNodeEntry, Checkpoint>() {
             @Nullable
             @Override
             public Checkpoint apply(@Nullable ChildNodeEntry input) {
@@ -91,4 +97,4 @@ public final class CheckpointRetriever {
             }
         }));
     }
-}
+}
\ No newline at end of file

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java?rev=1806378&r1=1806377&r2=1806378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
 Sun Aug 27 16:58:21 2017
@@ -26,7 +26,6 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.segment.file.FileStore.Builder;
 import 
org.apache.jackrabbit.oak.plugins.segment.file.InvalidFileStoreVersionException;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 
 import com.google.common.io.Closer;
@@ -82,12 +81,7 @@ public class SegmentFactory implements N
         }
         closer.register(asCloseable(fs));
 
-        return new TarNodeStore(SegmentNodeStore.builder(fs).build(), new 
TarNodeStore.SuperRootProvider() {
-            @Override
-            public NodeState getSuperRoot() {
-                return fs.getHead();
-            }
-        });
+        return SegmentNodeStore.builder(fs).build();
     }
 
     @Override

Modified: 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentTarFactory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentTarFactory.java?rev=1806378&r1=1806377&r2=1806378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentTarFactory.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentTarFactory.java
 Sun Aug 27 16:58:21 2017
@@ -26,14 +26,15 @@ import com.google.common.io.Closer;
 import org.apache.jackrabbit.oak.segment.RecordType;
 import org.apache.jackrabbit.oak.segment.Segment;
 import org.apache.jackrabbit.oak.segment.SegmentId;
+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.segment.file.FileStoreBuilder;
 import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
 import org.apache.jackrabbit.oak.segment.file.ReadOnlyFileStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.spi.state.ProxyNodeStore;
 
 public class SegmentTarFactory implements NodeStoreFactory {
 
@@ -77,12 +78,12 @@ public class SegmentTarFactory implement
                 final ReadOnlyFileStore fs;
                 fs = builder.buildReadOnly();
                 closer.register(asCloseable(fs));
-                return new 
TarNodeStore(SegmentNodeStoreBuilders.builder(fs).build(), new 
SegmentTarSuperRootProvider(fs));
+                return SegmentNodeStoreBuilders.builder(fs).build();
             } else {
                 final FileStore fs;
                 fs = builder.build();
                 closer.register(asCloseable(fs));
-                return new 
TarNodeStore(SegmentNodeStoreBuilders.builder(fs).build(), new 
SegmentTarSuperRootProvider(fs));
+                return new 
NodeStoreWithFileStore(SegmentNodeStoreBuilders.builder(fs).build(), fs);
             }
         } catch (InvalidFileStoreVersionException e) {
             throw new IllegalStateException(e);
@@ -154,25 +155,24 @@ public class SegmentTarFactory implement
     private static class ExternalBlobFound extends RuntimeException {
     }
 
-    private static class SegmentTarSuperRootProvider implements 
TarNodeStore.SuperRootProvider {
+    public static class NodeStoreWithFileStore extends ProxyNodeStore {
 
-        private final ReadOnlyFileStore readOnlyFileStore;
+        private final SegmentNodeStore segmentNodeStore;
 
         private final FileStore fileStore;
 
-        public SegmentTarSuperRootProvider(ReadOnlyFileStore 
readOnlyFileStore) {
-            this.readOnlyFileStore = readOnlyFileStore;
-            this.fileStore = null;
+        public NodeStoreWithFileStore(SegmentNodeStore segmentNodeStore, 
FileStore fileStore) {
+            this.segmentNodeStore = segmentNodeStore;
+            this.fileStore = fileStore;
         }
 
-        public SegmentTarSuperRootProvider(FileStore fileStore) {
-            this.readOnlyFileStore = null;
-            this.fileStore = fileStore;
+        public FileStore getFileStore() {
+            return fileStore;
         }
 
         @Override
-        public NodeState getSuperRoot() {
-            return fileStore == null ? readOnlyFileStore.getHead() : 
fileStore.getHead();
+        public SegmentNodeStore getNodeStore() {
+            return segmentNodeStore;
         }
     }
 }


Reply via email to