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]");
+    }
     
 }


Reply via email to