Author: thomasm
Date: Wed Feb 5 14:15:17 2014
New Revision: 1564782
URL: http://svn.apache.org/r1564782
Log:
OAK-1389 Query: an index is used even where traversing is faster
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.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/PropertyIndexLookup.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.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/RelativePathTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
Wed Feb 5 14:15:17 2014
@@ -122,7 +122,6 @@ class PropertyIndex implements QueryInde
@Override
public double getCost(Filter filter, NodeState root) {
- // TODO don't call getCost for such queries
if (filter.getFullTextConstraint() != null) {
// not an appropriate index for full-text search
return Double.POSITIVE_INFINITY;
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=1564782&r1=1564781&r2=1564782&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
Wed Feb 5 14:15:17 2014
@@ -113,7 +113,8 @@ class PropertyIndexEditor implements Ind
// get property names
PropertyState names = definition.getProperty(PROPERTY_NAMES);
- if (names.count() == 1) { // OAK-1273: optimize for the common case
+ if (names.count() == 1) {
+ // OAK-1273: optimize for the common case
this.propertyNames = singleton(names.getValue(NAME, 0));
} else {
this.propertyNames = newHashSet(names.getValue(NAMES));
@@ -198,7 +199,9 @@ class PropertyIndexEditor implements Ind
@Override
public void enter(NodeState before, NodeState after) {
- typeChanged = (typePredicate == null); // disables property name checks
+ // disables property name checks
+ typeChanged = typePredicate == null;
+
beforeKeys = null;
afterKeys = null;
}
@@ -271,7 +274,7 @@ class PropertyIndexEditor implements Ind
}
}
- private boolean isTypeProperty(String name) {
+ private static boolean isTypeProperty(String name) {
return JCR_PRIMARYTYPE.equals(name) || JCR_MIXINTYPES.equals(name);
}
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=1564782&r1=1564781&r2=1564782&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
Wed Feb 5 14:15:17 2014
@@ -60,6 +60,14 @@ import org.apache.jackrabbit.oak.spi.sta
*/
public class PropertyIndexLookup {
+ /**
+ * The cost overhead to use the index in number of read operations.
+ */
+ private static final int COST_OVERHEAD = 2;
+
+ /**
+ * The maximum cost when the index can be used.
+ */
private static final int MAX_COST = 100;
/** Index storage strategy */
@@ -122,7 +130,8 @@ public class PropertyIndexLookup {
if (indexMeta == null) {
return Double.POSITIVE_INFINITY;
}
- return getStrategy(indexMeta).count(indexMeta, encode(value),
MAX_COST);
+ return COST_OVERHEAD +
+ getStrategy(indexMeta).count(indexMeta, encode(value),
MAX_COST);
}
/**
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
Wed Feb 5 14:15:17 2014
@@ -39,7 +39,7 @@ public interface Query {
void bindValue(String key, PropertyValue value);
- void setTraversalFallback(boolean traversal);
+ void setTraversalEnabled(boolean traversalEnabled);
void prepare();
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
Wed Feb 5 14:15:17 2014
@@ -58,11 +58,10 @@ public abstract class QueryEngineImpl im
JQOM);
/**
- * Whether fallback to the traversing index is supported if no other index
- * is available. This is enabled by default and can be disabled for testing
- * purposes.
+ * Whether node traversal is enabled. This is enabled by default, and can
be
+ * disabled for testing purposes.
*/
- private boolean traversalFallback = true;
+ private boolean traversalEnabled = true;
/**
* @return Execution context for a single query execution.
@@ -163,13 +162,13 @@ public abstract class QueryEngineImpl im
q.bindValue(e.getKey(), e.getValue());
}
}
- q.setTraversalFallback(traversalFallback);
+ q.setTraversalEnabled(traversalEnabled);
q.prepare();
return q.executeQuery();
}
- protected void setTraversalFallback(boolean traversal) {
- this.traversalFallback = traversal;
+ protected void setTraversalEnabled(boolean traversalEnabled) {
+ this.traversalEnabled = traversalEnabled;
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
Wed Feb 5 14:15:17 2014
@@ -99,7 +99,7 @@ public class QueryImpl implements Query
* is available. This is enabled by default and can be disabled for testing
* purposes.
*/
- private boolean traversalFallback = true;
+ private boolean traversalEnabled = true;
private OrderingImpl[] orderings;
private ColumnImpl[] columns;
@@ -424,7 +424,7 @@ public class QueryImpl implements Query
@Override
public String getPlan() {
- return source.getPlan(context.getBaseState()); // + " cost: " +
estimatedCost;
+ return source.getPlan(context.getBaseState());
}
@Override
@@ -597,18 +597,18 @@ public class QueryImpl implements Query
}
@Override
- public void setTraversalFallback(boolean traversal) {
- this.traversalFallback = traversal;
+ public void setTraversalEnabled(boolean traversalEnabled) {
+ this.traversalEnabled = traversalEnabled;
}
public SelectorExecutionPlan getBestSelectorExecutionPlan(FilterImpl
filter) {
return getBestSelectorExecutionPlan(context.getBaseState(), filter,
- context.getIndexProvider(), traversalFallback);
+ context.getIndexProvider(), traversalEnabled);
}
private static SelectorExecutionPlan getBestSelectorExecutionPlan(
NodeState rootState, FilterImpl filter,
- QueryIndexProvider indexProvider, boolean traversalFallback) {
+ QueryIndexProvider indexProvider, boolean traversalEnabled) {
QueryIndex best = null;
if (LOG.isDebugEnabled()) {
LOG.debug("cost using filter " + filter);
@@ -626,9 +626,14 @@ public class QueryImpl implements Query
}
}
- if (bestCost == Double.POSITIVE_INFINITY && traversalFallback) {
- best = new TraversingIndex();
- bestCost = best.getCost(filter, rootState);
+
+ if (traversalEnabled) {
+ QueryIndex traversal = new TraversingIndex();
+ double cost = traversal.getCost(filter, rootState);
+ if (cost < bestCost || bestCost == Double.POSITIVE_INFINITY) {
+ bestCost = cost;
+ best = traversal;
+ }
}
SelectorExecutionPlan plan = new SelectorExecutionPlan();
plan.filter = filter;
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
Wed Feb 5 14:15:17 2014
@@ -96,9 +96,9 @@ public class UnionQueryImpl implements Q
}
@Override
- public void setTraversalFallback(boolean traversal) {
- left.setTraversalFallback(traversal);
- right.setTraversalFallback(traversal);
+ public void setTraversalEnabled(boolean traversal) {
+ left.setTraversalEnabled(traversal);
+ right.setTraversalEnabled(traversal);
}
@Override
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
Wed Feb 5 14:15:17 2014
@@ -38,6 +38,10 @@ public class TraversingIndex implements
@Override
public double getCost(Filter filter, NodeState rootState) {
+ if (filter.getFullTextConstraint() != null) {
+ // not an appropriate index for full-text search
+ return Double.POSITIVE_INFINITY;
+ }
if (filter.isAlwaysFalse()) {
return 0;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexQueryTest.java
Wed Feb 5 14:15:17 2014
@@ -60,7 +60,7 @@ public class NodeTypeIndexQueryTest exte
@Test
public void query() throws Exception {
- setTravesalFallback(false);
+ setTravesalEnabled(false);
Tree t = root.getTree("/");
child(t, "a", "nt:unstructured");
@@ -82,6 +82,6 @@ public class NodeTypeIndexQueryTest exte
assertQuery("select [jcr:path] from [nt:folder] ", of("/c", "/d"));
assertQuery("select [jcr:path] from [mix:language] ", of("/e", "/f"));
- setTravesalFallback(true);
+ setTravesalEnabled(true);
}
}
\ No newline at end of file
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexTest.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexTest.java
Wed Feb 5 14:15:17 2014
@@ -85,15 +85,15 @@ public class NodeTypeIndexTest {
FilterImpl filter;
filter = createFilter(rootState, JcrConstants.NT_FOLDER);
- assertEquals(2.0, index.getCost(filter, rootState), 0.0);
+ assertEquals(6.0, index.getCost(filter, rootState), 0.0);
checkCursor(index.query(filter, rootState), "/folder-1", "/folder-2");
filter = createFilter(rootState, JcrConstants.NT_FILE);
- assertEquals(1.0, index.getCost(filter, rootState), 0.0);
+ assertEquals(5.0, index.getCost(filter, rootState), 0.0);
checkCursor(index.query(filter, rootState), "/file-1");
filter = createFilter(rootState, JcrConstants.NT_HIERARCHYNODE);
- assertEquals(3.0, index.getCost(filter, rootState), 0.0);
+ assertEquals(7.0, index.getCost(filter, rootState), 0.0);
checkCursor(index.query(filter, rootState), "/folder-1", "/folder-2",
"/file-1");
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/MultipleIndicesTest.java
Wed Feb 5 14:15:17 2014
@@ -74,7 +74,7 @@ public class MultipleIndicesTest extends
content.addChild("z").setProperty("pid", "bar");
root.commit();
- setTravesalFallback(false);
+ setTravesalEnabled(false);
assertQuery("select [jcr:path] from [nt:base] where [cid] = 'foo'",
new ArrayList<String>());
@@ -86,7 +86,7 @@ public class MultipleIndicesTest extends
assertQuery("select [jcr:path] from [nt:base] where [pid] = 'baz'",
ImmutableList.of("/content/y"));
- setTravesalFallback(true);
+ setTravesalEnabled(true);
}
/**
@@ -106,7 +106,7 @@ public class MultipleIndicesTest extends
t.addChild("node-3").setProperty("pid", ":");
root.commit();
- setTravesalFallback(false);
+ setTravesalEnabled(false);
assertQuery("select [jcr:path] from [nt:base] where [pid] = 'value'",
ImmutableList.of("/node-1"));
assertQuery("select [jcr:path] from [nt:base] where [pid] = ''",
@@ -114,6 +114,6 @@ public class MultipleIndicesTest extends
assertQuery("select [jcr:path] from [nt:base] where [pid] = ':'",
ImmutableList.of("/node-3"));
- setTravesalFallback(true);
+ setTravesalEnabled(true);
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
Wed Feb 5 14:15:17 2014
@@ -86,19 +86,19 @@ public class PropertyIndexTest {
double cost;
cost = lookup.getCost(f, "foo", PropertyValues.newString("x1"));
- assertTrue("cost: " + cost, cost >= 4.5 && cost <= 5.5);
+ assertTrue("cost: " + cost, cost >= 6.5 && cost <= 7.5);
cost = lookup.getCost(f, "foo", PropertyValues.newString(
Arrays.asList("x1", "x2")));
- assertTrue("cost: " + cost, cost >= 9.5 && cost <= 10.5);
+ assertTrue("cost: " + cost, cost >= 11.5 && cost <= 12.5);
cost = lookup.getCost(f, "foo", PropertyValues.newString(
Arrays.asList("x1", "x2", "x3", "x4", "x5")));
- assertTrue("cost: " + cost, cost >= 24.5 && cost <= 25.5);
+ assertTrue("cost: " + cost, cost >= 26.5 && cost <= 27.5);
cost = lookup.getCost(f, "foo", PropertyValues.newString(
Arrays.asList("x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8",
"x9", "x0")));
- assertTrue("cost: " + cost, cost >= 49.5 && cost <= 50.5);
+ assertTrue("cost: " + cost, cost >= 51.5 && cost <= 52.5);
cost = lookup.getCost(f, "foo", null);
assertTrue("cost: " + cost, cost >= MANY);
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/RelativePathTest.java
Wed Feb 5 14:15:17 2014
@@ -65,7 +65,7 @@ public class RelativePathTest extends Ab
t.addChild("c").addChild("x").setProperty("myProp", "foo");
t.setProperty("myProp", "foo");
root.commit();
- setTravesalFallback(false);
+ setTravesalEnabled(false);
assertQuery("select [jcr:path] from [nt:base] where [n/myProp] is not
null",
ImmutableList.of("/a", "/b"));
@@ -79,6 +79,6 @@ public class RelativePathTest extends Ab
assertQuery(
"select [jcr:path] from [nt:base] where [n/myProp] = 'foo'",
ImmutableList.of("/a"));
- setTravesalFallback(false);
+ setTravesalEnabled(false);
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java?rev=1564782&r1=1564781&r2=1564782&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
Wed Feb 5 14:15:17 2014
@@ -264,8 +264,8 @@ public abstract class AbstractQueryTest
return paths;
}
- protected void setTravesalFallback(boolean traversal) {
- ((QueryEngineImpl) qe).setTraversalFallback(traversal);
+ protected void setTravesalEnabled(boolean traversalEnabled) {
+ ((QueryEngineImpl) qe).setTraversalEnabled(traversalEnabled);
}
protected static String readRow(ResultRow row, boolean pathOnly) {