Author: tomekr
Date: Mon Nov 20 11:22:55 2017
New Revision: 1815789

URL: http://svn.apache.org/viewvc?rev=1815789&view=rev
Log:
OAK-6066: Migration of binaries relies on implementation details of the TarMK

Modified:
    
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/BlobMigrator.java
    
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/DepthFirstNodeIterator.java
    
jackrabbit/oak/trunk/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/AbstractMigratorTest.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/DepthFirstNodeIteratorTest.java

Modified: 
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/BlobMigrator.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/BlobMigrator.java?rev=1815789&r1=1815788&r2=1815789&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/BlobMigrator.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/BlobMigrator.java
 Mon Nov 20 11:22:55 2017
@@ -70,16 +70,19 @@ public class BlobMigrator {
     public BlobMigrator(SplitBlobStore blobStore, NodeStore nodeStore) {
         this.blobStore = blobStore;
         this.nodeStore = nodeStore;
-        refreshAndReset();
     }
 
     public boolean start() throws IOException {
         totalMigratedNodes = 0;
-        refreshAndReset();
+        refreshAndReset(nodeStore.getRoot());
         return migrate();
     }
 
     public boolean migrate() throws IOException {
+        if (nodeIterator == null) {
+            refreshAndReset(nodeStore.getRoot());
+        }
+
         do {
             while (nodeIterator.hasNext()) {
                 lastPath = nodeIterator.getPath();
@@ -104,15 +107,19 @@ public class BlobMigrator {
 
     private boolean tryCommit() {
         try {
-            nodeStore.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+            NodeState newRoot = nodeStore.merge(rootBuilder, 
EmptyHook.INSTANCE, CommitInfo.EMPTY);
             totalMigratedNodes += migratedNodes;
             log.info("{} nodes merged succesfully. Nodes migrated in this 
session: {}", migratedNodes, totalMigratedNodes);
             lastCommit = System.currentTimeMillis();
             migratedNodes = 0;
+
+            rootBuilder = newRoot.builder();
+            nodeIterator = nodeIterator.switchRoot(newRoot);
+
             return true;
         } catch (CommitFailedException e) {
             log.error("Can't commit. Resetting the migrator", e);
-            refreshAndReset();
+            refreshAndReset(nodeStore.getRoot());
             return false;
         }
     }
@@ -141,8 +148,7 @@ public class BlobMigrator {
         return totalMigratedNodes;
     }
 
-    private void refreshAndReset() {
-        NodeState rootState = nodeStore.getRoot();
+    private void refreshAndReset(NodeState rootState) {
         rootBuilder = rootState.builder();
         nodeIterator = new DepthFirstNodeIterator(rootState);
         lastPath = null;

Modified: 
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/DepthFirstNodeIterator.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/DepthFirstNodeIterator.java?rev=1815789&r1=1815788&r2=1815789&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/DepthFirstNodeIterator.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/migration/DepthFirstNodeIterator.java
 Mon Nov 20 11:22:55 2017
@@ -29,20 +29,32 @@ import org.apache.jackrabbit.oak.spi.sta
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.AbstractIterator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DepthFirstNodeIterator extends AbstractIterator<ChildNodeEntry> {
 
-    private final Deque<Iterator<? extends ChildNodeEntry>> itQueue = new 
ArrayDeque<Iterator<? extends ChildNodeEntry>>();
+    private static final Logger log = 
LoggerFactory.getLogger(DepthFirstNodeIterator.class);
 
-    private final Deque<String> nameQueue = new ArrayDeque<String>();
+    private final Deque<Iterator<? extends ChildNodeEntry>> itQueue;
+
+    private final Deque<String> nameQueue;
 
     private final NodeState root;
 
     public DepthFirstNodeIterator(NodeState root) {
         this.root = root;
+        this.itQueue = new ArrayDeque<>();
+        this.nameQueue = new ArrayDeque<>();
         reset();
     }
 
+    private DepthFirstNodeIterator(NodeState root, Deque<Iterator<? extends 
ChildNodeEntry>> itQueue, Deque<String> nameQueue) {
+        this.root = root;
+        this.itQueue = itQueue;
+        this.nameQueue = nameQueue;
+    }
+
     public void reset() {
         itQueue.clear();
         nameQueue.clear();
@@ -81,4 +93,27 @@ public class DepthFirstNodeIterator exte
         return Joiner.on('/').appendTo(path, nameQueue).toString();
     }
 
+    public DepthFirstNodeIterator switchRoot(NodeState newRoot) {
+        Deque<Iterator<? extends ChildNodeEntry>> newQueue = new 
ArrayDeque<>();
+        NodeState current = newRoot;
+        for (String name : nameQueue) {
+            boolean found = false;
+            Iterator<? extends ChildNodeEntry> it = 
current.getChildNodeEntries().iterator();
+            newQueue.add(it);
+            while (it.hasNext()) {
+                ChildNodeEntry e = it.next();
+                if (name.equals(e.getName())) {
+                    current = e.getNodeState();
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                log.warn("Can't found {} in the new root. Switching to /", 
getPath());
+                return new DepthFirstNodeIterator(newRoot);
+            }
+        }
+        newQueue.add(current.getChildNodeEntries().iterator());
+        return new DepthFirstNodeIterator(newRoot, newQueue, nameQueue);
+    }
 }
\ No newline at end of file

Modified: 
jackrabbit/oak/trunk/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/AbstractMigratorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/AbstractMigratorTest.java?rev=1815789&r1=1815788&r2=1815789&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/AbstractMigratorTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/migration/AbstractMigratorTest.java
 Mon Nov 20 11:22:55 2017
@@ -74,6 +74,12 @@ public abstract class AbstractMigratorTe
         DefaultSplitBlobStore splitBlobStore = new 
DefaultSplitBlobStore(repository.getPath(), oldBlobStore, newBlobStore);
         nodeStore = createNodeStore(splitBlobStore, repository);
         migrator = new BlobMigrator(splitBlobStore, nodeStore);
+
+        // see OAK-6066
+        NodeBuilder builder = nodeStore.getRoot().builder();
+        builder.setProperty("foo", "bar");
+        nodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
     }
 
     protected abstract NodeStore createNodeStore(BlobStore blobStore, File 
repository) throws IOException;

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/DepthFirstNodeIteratorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/DepthFirstNodeIteratorTest.java?rev=1815789&r1=1815788&r2=1815789&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/DepthFirstNodeIteratorTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/migration/DepthFirstNodeIteratorTest.java
 Mon Nov 20 11:22:55 2017
@@ -96,4 +96,29 @@ public class DepthFirstNodeIteratorTest
         }
         assertTrue(nameToPath.isEmpty());
     }
+
+    @Test
+    public void testSwitchRoot() {
+        Map<String, String[]> subtrees = new HashMap<String, String[]>();
+        subtrees.put("uk", new String[] { "cities", "london", "districts", 
"frognal" });
+        subtrees.put("germany", new String[] {});
+        subtrees.put("france", new String[] { "cities", "paris" });
+
+        DepthFirstNodeIterator iterator = new 
DepthFirstNodeIterator(store.getRoot());
+        assertTrue(iterator.hasNext());
+        assertEquals("countries", iterator.next().getName());
+
+        for (int i = 0; i < 3; i++) {
+            assertTrue(iterator.hasNext());
+            String country = iterator.next().getName();
+            for (String node : subtrees.remove(country)) {
+                assertTrue(iterator.hasNext());
+                assertEquals(node, iterator.next().getName());
+                iterator = iterator.switchRoot(store.getRoot());
+            }
+        }
+        assertFalse(iterator.hasNext());
+        assertTrue(subtrees.isEmpty());
+    }
+
 }


Reply via email to