Author: chetanm
Date: Wed Oct 8 10:10:01 2014
New Revision: 1630055
URL: http://svn.apache.org/r1630055
Log:
OAK-2119 - AggregateIndex should support AdvanceQueryIndex
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java?rev=1630055&r1=1630054&r2=1630055&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java
Wed Oct 8 10:10:01 2014
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.oak.plugins.index.aggregate;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -24,6 +25,10 @@ import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.query.fulltext.FullTextAnd;
import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
@@ -36,59 +41,62 @@ import org.apache.jackrabbit.oak.spi.que
import org.apache.jackrabbit.oak.spi.query.Cursors.AbstractCursor;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.IndexRow;
-import org.apache.jackrabbit.oak.spi.query.QueryIndex.FulltextQueryIndex;
import org.apache.jackrabbit.oak.spi.state.NodeState;
-import com.google.common.base.Function;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
+import static
org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvanceFulltextQueryIndex;
/**
* A virtual full-text that can aggregate nodes based on aggregate definitions.
* Internally, it uses another full-text index.
*/
-public class AggregateIndex implements FulltextQueryIndex {
+public class AggregateIndex implements AdvanceFulltextQueryIndex {
- private final FulltextQueryIndex baseIndex;
+ private final AdvanceFulltextQueryIndex baseIndex;
- public AggregateIndex(FulltextQueryIndex baseIndex) {
+ public AggregateIndex(AdvanceFulltextQueryIndex baseIndex) {
this.baseIndex = baseIndex;
}
@Override
public double getCost(Filter filter, NodeState rootState) {
+ throw new UnsupportedOperationException("Not supported as implementing
AdvancedQueryIndex");
+ }
+
+ @Override
+ public Cursor query(Filter filter, NodeState rootState) {
+ throw new UnsupportedOperationException("Not supported as implementing
AdvancedQueryIndex");
+ }
+
+ @Override
+ public List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder,
NodeState rootState) {
if (baseIndex == null) {
- return Double.POSITIVE_INFINITY;
+ return Collections.emptyList();
}
- double localCost = Double.POSITIVE_INFINITY;
- FullTextExpression e = filter.getFullTextConstraint();
- if (e != null && hasCompositeExpression(e)) {
- localCost = flattenCost(e, filter, baseIndex, rootState);
- }
- double baseCost = baseIndex.getCost(filter, rootState);
- return Math.min(localCost, baseCost) - 0.05;
+ return baseIndex.getPlans(filter, sortOrder, rootState);
}
@Override
- public Cursor query(Filter filter, NodeState rootState) {
- // pass-through impl
+ public Cursor query(IndexPlan plan, NodeState rootState) {
+
if (baseIndex.getNodeAggregator() == null) {
- return baseIndex.query(filter, rootState);
+ return baseIndex.query(plan, rootState);
}
- return newCursor(filter, baseIndex, rootState);
+ return newCursor(plan, baseIndex, rootState);
}
- private static Cursor newCursor(Filter f, FulltextQueryIndex index,
- NodeState state) {
+ private static Cursor newCursor(IndexPlan plan, AdvanceFulltextQueryIndex
index,
+ NodeState state) {
+ Filter f = plan.getFilter();
FullTextExpression e = f.getFullTextConstraint();
if (hasCompositeExpression(e)) {
- Cursor c = flatten(e, f, index, state);
+ Cursor c = flatten(e, plan, index, state);
if (c != null) {
return c;
}
}
- return new AggregationCursor(index.query(newAggregationFilter(f, null),
+
+ IndexPlan newPlan = newPlanWithAggregationFilter(plan, null);
+ return new AggregationCursor(index.query(newPlan,
state), index.getNodeAggregator(), state);
}
@@ -143,17 +151,18 @@ public class AggregateIndex implements F
}
private static Cursor flatten(FullTextExpression constraint,
- final Filter filter, final FulltextQueryIndex index,
+ final IndexPlan plan, final AdvanceFulltextQueryIndex index,
final NodeState state) {
if (constraint == null) {
return null;
}
+ final Filter filter = plan.getFilter();
final AtomicReference<Cursor> result = new AtomicReference<Cursor>();
constraint.accept(new FullTextVisitor() {
@Override
public boolean visit(FullTextTerm term) {
- result.set(filterToCursor(newAggregationFilter(filter, term),
+ result.set(filterToCursor(newPlanWithAggregationFilter(plan,
term),
index, state));
return true;
}
@@ -161,10 +170,10 @@ public class AggregateIndex implements F
@Override
public boolean visit(FullTextAnd and) {
Iterator<FullTextExpression> iterator = and.list.iterator();
- Cursor c = flatten(iterator.next(), filter, index, state);
+ Cursor c = flatten(iterator.next(), plan, index, state);
while (iterator.hasNext()) {
FullTextExpression input = iterator.next();
- Cursor newC = flatten(input, filter, index, state);
+ Cursor newC = flatten(input, plan, index, state);
c = Cursors.newIntersectionCursor(c, newC,
filter.getQueryEngineSettings());
}
@@ -178,7 +187,7 @@ public class AggregateIndex implements F
new Function<FullTextExpression, Cursor>() {
@Override
public Cursor apply(FullTextExpression input) {
- return flatten(input, filter, index, state);
+ return flatten(input, plan, index, state);
}
});
result.set(Cursors.newConcatCursor(cursors,
@@ -189,65 +198,35 @@ public class AggregateIndex implements F
return result.get();
}
- private static double flattenCost(FullTextExpression constraint,
- final Filter filter, final FulltextQueryIndex index,
- final NodeState state) {
- if (constraint == null) {
- return Double.POSITIVE_INFINITY;
- }
- final AtomicReference<Double> result = new AtomicReference<Double>();
- result.set(0d);
- constraint.accept(new FullTextVisitor() {
-
- @Override
- public boolean visit(FullTextTerm term) {
- result.set(result.get() +
index.getCost(newAggregationFilter(filter, term), state));
- return true;
- }
-
- @Override
- public boolean visit(FullTextAnd and) {
- for (FullTextExpression input : and.list) {
- double d = flattenCost(input, filter, index, state);
- result.set(result.get() + d);
- }
- return true;
- }
-
- @Override
- public boolean visit(FullTextOr or) {
- for (FullTextExpression input : or.list) {
- double d = flattenCost(input, filter, index, state);
- result.set(result.get() + d);
- }
- return true;
- }
- });
- return result.get();
- }
-
- private static Cursor filterToCursor(Filter f, FulltextQueryIndex index,
+ private static Cursor filterToCursor(IndexPlan plan,
AdvanceFulltextQueryIndex index,
NodeState state) {
- return new AggregationCursor(index.query(f, state),
+ return new AggregationCursor(index.query(plan, state),
index.getNodeAggregator(), state);
}
- private static Filter newAggregationFilter(Filter filter,
FullTextExpression exp) {
- FilterImpl f = new FilterImpl(filter);
+ private static IndexPlan newPlanWithAggregationFilter(IndexPlan plan,
FullTextExpression exp) {
+ FilterImpl f = new FilterImpl(plan.getFilter());
// disables node type checks for now
f.setMatchesAllTypes(true);
if (exp != null) {
f.setFullTextConstraint(exp);
}
- return f;
+ IndexPlan copy = plan.copy();
+ copy.setFilter(f);
+ return copy;
}
@Override
public String getPlan(Filter filter, NodeState rootState) {
+ throw new UnsupportedOperationException("Not supported as implementing
AdvancedQueryIndex");
+ }
+
+ @Override
+ public String getPlanDescription(IndexPlan plan, NodeState root) {
if (baseIndex == null) {
return "aggregate no-index";
}
- return "aggregate " + baseIndex.getPlan(filter, rootState);
+ return "aggregate " + baseIndex.getPlanDescription(plan, root);
}
@Override
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexProvider.java?rev=1630055&r1=1630054&r2=1630055&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexProvider.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexProvider.java
Wed Oct 8 10:10:01 2014
@@ -22,10 +22,11 @@ import java.util.List;
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
-import org.apache.jackrabbit.oak.spi.query.QueryIndex.FulltextQueryIndex;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import static
org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvanceFulltextQueryIndex;
+
/**
* A provider for aggregate indexes. It wraps all full-text query indexes.
*/
@@ -47,11 +48,10 @@ public class AggregateIndexProvider impl
public List<? extends QueryIndex> getQueryIndexes(NodeState state) {
List<? extends QueryIndex> list = baseProvider.getQueryIndexes(state);
ArrayList<AggregateIndex> aggregateList = new
ArrayList<AggregateIndex>();
- for (int i = 0; i < list.size(); i++) {
- QueryIndex index = list.get(i);
- if (index instanceof FulltextQueryIndex) {
+ for (QueryIndex index : list) {
+ if (index instanceof AdvanceFulltextQueryIndex) {
aggregateList
- .add(new AggregateIndex((FulltextQueryIndex) index));
+ .add(new AggregateIndex((AdvanceFulltextQueryIndex)
index));
}
}
return aggregateList;
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java?rev=1630055&r1=1630054&r2=1630055&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
Wed Oct 8 10:10:01 2014
@@ -131,6 +131,10 @@ public interface QueryIndex {
}
+ public interface AdvanceFulltextQueryIndex extends FulltextQueryIndex,
AdvancedQueryIndex {
+
+ }
+
/**
* An query index that may support using multiple access orders
* (returning the rows in a specific order), and that can provide detailed
@@ -181,7 +185,7 @@ public interface QueryIndex {
/**
* An index plan.
*/
- public interface IndexPlan {
+ public interface IndexPlan extends Cloneable{
/**
* The cost to execute the query once. The returned value should
@@ -261,7 +265,6 @@ public interface QueryIndex {
/**
* The path prefix for this index plan.
- * @return
*/
String getPathPrefix();
@@ -274,6 +277,14 @@ public interface QueryIndex {
*/
@CheckForNull
PropertyRestriction getPropertyRestriction();
+
+ /**
+ * Creates a cloned copy of current plan. Mostly used when the filter
needs to be
+ * modified for a given call
+ *
+ * @return clone of current plan
+ */
+ IndexPlan copy();
/**
* A builder for index plans.
@@ -463,6 +474,20 @@ public interface QueryIndex {
public String getPathPrefix() {
return pathPrefix;
}
+
+ @Override
+ protected Object clone() throws CloneNotSupportedException
{
+ return super.clone();
+ }
+
+ @Override
+ public IndexPlan copy() {
+ try {
+ return (IndexPlan) super.clone();
+ } catch (CloneNotSupportedException e){
+ throw new IllegalStateException(e);
+ }
+ }
};
}
@@ -488,7 +513,7 @@ public interface QueryIndex {
/**
* The sort order (ascending or descending).
*/
- public enum Order { ASCENDING, DESCENDING };
+ public enum Order { ASCENDING, DESCENDING }
private final Order order;
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java?rev=1630055&r1=1630054&r2=1630055&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java
Wed Oct 8 10:10:01 2014
@@ -19,7 +19,10 @@
package org.apache.jackrabbit.oak.query.index;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.apache.jackrabbit.oak.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan;
import org.junit.Test;
@@ -36,5 +39,22 @@ public class AdvancedIndexTest {
b.setEstimatedEntryCount(20);
assertEquals(10, plan.getEstimatedEntryCount());
}
+
+ @Test
+ public void copy() throws Exception{
+ Filter f = new FilterImpl(null, "SELECT * FROM [nt:file]", new
QueryEngineSettings());
+ IndexPlan.Builder b = new IndexPlan.Builder();
+ IndexPlan plan1 =
b.setEstimatedEntryCount(10).setFilter(f).setDelayed(true).build();
+
+ IndexPlan plan2 = plan1.copy();
+ plan2.setFilter(new FilterImpl(null, "SELECT * FROM
[oak:Unstructured]", new QueryEngineSettings()));
+
+ assertEquals(plan1.getEstimatedEntryCount(), 10);
+ assertEquals(plan2.getEstimatedEntryCount(), 10);
+ assertTrue(plan1.isDelayed());
+ assertTrue(plan2.isDelayed());
+ assertEquals(plan1.getFilter().getQueryStatement(), "SELECT * FROM
[nt:file]");
+ assertEquals(plan2.getFilter().getQueryStatement(), "SELECT * FROM
[oak:Unstructured]");
+ }
}