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());
+ }
+
}