You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2013/06/11 15:00:06 UTC
svn commit: r1491780 [1/3] - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/
oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/
oak-core/src/main/java/org/a...
Author: jukka
Date: Tue Jun 11 13:00:04 2013
New Revision: 1491780
URL: http://svn.apache.org/r1491780
Log:
OAK-860: Streamline the IndexEditor
Added:
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditor.java (with props)
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorProvider.java (contents, props changed)
- copied, changed from r1491447, jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java
Removed:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexDefinition.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexDefinitionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexUpdate.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiff.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrNodeStateDiff.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrObserver.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookTest.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiffIT.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexEditorProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/CompositeIndexEditorProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexEditorProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditorProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/IndexStoreStrategy.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java
jackrabbit/oak/trunk/oak-core/src/main/resources/org/apache/jackrabbit/oak/plugins/nodetype/write/builtin_nodetypes.cnd
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/aggregation/NodeAggregator.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java Tue Jun 11 13:00:04 2013
@@ -23,6 +23,7 @@ import static java.util.concurrent.Execu
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.jcr.NoSuchWorkspaceException;
@@ -32,8 +33,6 @@ import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.mk.core.MicroKernelImpl;
-import org.apache.jackrabbit.mongomk.MongoMK;
-import org.apache.jackrabbit.mongomk.util.LogWrapper;
import org.apache.jackrabbit.oak.api.ContentRepository;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.Root;
@@ -279,7 +278,9 @@ public class Oak {
.compose(editorProviders)));
if (asyncIndexing) {
- new AsyncIndexUpdate(store, executor, indexEditors);
+ executor.scheduleWithFixedDelay(
+ new AsyncIndexUpdate("async", store, indexEditors),
+ 1, 5, TimeUnit.SECONDS);
}
// FIXME: OAK-810 move to proper workspace initialization
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexEditorProvider.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexEditorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexEditorProvider.java Tue Jun 11 13:00:04 2013
@@ -18,10 +18,12 @@
*/
package org.apache.jackrabbit.oak.osgi;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.index.CompositeIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* This IndexEditor provider combines all index editors of all available OSGi
@@ -35,13 +37,15 @@ public class OsgiIndexEditorProvider ext
}
@Override
- public Editor getIndexEditor(String type, NodeBuilder builder) {
+ public Editor getIndexEditor(
+ String type, NodeBuilder builder, NodeState root)
+ throws CommitFailedException {
IndexEditorProvider composite = CompositeIndexEditorProvider
.compose(getServices());
if (composite == null) {
return null;
}
- return composite.getIndexEditor(type, builder);
+ return composite.getIndexEditor(type, builder, root);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java Tue Jun 11 13:00:04 2013
@@ -19,33 +19,14 @@
package org.apache.jackrabbit.oak.plugins.index;
import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getBoolean;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getString;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.isIndexNodeType;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
-import org.apache.jackrabbit.oak.spi.commit.DefaultEditor;
-import org.apache.jackrabbit.oak.spi.commit.Editor;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.EditorHook;
-import org.apache.jackrabbit.oak.spi.commit.EditorProvider;
import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
-import org.apache.jackrabbit.oak.spi.commit.VisibleEditor;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
@@ -57,243 +38,36 @@ public class AsyncIndexUpdate implements
private static final Logger log = LoggerFactory
.getLogger(AsyncIndexUpdate.class);
- private final static int CONFIG_WATCH_DELAY_MS = 30000;
-
- // TODO index impl run frequency could be picked up from the index config
- // directly
- private final static int INDEX_TASK_DELAY_MS = 5000;
+ private final String name;
private final NodeStore store;
- private final ScheduledExecutorService executor;
-
- private final IndexEditorProvider provider;
-
+ private final CommitHook hook;
+
private NodeState current = EmptyNodeState.EMPTY_NODE;
- final Map<String, IndexTask> active = new ConcurrentHashMap<String, IndexTask>();
-
- private boolean started;
-
- public AsyncIndexUpdate(@Nonnull NodeStore store,
- @Nonnull ScheduledExecutorService executor,
+ public AsyncIndexUpdate(
+ @Nonnull String name,
+ @Nonnull NodeStore store,
@Nonnull IndexEditorProvider provider) {
+ this.name = checkNotNull(name);
this.store = checkNotNull(store);
- this.executor = checkNotNull(executor);
- this.provider = checkNotNull(provider);
- }
-
- public synchronized void start() {
- if (started) {
- log.error("Background index config watcher task already started");
- return;
- }
- started = true;
- executor.scheduleWithFixedDelay(this, 100, CONFIG_WATCH_DELAY_MS,
- TimeUnit.MILLISECONDS);
+ this.hook = new EditorHook(
+ new IndexUpdateProvider(checkNotNull(provider), name));
}
@Override
public void run() {
- log.debug("Running background index config watcher task");
- NodeState after = store.getRoot();
+ log.debug("Running background index task {}", name);
+ NodeStoreBranch branch = store.branch();
+ NodeState after = branch.getHead();
try {
- EditorHook hook = new EditorHook(new EditorProvider() {
- @Override
- public Editor getRootEditor(NodeState before, NodeState after,
- NodeBuilder builder) {
- return VisibleEditor.wrap(new IndexConfigWatcher());
- }
- });
- hook.processCommit(current, after);
+ NodeState processed = hook.processCommit(current, after);
+ branch.setRoot(processed);
+ branch.merge(EmptyHook.INSTANCE);
current = after;
} catch (CommitFailedException e) {
- log.warn("IndexTask update failed", e);
- }
- }
-
- public synchronized void replace(Map<String, Set<String>> async) {
- Set<String> in = new HashSet<String>(async.keySet());
- Set<String> existing = active.keySet();
- for (String type : existing) {
- if (in.remove(type)) {
- Set<String> defs = async.get(type);
- if (defs.isEmpty()) {
- remove(type);
- } else {
- addOrUpdate(type, defs);
- }
- } else {
- remove(type);
- }
- }
- for (String type : in) {
- addOrUpdate(type, async.get(type));
- }
- }
-
- void addOrUpdate(String type, Set<String> defs) {
- IndexTask task = active.get(type);
- if (task == null) {
- task = new IndexTask(store, provider, type, defs);
- active.put(type, task);
- task.start(executor);
- } else {
- task.update(defs);
- }
- }
-
- void remove(String type) {
- IndexTask task = active.remove(type);
- if (task != null) {
- task.stop();
- }
- }
-
- /**
- * This Editor is responsible for watching over changes on async index defs:
- * added index defs and deleted index defs are pushed forward to the
- * #replace method
- *
- */
- class IndexConfigWatcher extends DefaultEditor {
-
- private final Map<String, Set<String>> async = new HashMap<String, Set<String>>();
-
- @Override
- public void enter(NodeState before, NodeState after)
- throws CommitFailedException {
- if (!after.hasChildNode(INDEX_DEFINITIONS_NAME)) {
- return;
- }
- NodeState index = after.getChildNode(INDEX_DEFINITIONS_NAME);
- for (String indexName : index.getChildNodeNames()) {
- NodeState indexChild = index.getChildNode(indexName);
- if (isIndexNodeType(indexChild)) {
- boolean isasync = getBoolean(indexChild,
- ASYNC_PROPERTY_NAME);
- String type = getString(indexChild, TYPE_PROPERTY_NAME);
- if (type == null || !isasync) {
- // skip null and non-async types
- continue;
- }
- Set<String> defs = async.get(type);
- if (defs == null) {
- defs = new HashSet<String>();
- async.put(type, defs);
- }
- defs.add(type);
- }
- }
- }
-
- @Override
- public void leave(NodeState before, NodeState after)
- throws CommitFailedException {
- replace(async);
- async.clear();
- }
-
- }
-
- static class IndexTask implements Runnable {
-
- private static final Logger log = LoggerFactory
- .getLogger(IndexTask.class);
-
- private final NodeStore store;
-
- private final String type;
- private Set<String> defs;
-
- private final IndexEditorProvider provider;
-
- private ScheduledFuture<?> future;
-
- private NodeState before;
-
- public IndexTask(NodeStore store, IndexEditorProvider provider,
- String type, Set<String> defs) {
- this.store = store;
- this.provider = provider;
- this.type = type;
- this.defs = defs;
- this.before = EmptyNodeState.EMPTY_NODE;
- }
-
- public void update(Set<String> defs) {
- // check of there are any changes
- // TODO what happens when I move a def? (rm + add appears as a no-op
- // in the set)
- if (this.defs.equals(defs)) {
- // no-op
- return;
- }
-
- log.debug("Updated index def for type {}, reindexing", type);
- this.defs = defs;
- this.before = EmptyNodeState.EMPTY_NODE;
- }
-
- public synchronized void start(ScheduledExecutorService executor) {
- if (future != null) {
- throw new IllegalStateException("IndexTask has already started");
- }
- future = executor.scheduleWithFixedDelay(this, 100,
- INDEX_TASK_DELAY_MS, TimeUnit.MILLISECONDS);
- }
-
- public synchronized void stop() {
- if (future == null) {
- log.warn("IndexTask has already stopped.");
- return;
- }
- future.cancel(true);
- }
-
- @Override
- public void run() {
- log.debug("Running background index task for type {}.", type);
- NodeStoreBranch branch = store.branch();
- NodeState after = branch.getHead();
- try {
- EditorHook hook = new EditorHook(new TypedEditorProvider(
- provider, type));
- NodeState processed = hook.processCommit(before, after);
- branch.setRoot(processed);
- branch.merge(EmptyHook.INSTANCE);
- before = after;
- } catch (CommitFailedException e) {
- log.warn("IndexTask update failed", e);
- }
- }
- }
-
- /**
- * This creates a composite editor from a type-filtered index provider.
- *
- */
- private static class TypedEditorProvider implements EditorProvider {
-
- private final IndexEditorProvider provider;
-
- private final String type;
-
- public TypedEditorProvider(IndexEditorProvider provider, String type) {
- this.type = type;
- this.provider = provider;
- }
-
- /**
- * This does not make any effort to filter async definitions. The
- * assumption is that given an index type, all of the returned index
- * hooks inherit the same async assumption.
- *
- */
- @Override
- public Editor getRootEditor(NodeState before, NodeState after,
- NodeBuilder builder) {
- return VisibleEditor.wrap(provider.getIndexEditor(type, builder));
+ log.warn("Background index update " + name + " failed", e);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/CompositeIndexEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/CompositeIndexEditorProvider.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/CompositeIndexEditorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/CompositeIndexEditorProvider.java Tue Jun 11 13:00:04 2013
@@ -22,10 +22,12 @@ import java.util.List;
import javax.annotation.Nonnull;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.spi.commit.CompositeEditor;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.commit.VisibleEditor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -41,7 +43,8 @@ public class CompositeIndexEditorProvide
if (providers.isEmpty()) {
return new IndexEditorProvider() {
@Override
- public Editor getIndexEditor(String type, NodeBuilder builder) {
+ public Editor getIndexEditor(
+ String type, NodeBuilder builder, NodeState root) {
return null;
}
};
@@ -64,10 +67,12 @@ public class CompositeIndexEditorProvide
}
@Override
- public Editor getIndexEditor(String type, NodeBuilder builder) {
+ public Editor getIndexEditor(
+ String type, NodeBuilder builder, NodeState root)
+ throws CommitFailedException {
List<Editor> indexes = Lists.newArrayList();
for (IndexEditorProvider provider : providers) {
- Editor e = provider.getIndexEditor(type, builder);
+ Editor e = provider.getIndexEditor(type, builder, root);
if (e != null) {
indexes.add(e);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexEditorProvider.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexEditorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexEditorProvider.java Tue Jun 11 13:00:04 2013
@@ -17,9 +17,12 @@
package org.apache.jackrabbit.oak.plugins.index;
import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* Extension point for plugging in different kinds of IndexEditor providers.
@@ -29,23 +32,22 @@ import org.apache.jackrabbit.oak.spi.sta
public interface IndexEditorProvider {
/**
- *
* Each provider knows how to produce a certain type of index. If the
* <code>type</code> param is of an unknown value, the provider is expected
* to return {@code null}.
*
* <p>
- * The <code>builder</code> must points to the index definition node
- * under which the indexer is expected to store the index content.
+ * The <code>definition</code> builder must points to the index definition
+ * node under which the indexer is expected to store the index content.
* </p>
*
- * @param type
- * the index type
- * @param builder
- * the node state builder of the index definition node that
- * will be used for updates
+ * @param type index type
+ * @param definition index definition node builder, used for updates
+ * @param root root node state, used for things like node type information
* @return index update editor, or {@code null} if type is unknown
*/
@CheckForNull
- Editor getIndexEditor(String type, NodeBuilder builder);
+ Editor getIndexEditor(
+ @Nonnull String type, @Nonnull NodeBuilder definition,
+ @Nonnull NodeState root) throws CommitFailedException;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java Tue Jun 11 13:00:04 2013
@@ -27,9 +27,7 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getString;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -43,20 +41,30 @@ import org.apache.jackrabbit.oak.spi.com
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import com.google.common.base.Objects;
+
class IndexUpdate implements Editor {
private final IndexEditorProvider provider;
- private final boolean async;
+ private final String async;
private final NodeState root;
private final NodeBuilder builder;
+ /**
+ * Editors for indexes that will be normally updated.
+ */
private final List<Editor> editors = newArrayList();
+ /**
+ * Editors for indexes that need to be re-indexed.
+ */
+ private final List<Editor> reindex = newArrayList();
+
IndexUpdate(
- IndexEditorProvider provider, boolean async,
+ IndexEditorProvider provider, String async,
NodeState root, NodeBuilder builder) {
this.provider = checkNotNull(provider);
this.async = async;
@@ -75,43 +83,11 @@ class IndexUpdate implements Editor {
@Override
public void enter(NodeState before, NodeState after)
throws CommitFailedException {
- List<Editor> reindex = newArrayList();
- if (builder.hasChildNode(INDEX_DEFINITIONS_NAME)) {
- Map<String, Editor> tempEditors = new HashMap<String, Editor>();
- NodeBuilder definitions = builder.child(INDEX_DEFINITIONS_NAME);
- for (String name : definitions.getChildNodeNames()) {
- NodeBuilder definition = definitions.child(name);
- if (async == getBoolean(definition, ASYNC_PROPERTY_NAME)) {
- String type = getString(definition, TYPE_PROPERTY_NAME);
- Editor editor = null;
- if (tempEditors.containsKey(type)) {
- editor = tempEditors.get(type);
- } else {
- editor = provider.getIndexEditor(type, builder);
- tempEditors.put(type, editor);
- }
-
- if (editor == null) {
- // trigger reindexing when an indexer becomes available
- definition.setProperty(REINDEX_PROPERTY_NAME, true);
- } else if (getBoolean(definition, REINDEX_PROPERTY_NAME)) {
- definition.setProperty(REINDEX_PROPERTY_NAME, false);
- // as we don't know the index content node name
- // beforehand, we'll remove all child nodes
- for (String rm : definition.getChildNodeNames()) {
- definition.getChildNode(rm).remove();
- }
- reindex.add(editor);
- } else {
- editors.add(VisibleEditor.wrap(editor));
- }
- }
- }
- }
+ collectIndexEditors(builder.getChildNode(INDEX_DEFINITIONS_NAME));
// no-op when reindex is empty
CommitFailedException exception = EditorDiff.process(
- VisibleEditor.wrap(CompositeEditor.compose(reindex)), MISSING_NODE, after);
+ CompositeEditor.compose(reindex), MISSING_NODE, after);
if (exception != null) {
throw exception;
}
@@ -121,6 +97,31 @@ class IndexUpdate implements Editor {
}
}
+ private void collectIndexEditors(NodeBuilder definitions)
+ throws CommitFailedException {
+ for (String name : definitions.getChildNodeNames()) {
+ NodeBuilder definition = definitions.getChildNode(name);
+ if (Objects.equal(async, getString(definition, ASYNC_PROPERTY_NAME))) {
+ String type = getString(definition, TYPE_PROPERTY_NAME);
+ Editor editor = provider.getIndexEditor(type, definition, root);
+ if (editor == null) {
+ // trigger reindexing when an indexer becomes available
+ definition.setProperty(REINDEX_PROPERTY_NAME, true);
+ } else if (getBoolean(definition, REINDEX_PROPERTY_NAME)) {
+ definition.setProperty(REINDEX_PROPERTY_NAME, false);
+ // as we don't know the index content node name
+ // beforehand, we'll remove all child nodes
+ for (String rm : definition.getChildNodeNames()) {
+ definition.getChildNode(rm).remove();
+ }
+ reindex.add(VisibleEditor.wrap(editor));
+ } else {
+ editors.add(VisibleEditor.wrap(editor));
+ }
+ }
+ }
+ }
+
@Override
public void leave(NodeState before, NodeState after)
throws CommitFailedException {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateProvider.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateProvider.java Tue Jun 11 13:00:04 2013
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.oak.plugins.index;
import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.commit.EditorProvider;
@@ -27,13 +28,14 @@ public class IndexUpdateProvider impleme
private final IndexEditorProvider provider;
- private final boolean async;
+ private final String async;
public IndexUpdateProvider(IndexEditorProvider provider) {
- this(provider, false);
+ this(provider, null);
}
- public IndexUpdateProvider(IndexEditorProvider provider, boolean async) {
+ public IndexUpdateProvider(
+ @Nonnull IndexEditorProvider provider, @CheckForNull String async) {
this.provider = provider;
this.async = async;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java Tue Jun 11 13:00:04 2013
@@ -16,38 +16,33 @@
*/
package org.apache.jackrabbit.oak.plugins.index;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
-import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.util.NodeUtil;
-
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
import static org.apache.jackrabbit.oak.api.Type.BOOLEAN;
import static org.apache.jackrabbit.oak.api.Type.NAME;
import static org.apache.jackrabbit.oak.api.Type.NAMES;
import static org.apache.jackrabbit.oak.api.Type.STRING;
-import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.PROPERTY_NAMES;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_UNKNOWN;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.UNIQUE_PROPERTY_NAME;
+import java.util.Collection;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+
/**
* TODO document
*/
@@ -123,59 +118,6 @@ public class IndexUtils {
entry.setNames(PROPERTY_NAMES, propertyNames);
}
- /**
- * Builds a list of the existing index definitions.
- * <p/>
- * Checks only children of the provided state for an index definitions
- * container node, aka a node named {@link IndexConstants#INDEX_DEFINITIONS_NAME}
- *
- * @param state
- * @param indexConfigPath
- * @param typeFilter
- * @return A list of index definitions.
- */
- public static List<IndexDefinition> buildIndexDefinitions(NodeState state,
- String indexConfigPath, String typeFilter) {
- NodeState definitions = state.getChildNode(INDEX_DEFINITIONS_NAME);
- if (!definitions.exists()) {
- return Collections.emptyList();
- }
- indexConfigPath = concat(indexConfigPath, INDEX_DEFINITIONS_NAME);
-
- List<IndexDefinition> defs = new ArrayList<IndexDefinition>();
- for (ChildNodeEntry c : definitions.getChildNodeEntries()) {
- IndexDefinition def = getDefinition(indexConfigPath, c, typeFilter);
- if (def == null) {
- continue;
- }
- defs.add(def);
- }
- return defs;
- }
-
- /**
- * Builds an {@link IndexDefinition} out of a {@link ChildNodeEntry}
- *
- * @param path
- * @param def {@code ChildNodeEntry} storing the index definition.
- * @param typeFilter
- * @return a new {@code IndexDefinition}
- */
- private static IndexDefinition getDefinition(String path,
- ChildNodeEntry def, String typeFilter) {
- String name = def.getName();
- NodeState ns = def.getNodeState();
- PropertyState typeProp = ns.getProperty(TYPE_PROPERTY_NAME);
- String type = TYPE_UNKNOWN;
- if (typeProp != null && !typeProp.isArray()) {
- type = typeProp.getValue(STRING);
- }
- if (typeFilter != null && !typeFilter.equals(type)) {
- return null;
- }
- return new IndexDefinitionImpl(name, type, concat(path, name));
- }
-
public static boolean isIndexNodeType(NodeState state) {
PropertyState ps = state.getProperty(JCR_PRIMARYTYPE);
return ps != null
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditor.java Tue Jun 11 13:00:04 2013
@@ -16,197 +16,168 @@
*/
package org.apache.jackrabbit.oak.plugins.index.property;
+import static com.google.common.base.Predicates.in;
import static com.google.common.collect.Iterables.addAll;
-import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Sets.newHashSet;
+import static java.util.Collections.singleton;
import static org.apache.jackrabbit.JcrConstants.JCR_ISMIXIN;
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
+import static org.apache.jackrabbit.oak.api.CommitFailedException.CONSTRAINT;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.PROPERTY_NAMES;
-import static org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider.TYPE;
-import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+import static org.apache.jackrabbit.oak.plugins.index.property.PropertyIndex.encode;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_MIXIN_SUBTYPES;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.OAK_PRIMARY_SUBTYPES;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.isIndexNodeType;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getChildOrNull;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
+import javax.jcr.PropertyType;
+
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.plugins.index.IndexConstants;
import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
import org.apache.jackrabbit.oak.plugins.index.property.strategy.ContentMirrorStoreStrategy;
import org.apache.jackrabbit.oak.plugins.index.property.strategy.IndexStoreStrategy;
-import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
import org.apache.jackrabbit.oak.spi.commit.Editor;
+import org.apache.jackrabbit.oak.spi.query.PropertyValues;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
-import com.google.common.collect.ImmutableList;
-
/**
- * {@link IndexEditor} implementation that is responsible for keeping the
- * {@link PropertyIndex} up to date.
- * <br>
- * There is a tree of PropertyIndexDiff objects, each object represents the
- * changes at a given node.
+ * Index editor for keeping a property index up to date.
*
* @see PropertyIndex
* @see PropertyIndexLookup
*/
-class PropertyIndexEditor implements IndexEditor, Closeable {
+class PropertyIndexEditor implements IndexEditor {
- private final IndexStoreStrategy store = new ContentMirrorStoreStrategy();
+ /** Index storage strategy */
+ private static final IndexStoreStrategy STORE =
+ new ContentMirrorStoreStrategy();
- /**
- * The parent (null if this is the root node).
- */
+ /** Parent editor, or {@code null} if this is the root editor. */
private final PropertyIndexEditor parent;
- /**
- * The node (can be null in the case of a deleted node).
- */
- private final NodeBuilder node;
+ /** Name of this node, or {@code null} for the root node. */
+ private final String name;
- /**
- * The node name (the path element). Null for the root node.
- */
- private final String nodeName;
+ /** Path of this editor, built lazily in {@link #getPath()}. */
+ private String path;
+
+ /** Index definition node builder */
+ private final NodeBuilder definition;
+
+ private final Set<String> propertyNames;
+
+ private final Set<String> primaryTypes;
+
+ private final Set<String> mixinTypes;
+
+ private final Set<String> keysToCheckForUniqueness;
/**
- * The path of the changed node (built lazily).
+ * Flag to indicate whether individual property changes should
+ * be tracked for this node.
*/
- private String path;
-
- private final boolean isRoot;
+ private boolean trackChanges = false;
/**
- * The map of known indexes. Key: the property name. Value: the list of
- * indexes (it is possible to have multiple indexes for the same property
- * name).
+ * Matching property value keys from the before state,
+ * or {@code null} if this node is not indexed.
*/
- private final Map<String, List<PropertyIndexUpdate>> indexMap;
+ private Set<String> beforeKeys = null;
/**
- * The {@code /jcr:system/jcr:nodeTypes} subtree.
+ * Matching property value keys from the after state,
+ * or {@code null} if this node is not indexed.
*/
- private final NodeState types;
+ private Set<String> afterKeys = null;
- public PropertyIndexEditor(NodeBuilder builder) {
- this(null, builder, null, "/", true);
- }
+ public PropertyIndexEditor(NodeBuilder definition, NodeState root) {
+ this.parent = null;
+ this.name = null;
+ this.path = "/";
+ this.definition = definition;
+
+ // get property names
+ this.propertyNames = newHashSet(definition.getNames(PROPERTY_NAMES));
+
+ // get declaring types, and all their subtypes
+ // TODO: should we reindex when type definitions change?
+ if (definition.hasProperty(DECLARING_NODE_TYPES)) {
+ this.primaryTypes = newHashSet();
+ this.mixinTypes = newHashSet();
+ NodeState types =
+ root.getChildNode(JCR_SYSTEM).getChildNode(JCR_NODE_TYPES);
+ for (String name : definition.getNames(DECLARING_NODE_TYPES)) {
+ NodeState type = types.getChildNode(name);
+ if (type.getBoolean(JCR_ISMIXIN)) {
+ mixinTypes.add(name);
+ } else {
+ primaryTypes.add(name);
+ }
+ addAll(mixinTypes, type.getNames(OAK_MIXIN_SUBTYPES));
+ addAll(primaryTypes, type.getNames(OAK_PRIMARY_SUBTYPES));
+ }
+ } else {
+ this.primaryTypes = null;
+ this.mixinTypes = null;
+ }
- private PropertyIndexEditor(PropertyIndexEditor parent, String nodeName) {
- this(parent, getChildOrNull(parent.node, nodeName), nodeName, null, false);
+ // keep track of modified keys for uniqueness checks
+ if (definition.getBoolean(IndexConstants.UNIQUE_PROPERTY_NAME)) {
+ this.keysToCheckForUniqueness = newHashSet();
+ } else {
+ this.keysToCheckForUniqueness = null;
+ }
}
- private PropertyIndexEditor(PropertyIndexEditor parent, NodeBuilder node,
- String nodeName, String path, boolean root) {
+ private PropertyIndexEditor(PropertyIndexEditor parent, String name) {
this.parent = parent;
- this.node = node;
- this.nodeName = nodeName;
- this.path = path;
- this.isRoot = root;
-
- if (parent == null) {
- this.indexMap = new HashMap<String, List<PropertyIndexUpdate>>();
- if (node.hasChildNode(JCR_SYSTEM)) {
- NodeBuilder typeNB = node.getChildNode(JCR_SYSTEM)
- .getChildNode(JCR_NODE_TYPES);
- this.types = typeNB.getNodeState();
- } else {
- this.types = EmptyNodeState.MISSING_NODE;
- }
- } else {
- this.indexMap = parent.indexMap;
- this.types = parent.types;
- }
+ this.name = name;
+ this.path = null;
+ this.definition = parent.definition;
+ this.propertyNames = parent.propertyNames;
+ this.primaryTypes = parent.primaryTypes;
+ this.mixinTypes = parent.mixinTypes;
+ this.keysToCheckForUniqueness = parent.keysToCheckForUniqueness;
}
- public String getPath() {
- // build the path lazily
+ /**
+ * Returns the path of this node, building it lazily when first requested.
+ */
+ private String getPath() {
if (path == null) {
- path = concat(parent.getPath(), nodeName);
+ path = concat(parent.getPath(), name);
}
return path;
}
- /**
- * Get all the indexes for the given property name.
- *
- * @param propertyName
- * the property name
- * @return the indexes
- */
- private Iterable<PropertyIndexUpdate> getIndexes(String propertyName) {
- List<PropertyIndexUpdate> indexes = indexMap.get(propertyName);
- if (indexes == null) {
- return ImmutableList.of();
- }
- List<PropertyIndexUpdate> filtered = new ArrayList<PropertyIndexUpdate>();
- for (PropertyIndexUpdate pi : indexes) {
- if (node == null || pi.matchesNodeType(node, getPath())) {
- filtered.add(pi);
- }
- }
- return filtered;
+ private boolean isOfMatchingType(NodeState state) {
+ return primaryTypes == null // no type limitations
+ || primaryTypes.contains(state.getName(JCR_PRIMARYTYPE))
+ || any(state.getNames(JCR_MIXINTYPES), in(mixinTypes));
}
- /**
- * Add the index definitions to the in-memory set of known index
- * definitions.
- *
- * @param state
- * the node state that contains the index definition
- * @param indexName
- * the name of the index
- */
- private void addIndexes(NodeState state, String indexName) {
- Set<String> primaryTypes = newHashSet();
- Set<String> mixinTypes = newHashSet();
- for (String typeName : state.getNames(DECLARING_NODE_TYPES)) {
- NodeState type = types.getChildNode(typeName);
- if (type.getBoolean(JCR_ISMIXIN)) {
- mixinTypes.add(typeName);
- } else {
- primaryTypes.add(typeName);
- }
- addAll(primaryTypes, type.getNames(OAK_PRIMARY_SUBTYPES));
- addAll(mixinTypes, type.getNames(OAK_MIXIN_SUBTYPES));
+ private static void addValueKeys(Set<String> keys, PropertyState property) {
+ if (property.getType().tag() != PropertyType.BINARY) {
+ keys.addAll(encode(PropertyValues.create(property)));
}
+ }
- PropertyState ps = state.getProperty(PROPERTY_NAMES);
- Iterable<String> propertyNames = ps != null ? ps.getValue(Type.NAMES)
- : ImmutableList.of(indexName);
- for (String pname : propertyNames) {
- List<PropertyIndexUpdate> list = this.indexMap.get(pname);
- if (list == null) {
- list = newArrayList();
- this.indexMap.put(pname, list);
- }
- boolean exists = false;
- String localPath = getPath();
- for (PropertyIndexUpdate piu : list) {
- if (piu.matches(localPath, primaryTypes, mixinTypes)) {
- exists = true;
- break;
- }
- }
- if (!exists) {
- PropertyIndexUpdate update = new PropertyIndexUpdate(
- getPath(), node.child(INDEX_DEFINITIONS_NAME).child(indexName),
- store, primaryTypes, mixinTypes);
- list.add(update);
+ private static void addMatchingKeys(
+ Set<String> keys, NodeState state, Iterable<String> propertyNames) {
+ for (String propertyName : propertyNames) {
+ PropertyState property = state.getProperty(propertyName);
+ if (property != null) {
+ addValueKeys(keys, property);
}
}
}
@@ -214,75 +185,100 @@ class PropertyIndexEditor implements Ind
@Override
public void enter(NodeState before, NodeState after)
throws CommitFailedException {
- if (after != null && after.hasChildNode(INDEX_DEFINITIONS_NAME)) {
- NodeState index = after.getChildNode(INDEX_DEFINITIONS_NAME);
- for (String indexName : index.getChildNodeNames()) {
- NodeState child = index.getChildNode(indexName);
- if (isIndexNodeType(child, TYPE)) {
- addIndexes(child, indexName);
- }
- }
+ boolean beforeMatches = before.exists() && isOfMatchingType(before);
+ boolean afterMatches = after.exists() && isOfMatchingType(after);
+
+ if (beforeMatches || afterMatches) {
+ beforeKeys = newHashSet();
+ afterKeys = newHashSet();
+ }
+
+ if (beforeMatches && afterMatches) {
+ trackChanges = true;
+ } else if (beforeMatches) {
+ // all matching values should be removed from the index
+ addMatchingKeys(beforeKeys, before, propertyNames);
+ } else if (afterMatches) {
+ // all matching values should be added to the index
+ addMatchingKeys(afterKeys, after, propertyNames);
}
}
@Override
public void leave(NodeState before, NodeState after)
throws CommitFailedException {
- if (isRoot) {
- for (List<PropertyIndexUpdate> updates : indexMap.values()) {
- for (PropertyIndexUpdate update : updates) {
- update.checkUniqueKeys();
+ if (beforeKeys != null) {
+ Set<String> sharedKeys = newHashSet(beforeKeys);
+ sharedKeys.retainAll(afterKeys);
+
+ beforeKeys.removeAll(sharedKeys);
+ afterKeys.removeAll(sharedKeys);
+
+ if (!beforeKeys.isEmpty() || !afterKeys.isEmpty()) {
+ NodeBuilder index = definition.child(INDEX_CONTENT_NODE_NAME);
+ STORE.update(index, getPath(), beforeKeys, afterKeys);
+
+ if (keysToCheckForUniqueness != null) {
+ keysToCheckForUniqueness.addAll(afterKeys);
}
}
}
- }
- @Override
- public void propertyAdded(PropertyState after) throws CommitFailedException {
- for (PropertyIndexUpdate update : getIndexes(after.getName())) {
- update.insert(getPath(), after);
+ if (parent == null) {
+ // make sure that the index node exist, even with no content
+ NodeBuilder index = definition.child(INDEX_CONTENT_NODE_NAME);
+
+ // check uniqueness constraints when leaving the root
+ if (keysToCheckForUniqueness != null
+ && !keysToCheckForUniqueness.isEmpty()) {
+ NodeState state = index.getNodeState();
+ for (String key : keysToCheckForUniqueness) {
+ if (STORE.count(state, singleton(key), 2) > 1) {
+ throw new CommitFailedException(
+ CONSTRAINT, 30,
+ "Uniqueness constraint violated for key " + key);
+ }
+ }
+ }
}
}
@Override
- public void propertyChanged(PropertyState before, PropertyState after)
- throws CommitFailedException {
- for (PropertyIndexUpdate update : getIndexes(after.getName())) {
- update.remove(getPath(), before);
- update.insert(getPath(), after);
+ public void propertyAdded(PropertyState after) {
+ if (trackChanges && propertyNames.contains(after.getName())) {
+ addValueKeys(afterKeys, after);
}
}
@Override
- public void propertyDeleted(PropertyState before)
- throws CommitFailedException {
- for (PropertyIndexUpdate update : getIndexes(before.getName())) {
- update.remove(getPath(), before);
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ if (trackChanges && propertyNames.contains(after.getName())) {
+ addValueKeys(beforeKeys, before);
+ addValueKeys(afterKeys, after);
}
}
@Override
- public Editor childNodeAdded(String name, NodeState after)
- throws CommitFailedException {
- return childNodeChanged(name, EMPTY_NODE, after);
+ public void propertyDeleted(PropertyState before) {
+ if (trackChanges && propertyNames.contains(before.getName())) {
+ addValueKeys(beforeKeys, before);
+ }
}
@Override
- public Editor childNodeChanged(String name, NodeState before,
- NodeState after) throws CommitFailedException {
+ public Editor childNodeAdded(String name, NodeState after) {
return new PropertyIndexEditor(this, name);
}
@Override
- public Editor childNodeDeleted(String name, NodeState before)
- throws CommitFailedException {
- return childNodeChanged(name, before, EMPTY_NODE);
+ public Editor childNodeChanged(
+ String name, NodeState before, NodeState after) {
+ return new PropertyIndexEditor(this, name);
}
- // -----------------------------------------------------< Closeable >--
-
@Override
- public void close() throws IOException {
- indexMap.clear();
+ public Editor childNodeDeleted(String name, NodeState before) {
+ return new PropertyIndexEditor(this, name);
}
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditorProvider.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexEditorProvider.java Tue Jun 11 13:00:04 2013
@@ -21,6 +21,7 @@ import org.apache.felix.scr.annotations.
import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* Service that provides PropertyIndex based editors.
@@ -36,9 +37,10 @@ public class PropertyIndexEditorProvider
public static final String TYPE = "property";
@Override
- public Editor getIndexEditor(String type, NodeBuilder builder) {
+ public Editor getIndexEditor(
+ String type, NodeBuilder definition, NodeState root) {
if (TYPE.equals(type)) {
- return new PropertyIndexEditor(builder);
+ return new PropertyIndexEditor(definition, root);
}
return null;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java Tue Jun 11 13:00:04 2013
@@ -24,6 +24,7 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider.TYPE;
import static org.apache.jackrabbit.oak.plugins.index.property.PropertyIndex.encode;
+import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;
import java.util.Iterator;
import java.util.Set;
@@ -85,13 +86,13 @@ public class PropertyIndexLookup {
}
if (PathUtils.denotesRoot(path)) {
- return getIndexDataNode(root, propertyName, supertypes) != null;
+ return getIndexDataNode(root, propertyName, supertypes).exists();
}
NodeState node = root;
Iterator<String> it = PathUtils.elements(path).iterator();
while (it.hasNext()) {
- if (getIndexDataNode(node, propertyName, supertypes) != null) {
+ if (getIndexDataNode(node, propertyName, supertypes).exists()) {
return true;
}
node = node.getChildNode(it.next());
@@ -106,10 +107,11 @@ public class PropertyIndexLookup {
}
NodeState state = getIndexDataNode(root, propertyName, supertypes);
- if (state == null) {
+ if (state.exists()) {
+ return store.query(filter, propertyName, state, encode(value));
+ } else {
throw new IllegalArgumentException("No index for " + propertyName);
}
- return store.query(filter, propertyName, state, encode(value));
}
public double getCost(Filter filter, String name, PropertyValue value) {
@@ -119,10 +121,11 @@ public class PropertyIndexLookup {
}
NodeState state = getIndexDataNode(root, name, supertypes);
- if (state == null) {
+ if (state.exists()) {
+ return store.count(state, encode(value), MAX_COST);
+ } else {
return Double.POSITIVE_INFINITY;
}
- return store.count(state, encode(value), MAX_COST);
}
/**
@@ -139,7 +142,7 @@ public class PropertyIndexLookup {
private NodeState getIndexDataNode(
NodeState node, String propertyName, Set<String> supertypes) {
//keep a fallback to a matching index def that has *no* node type constraints
- NodeState fallback = null;
+ NodeState fallback = MISSING_NODE;
NodeState state = node.getChildNode(INDEX_DEFINITIONS_NAME);
for (ChildNodeEntry entry : state.getChildNodeEntries()) {
@@ -161,7 +164,7 @@ public class PropertyIndexLookup {
}
} else if (supertypes == null) {
return index;
- } else if (fallback == null) {
+ } else if (index.exists() && !fallback.exists()) {
fallback = index;
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java Tue Jun 11 13:00:04 2013
@@ -16,14 +16,12 @@
*/
package org.apache.jackrabbit.oak.plugins.index.property.strategy;
-import java.util.Collections;
+import static com.google.common.collect.Queues.newArrayDeque;
+
import java.util.Deque;
import java.util.Iterator;
-import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
-import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -65,82 +63,52 @@ public class ContentMirrorStoreStrategy
static final Logger LOG = LoggerFactory.getLogger(ContentMirrorStoreStrategy.class);
@Override
- public void remove(NodeBuilder index, String key, Iterable<String> values) {
- if (!index.hasChildNode(key)) {
- return;
- }
- NodeBuilder child = index.child(key);
- Map<String, NodeBuilder> parents = new TreeMap<String, NodeBuilder>(Collections.reverseOrder());
-
- for (String rm : values) {
- if (PathUtils.denotesRoot(rm)) {
- child.removeProperty("match");
- } else {
- String parentPath = PathUtils.getParentPath(rm);
- String name = PathUtils.getName(rm);
- NodeBuilder indexEntry = parents.get(parentPath);
- if (indexEntry == null) {
- indexEntry = child;
- String segmentPath = "";
- Iterator<String> segments = PathUtils.elements(parentPath)
- .iterator();
- while (segments.hasNext()) {
- String segment = segments.next();
- segmentPath = PathUtils.concat(segmentPath, segment);
- indexEntry = indexEntry.child(segment);
- parents.put(segmentPath, indexEntry);
- }
- }
- if (indexEntry.hasChildNode(name)) {
- NodeBuilder childEntry = indexEntry.child(name);
- childEntry.removeProperty("match");
- if (childEntry.getChildNodeCount() == 0) {
- indexEntry.getChildNode(name).remove();
- }
- }
- }
+ public void update(
+ NodeBuilder index, String path,
+ Set<String> beforeKeys, Set<String> afterKeys) {
+ for (String key : beforeKeys) {
+ remove(index, key, path);
}
- // prune the index: remove all children that have no children
- // and no "match" property progressing bottom up
- Iterator<String> it = parents.keySet().iterator();
- while (it.hasNext()) {
- String path = it.next();
- NodeBuilder parent = parents.get(path);
- pruneNode(parent);
- }
-
- // finally prune the index node
- pruneNode(child);
- if (child.getChildNodeCount() == 0
- && !child.hasProperty("match")) {
- index.getChildNode(key).remove();
+ for (String key : afterKeys) {
+ insert(index, key, path);
}
}
- private static void pruneNode(NodeBuilder parent) {
- if (!parent.exists()) {
- return;
- }
- for (String name : parent.getChildNodeNames()) {
- NodeBuilder segment = parent.child(name);
- if (segment.getChildNodeCount() == 0
- && !segment.hasProperty("match")) {
- parent.getChildNode(name).remove();
+ private void remove(NodeBuilder index, String key, String value) {
+ NodeBuilder builder = index.getChildNode(key);
+ if (builder.exists()) {
+ // Collect all builders along the given path
+ Deque<NodeBuilder> builders = newArrayDeque();
+ builders.addFirst(builder);
+
+ // Descend to the correct location in the index tree
+ for (String name : PathUtils.elements(value)) {
+ builder = builder.getChildNode(name);
+ builders.addFirst(builder);
+ }
+
+ // Drop the match value, if present
+ if (builder.exists()) {
+ builder.removeProperty("match");
+ }
+
+ // Prune all index nodes that are no longer needed
+ for (NodeBuilder node : builders) {
+ if (node.getBoolean("match") || node.getChildNodeCount() > 0) {
+ return;
+ } else if (node.exists()) {
+ node.remove();
+ }
}
}
}
- @Override
- public void insert(NodeBuilder index, String key, Iterable<String> values)
- throws CommitFailedException {
- NodeBuilder child = index.child(key);
- for (String add : values) {
- NodeBuilder indexEntry = child;
- for (String segment : PathUtils.elements(add)) {
- indexEntry = indexEntry.child(segment);
- }
- indexEntry.setProperty("match", true);
+ private void insert(NodeBuilder index, String key, String value) {
+ NodeBuilder builder = index.child(key);
+ for (String name : PathUtils.elements(value)) {
+ builder = builder.child(name);
}
+ builder.setProperty("match", true);
}
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/IndexStoreStrategy.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/IndexStoreStrategy.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/IndexStoreStrategy.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/IndexStoreStrategy.java Tue Jun 11 13:00:04 2013
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.plugin
import java.util.Set;
-import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -30,26 +29,16 @@ import org.apache.jackrabbit.oak.spi.sta
public interface IndexStoreStrategy {
/**
- * Removes a set of values from the index
+ * Updates the index for the given path.
*
* @param index the index node
- * @param key the index key
- * @param values the values to be removed from the given key
- * @throws CommitFailedException
+ * @param path path stored in the index
+ * @param beforeKeys keys that no longer apply to the path
+ * @param afterKeys keys that now do apply to the path
*/
- void remove(NodeBuilder index, String key, Iterable<String> values)
- throws CommitFailedException;
-
- /**
- * Inserts a set of values in the index
- *
- * @param index the index node
- * @param key the index key
- * @param values the values to be added to the given key
- * @throws CommitFailedException
- */
- void insert(NodeBuilder index, String key, Iterable<String> values)
- throws CommitFailedException;
+ void update(
+ NodeBuilder index, String path,
+ Set<String> beforeKeys, Set<String> afterKeys);
/**
* Search for a given set of values.
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeBuilder.java Tue Jun 11 13:00:04 2013
@@ -260,7 +260,7 @@ public class MemoryNodeBuilder implement
@Override
public NodeBuilder setChildNode(String name, NodeState state) {
- checkState(exists(), "This builder does not exist: " + name);
+ checkState(exists(), "This builder does not exist: " + this.name);
head().getMutableNodeState().setChildNode(checkNotNull(name), checkNotNull(state));
MemoryNodeBuilder builder = createChildBuilder(name);
updated();
Modified: jackrabbit/oak/trunk/oak-core/src/main/resources/org/apache/jackrabbit/oak/plugins/nodetype/write/builtin_nodetypes.cnd
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/resources/org/apache/jackrabbit/oak/plugins/nodetype/write/builtin_nodetypes.cnd?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/resources/org/apache/jackrabbit/oak/plugins/nodetype/write/builtin_nodetypes.cnd (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/resources/org/apache/jackrabbit/oak/plugins/nodetype/write/builtin_nodetypes.cnd Tue Jun 11 13:00:04 2013
@@ -511,7 +511,8 @@
* @since oak 0.6
*/
[oak:queryIndexDefinition] > nt:unstructured
- - type (STRING)
+ - type (STRING) mandatory
+ - async (STRING)
- reindex (BOOLEAN) mandatory IGNORE
//------------------------------------------------------------------------------
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java Tue Jun 11 13:00:04 2013
@@ -23,12 +23,8 @@ import static org.apache.jackrabbit.oak.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import java.util.Map;
import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.IndexTask;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexLookup;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
@@ -74,7 +70,6 @@ public class AsyncIndexUpdateTest {
@Test
public void testAsync() throws Exception {
NodeStore store = new MemoryNodeStore();
- ScheduledExecutorService executor = Executors.newScheduledThreadPool(0);
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeStoreBranch branch = store.branch();
@@ -82,15 +77,15 @@ public class AsyncIndexUpdateTest {
NodeBuilder builder = root.builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
"rootIndex", true, false, ImmutableSet.of("foo"), null)
- .setProperty(ASYNC_PROPERTY_NAME, true);
+ .setProperty(ASYNC_PROPERTY_NAME, "async");
builder.child("testRoot").setProperty("foo", "abc");
// merge it back in
branch.setRoot(builder.getNodeState());
branch.merge(EmptyHook.INSTANCE);
- AsyncIndexUpdate async = new AsyncIndexUpdate(store, executor, provider);
- runIndexing(async, 1);
+ AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider);
+ async.run();
root = store.getRoot();
// first check that the index content nodes exist
@@ -101,15 +96,6 @@ public class AsyncIndexUpdateTest {
assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", "abc"));
}
- private static void runIndexing(AsyncIndexUpdate async, int expectedActive) {
- async.run();
- Map<String, IndexTask> active = async.active;
- assertEquals(expectedActive, active.size());
- for (IndexTask task : active.values()) {
- task.run();
- }
- }
-
/**
* Async Index Test with 2 index defs at the same location
* <ul>
@@ -122,7 +108,6 @@ public class AsyncIndexUpdateTest {
@Test
public void testAsyncDouble() throws Exception {
NodeStore store = new MemoryNodeStore();
- ScheduledExecutorService executor = Executors.newScheduledThreadPool(0);
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeStoreBranch branch = store.branch();
@@ -130,10 +115,10 @@ public class AsyncIndexUpdateTest {
NodeBuilder builder = root.builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
"rootIndex", true, false, ImmutableSet.of("foo"), null)
- .setProperty(ASYNC_PROPERTY_NAME, true);
+ .setProperty(ASYNC_PROPERTY_NAME, "async");
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
"rootIndexSecond", true, false, ImmutableSet.of("bar"), null)
- .setProperty(ASYNC_PROPERTY_NAME, true);
+ .setProperty(ASYNC_PROPERTY_NAME, "async");
builder.child("testRoot").setProperty("foo", "abc")
.setProperty("bar", "def");
@@ -143,8 +128,8 @@ public class AsyncIndexUpdateTest {
branch.setRoot(builder.getNodeState());
branch.merge(EmptyHook.INSTANCE);
- AsyncIndexUpdate async = new AsyncIndexUpdate(store, executor, provider);
- runIndexing(async, 1);
+ AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider);
+ async.run();
root = store.getRoot();
// first check that the index content nodes exist
@@ -176,7 +161,6 @@ public class AsyncIndexUpdateTest {
@Test
public void testAsyncDoubleSubtree() throws Exception {
NodeStore store = new MemoryNodeStore();
- ScheduledExecutorService executor = Executors.newScheduledThreadPool(0);
IndexEditorProvider provider = new PropertyIndexEditorProvider();
NodeStoreBranch branch = store.branch();
@@ -184,12 +168,12 @@ public class AsyncIndexUpdateTest {
NodeBuilder builder = root.builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
"rootIndex", true, false, ImmutableSet.of("foo"), null)
- .setProperty(ASYNC_PROPERTY_NAME, true);
+ .setProperty(ASYNC_PROPERTY_NAME, "async");
createIndexDefinition(
builder.child("newchild").child("other")
.child(INDEX_DEFINITIONS_NAME), "subIndex", true,
- false, ImmutableSet.of("foo"), null).setProperty(
- ASYNC_PROPERTY_NAME, true);
+ false, ImmutableSet.of("foo"), null)
+ .setProperty(ASYNC_PROPERTY_NAME, "async");
builder.child("testRoot").setProperty("foo", "abc");
builder.child("newchild").child("other").child("testChild")
@@ -199,8 +183,8 @@ public class AsyncIndexUpdateTest {
branch.setRoot(builder.getNodeState());
branch.merge(EmptyHook.INSTANCE);
- AsyncIndexUpdate async = new AsyncIndexUpdate(store, executor, provider);
- runIndexing(async, 1);
+ AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider);
+ async.run();
root = store.getRoot();
// first check that the index content nodes exist
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java Tue Jun 11 13:00:04 2013
@@ -50,6 +50,9 @@ import com.google.common.collect.Sets;
public class IndexUpdateTest {
+ private static final EditorHook HOOK = new EditorHook(
+ new IndexUpdateProvider(new PropertyIndexEditorProvider()));
+
private NodeState root = new InitialContent().initialize(EMPTY_NODE);
private NodeBuilder builder = root.builder();
@@ -81,10 +84,7 @@ public class IndexUpdateTest {
NodeState after = builder.getNodeState();
- IndexUpdateProvider p = new IndexUpdateProvider(
- new PropertyIndexEditorProvider());
- EditorHook hook = new EditorHook(p);
- NodeState indexed = hook.processCommit(before, after);
+ NodeState indexed = HOOK.processCommit(before, after);
// first check that the index content nodes exist
checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "rootIndex",
@@ -120,10 +120,7 @@ public class IndexUpdateTest {
NodeState after = builder.getNodeState();
- IndexUpdateProvider p = new IndexUpdateProvider(
- new PropertyIndexEditorProvider());
- EditorHook hook = new EditorHook(p);
- NodeState indexed = hook.processCommit(before, after);
+ NodeState indexed = HOOK.processCommit(before, after);
// first check that the index content nodes exist
NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
@@ -159,10 +156,7 @@ public class IndexUpdateTest {
.setProperty(REINDEX_PROPERTY_NAME, true);
NodeState after = builder.getNodeState();
- IndexUpdateProvider p = new IndexUpdateProvider(
- new PropertyIndexEditorProvider());
- EditorHook hook = new EditorHook(p);
- NodeState indexed = hook.processCommit(before, after);
+ NodeState indexed = HOOK.processCommit(before, after);
// first check that the index content nodes exist
NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
@@ -183,19 +177,16 @@ public class IndexUpdateTest {
"existing", true, false, ImmutableSet.of("foo"), null);
NodeState before = builder.getNodeState();
+ NodeBuilder other = builder.child("test").child("other");
// Add index definition
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "foo",
true, false, ImmutableSet.of("foo"), null);
createIndexDefinition(
- builder.child("test").child("other")
- .child(INDEX_DEFINITIONS_NAME), "index2", true, false,
+ other.child(INDEX_DEFINITIONS_NAME), "index2", true, false,
ImmutableSet.of("foo"), null);
NodeState after = builder.getNodeState();
- IndexUpdateProvider p = new IndexUpdateProvider(
- new PropertyIndexEditorProvider());
- EditorHook hook = new EditorHook(p);
- NodeState indexed = hook.processCommit(before, after);
+ NodeState indexed = HOOK.processCommit(before, after);
// check that the index content nodes exist
checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "existing",