diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java index 61cffe0..880e940 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java @@ -163,13 +163,22 @@ public class IndexUpdate implements Editor { log.info("Reindexing will be performed for following indexes: {}", reindex.keySet()); rootState.reindexedIndexes.addAll(reindex.keySet()); - } - // no-op when reindex is empty - CommitFailedException exception = process( - wrap(wrapProgress(compose(reindex.values()), "Reindexing")), MISSING_NODE, after); - if (exception != null) { - throw exception; + System.err.println("[IU] Reindexing " + reindex.keySet()); + boolean enableOAK5499 = true; + + Editor reindexer = wrap(wrapProgress(compose(reindex.values()), "Reindexing")); + // if before == MISSING_NODE there's no need for the out-of-band + // reindexing, we can do it in the current run + if (enableOAK5499 && before == MISSING_NODE) { + editors.add(reindexer); + } else { + CommitFailedException exception = process(reindexer, MISSING_NODE, after); + if (exception != null) { + throw exception; + } + System.err.println("[IU] Reindexing done for " + reindex.keySet()); + } } for (Editor editor : editors) { @@ -368,6 +377,8 @@ public class IndexUpdate implements Editor { @Override @Nonnull public Editor childNodeAdded(String name, NodeState after) throws CommitFailedException { + System.err.println("[IU] CNA " + getPath()); + rootState.nodeRead(name); List children = newArrayListWithCapacity(1 + editors.size()); children.add(new IndexUpdate(this, name)); diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java index 0b90644..7027ea8 100644 --- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java +++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java @@ -41,10 +41,10 @@ import static org.junit.Assert.fail; import java.util.Calendar; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; import javax.annotation.Nonnull; -import com.google.common.collect.Maps; import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Type; @@ -61,6 +61,7 @@ import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider; import org.apache.jackrabbit.oak.query.ast.SelectorImpl; import org.apache.jackrabbit.oak.query.index.FilterImpl; import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.DefaultEditor; import org.apache.jackrabbit.oak.spi.commit.Editor; import org.apache.jackrabbit.oak.spi.commit.EditorHook; import org.apache.jackrabbit.oak.spi.commit.EditorProvider; @@ -74,6 +75,7 @@ import org.apache.jackrabbit.util.ISO8601; import org.junit.Test; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; public class IndexUpdateTest { @@ -734,4 +736,77 @@ public class IndexUpdateTest { return nb; } + /** + * Reindex Test for OAK-5499 + * + */ + @Test + public void testReindexExtraTraversals() throws Exception { + final AtomicLong id = new AtomicLong(); + IndexEditorProvider provider = new IndexEditorProvider() { + + @Override + public Editor getIndexEditor(String type, NodeBuilder definition, NodeState root, + IndexUpdateCallback callback) { + return new CountingEditor(id.getAndIncrement()); + } + + }; + + EditorHook HOOK = new EditorHook(new IndexUpdateProvider(provider)); + NodeState before = EmptyNodeState.EMPTY_NODE; + NodeBuilder builder = before.builder(); + + builder.child("content").setProperty("foo", "abc"); + builder.child("content").child("childContent").setProperty("bar", "cde"); + NodeBuilder c = builder.child("content").child("childContent"); + for (int i = 0; i < 2; i++) { + c = c.child("c" + i); + } + createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), + "foo1Index", false, false, ImmutableSet.of("foo"), null); + createIndexDefinition(builder.child("content").child(INDEX_DEFINITIONS_NAME), + "foo2Index", false, false, ImmutableSet.of("bar"), null); + + NodeState after = builder.getNodeState(); + HOOK.processCommit(EmptyNodeState.MISSING_NODE, after, CommitInfo.EMPTY); + } + + private static class CountingEditor extends DefaultEditor { + + private String path = "/"; + + private final long id; + + public CountingEditor(long id) { + this.id = id; + } + + @Override + public void enter(NodeState before, NodeState after) throws CommitFailedException { + System.err.println("[E" + id + "] " + path); + } + + @Override + public Editor childNodeAdded(String name, NodeState after) throws CommitFailedException { + path = PathUtils.concat(path, name); + return this; + } + + @Override + public Editor childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException { + path = PathUtils.concat(path, name); + return this; + } + + @Override + public void leave(NodeState before, NodeState after) throws CommitFailedException { + path = PathUtils.getParentPath(path); + } + + } }