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 ch...@apache.org on 2014/10/31 07:32:56 UTC
svn commit: r1635689 - in /jackrabbit/oak/branches/1.0: ./
oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/
oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/
Author: chetanm
Date: Fri Oct 31 06:32:56 2014
New Revision: 1635689
URL: http://svn.apache.org/r1635689
Log:
OAK-2198 - Add support for declaringNodeTypes to only index node with specific types
Merging 1634792,1634814
Modified:
jackrabbit/oak/branches/1.0/ (props changed)
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
Merged /jackrabbit/oak/trunk:r1634792,1634814
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java?rev=1635689&r1=1635688&r2=1635689&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java Fri Oct 31 06:32:56 2014
@@ -40,6 +40,7 @@ import org.apache.lucene.codecs.Codec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ENTRY_COUNT_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_COUNT;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.BLOB_SIZE;
@@ -72,6 +73,8 @@ public class IndexDefinition {
private final Set<String> orderedProps;
+ private final Set<String> declaringNodeTypes;
+
private final boolean fullTextEnabled;
private final boolean storageEnabled;
@@ -112,6 +115,8 @@ public class IndexDefinition {
this.excludes = toLowerCase(getMultiProperty(defn, EXCLUDE_PROPERTY_NAMES));
this.includes = getMultiProperty(defn, INCLUDE_PROPERTY_NAMES);
this.orderedProps = getMultiProperty(defn, ORDERED_PROP_NAMES);
+ this.declaringNodeTypes = getMultiProperty(defn, DECLARING_NODE_TYPES);
+
this.blobSize = getOptionalValue(defn, BLOB_SIZE, DEFAULT_BLOB_SIZE);
this.fullTextEnabled = getOptionalValue(defn, FULL_TEXT_ENABLED, true);
@@ -169,6 +174,13 @@ public class IndexDefinition {
return propertyTypes;
}
+ public Set<String> getDeclaringNodeTypes() {
+ return declaringNodeTypes;
+ }
+
+ public boolean hasDeclaredNodeTypes(){
+ return !declaringNodeTypes.isEmpty();
+ }
/**
* Checks if a given property should be stored in the lucene index or not
*/
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1635689&r1=1635688&r2=1635689&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java Fri Oct 31 06:32:56 2014
@@ -21,9 +21,11 @@ package org.apache.jackrabbit.oak.plugin
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import javax.annotation.CheckForNull;
+import com.google.common.collect.Sets;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -88,19 +90,39 @@ public class IndexPlanner {
//TODO Need a way to have better cost estimate to indicate that
//this index can evaluate more propertyRestrictions natively (if more props are indexed)
//For now we reduce cost per entry
+ int costPerEntryFactor = indexedProps.size();
+
+ // Restrict matching index when declaringNodeTypes declared
+ if (defn.hasDeclaredNodeTypes()) {
+ if (supportsNodeTypes(filter)) {
+ // Reduce cost per entry by a small factor because number of nodes would be less
+ costPerEntryFactor += 1;
+ } else {
+ return null;
+ }
+ }
+ //this index can evaluate more propertyRestrictions natively (if more props are indexed)
+ //For now we reduce cost per entry
IndexPlan.Builder plan = defaultPlan();
if (plan != null) {
- return plan.setCostPerEntry(1.0 / indexedProps.size());
+ return plan.setCostPerEntry(1.0 / costPerEntryFactor);
}
}
//TODO Support for path restrictions
- //TODO support for NodeTypes
//TODO Support for property existence queries
//TODO support for nodeName queries
return null;
}
+ /**
+ * Determines if NodeTypes as defined in Filter are supported by current index
+ */
+ private boolean supportsNodeTypes(Filter filter) {
+ return !Sets
+ .intersection(defn.getDeclaringNodeTypes(), getSuperTypes(filter)).isEmpty();
+ }
+
private IndexPlan.Builder defaultPlan() {
return new IndexPlan.Builder()
.setCostPerExecution(1) // we're local. Low-cost
@@ -149,4 +171,8 @@ public class IndexPlanner {
}
return orderEntries;
}
+
+ private static Set<String> getSuperTypes(Filter filter) {
+ return filter.matchesAllTypes() ? Collections.<String>emptySet() : filter.getSupertypes();
+ }
}
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java?rev=1635689&r1=1635688&r2=1635689&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java Fri Oct 31 06:32:56 2014
@@ -29,6 +29,8 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -36,6 +38,7 @@ import org.apache.jackrabbit.oak.api.Pro
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
+import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -81,13 +84,23 @@ public class LuceneIndexEditor implement
private boolean propertiesChanged = false;
- LuceneIndexEditor(NodeBuilder definition, Analyzer analyzer,
- IndexUpdateCallback updateCallback) throws CommitFailedException {
+ private NodeState root;
+
+ private final Predicate typePredicate;
+
+ LuceneIndexEditor(NodeState root, NodeBuilder definition, Analyzer analyzer,
+ IndexUpdateCallback updateCallback) throws CommitFailedException {
this.parent = null;
this.name = null;
this.path = "/";
this.context = new LuceneIndexEditorContext(definition, analyzer,
updateCallback);
+ this.root = root;
+ if (context.getDefinition().hasDeclaredNodeTypes()) {
+ typePredicate = new TypePredicate(root, context.getDefinition().getDeclaringNodeTypes());
+ } else {
+ typePredicate = Predicates.alwaysTrue();
+ }
}
private LuceneIndexEditor(LuceneIndexEditor parent, String name) {
@@ -95,6 +108,8 @@ public class LuceneIndexEditor implement
this.name = name;
this.path = null;
this.context = parent.context;
+ this.root = parent.root;
+ this.typePredicate = parent.typePredicate;
}
public String getPath() {
@@ -200,6 +215,11 @@ public class LuceneIndexEditor implement
//TODO Possibly we can add support for compound properties like foo/bar
//i.e. support for relative path restrictions
+ // Check for declaringNodeType validity
+ if (!typePredicate.apply(state)) {
+ return null;
+ }
+
List<Field> fields = new ArrayList<Field>();
boolean dirty = false;
for (PropertyState property : state.getProperties()) {
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java?rev=1635689&r1=1635688&r2=1635689&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java Fri Oct 31 06:32:56 2014
@@ -51,7 +51,7 @@ public class LuceneIndexEditorProvider i
String type, NodeBuilder definition, NodeState root, IndexUpdateCallback callback)
throws CommitFailedException {
if (TYPE_LUCENE.equals(type)) {
- return new LuceneIndexEditor(definition, analyzer, callback);
+ return new LuceneIndexEditor(root, definition, analyzer, callback);
}
return null;
}
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1635689&r1=1635688&r2=1635689&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java Fri Oct 31 06:32:56 2014
@@ -29,6 +29,7 @@ import java.util.Set;
import javax.jcr.PropertyType;
import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.Oak;
@@ -118,6 +119,7 @@ public class LucenePropertyIndexTest ext
@Test
public void indexSelectionVsNodeType() throws Exception {
Tree luceneIndex = createIndex("test1", of("propa"));
+ // decrease cost of lucene property index
luceneIndex.setProperty(IndexConstants.ENTRY_COUNT_PROPERTY_NAME, 5L, Type.LONG);
// Decrease cost of node type index
@@ -138,13 +140,79 @@ public class LucenePropertyIndexTest ext
root.commit();
String propaQuery = "select [jcr:path] from [nt:unstructured] where [propa] = 'foo'";
- String explain = explain(propaQuery);
assertThat(explain(propaQuery), containsString("lucene:test1"));
assertQuery(propaQuery, paths);
}
@Test
+ public void declaringNodeTypeSameProp() throws Exception {
+ createIndex("test1", of("propa"));
+
+ Tree indexWithType = createIndex("test2", of("propa"));
+ indexWithType.setProperty(PropertyStates
+ .createProperty(IndexConstants.DECLARING_NODE_TYPES, of("nt:unstructured"),
+ Type.STRINGS));
+
+ Tree test = root.getTree("/").addChild("test");
+ test.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ root.commit();
+
+ Tree a = test.addChild("a");
+ a.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ a.setProperty("propa", "foo");
+ Tree b = test.addChild("b");
+ b.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ b.setProperty("propa", "foo");
+
+ test.addChild("c").setProperty("propa", "foo");
+ test.addChild("d").setProperty("propa", "foo");
+
+ root.commit();
+
+ String propabQuery = "select [jcr:path] from [nt:unstructured] where [propa] = 'foo'";
+ assertThat(explain(propabQuery), containsString("lucene:test2"));
+ assertQuery(propabQuery, asList("/test/a", "/test/b"));
+
+ String propcdQuery = "select [jcr:path] from [nt:base] where [propa] = 'foo'";
+ assertThat(explain(propcdQuery), containsString("lucene:test1"));
+ assertQuery(propcdQuery, asList("/test/a", "/test/b", "/test/c", "/test/d"));
+ }
+
+ @Test
+ public void declaringNodeTypeSingleIndex() throws Exception {
+ Tree indexWithType = createIndex("test2", of("propa", "propb"));
+ indexWithType.setProperty(PropertyStates
+ .createProperty(IndexConstants.DECLARING_NODE_TYPES, of("nt:unstructured"),
+ Type.STRINGS));
+
+ Tree test = root.getTree("/").addChild("test");
+ test.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ root.commit();
+
+ Tree a = test.addChild("a");
+ a.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ a.setProperty("propa", "foo");
+ a.setProperty("propb", "baz");
+
+ Tree b = test.addChild("b");
+ b.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ b.setProperty("propa", "foo");
+ b.setProperty("propb", "baz");
+
+ root.commit();
+
+ String propabQuery = "select [jcr:path] from [nt:unstructured] where [propb] = 'baz' and " +
+ "[propa] = 'foo'";
+ assertThat(explain(propabQuery), containsString("lucene:test2"));
+ assertQuery(propabQuery, asList("/test/a", "/test/b"));
+
+ String propNoIdxQuery = "select [jcr:path] from [nt:base] where [propb] = 'baz'";
+ assertThat(explain(propNoIdxQuery), containsString("no-index"));
+ assertQuery(propNoIdxQuery, ImmutableList.<String>of());
+ }
+
+ @Test
public void rangeQueriesWithLong() throws Exception {
Tree idx = createIndex("test1", of("propa", "propb"));
Tree propIdx = idx.addChild(PROP_NODE).addChild("propa");