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 th...@apache.org on 2018/03/28 07:27:07 UTC

svn commit: r1827895 - in /jackrabbit/oak/trunk/oak-lucene/src: main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java

Author: thomasm
Date: Wed Mar 28 07:27:07 2018
New Revision: 1827895

URL: http://svn.apache.org/viewvc?rev=1827895&view=rev
Log:
OAK-7379 Lucene Index: per-column selectivity, assume 5 unique entries

Modified:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
    jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1827895&r1=1827894&r2=1827895&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java Wed Mar 28 07:27:07 2018
@@ -48,6 +48,7 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextVisitor;
 import org.apache.jackrabbit.oak.spi.query.Filter;
 import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,7 +61,6 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.commons.PathUtils.getDepth;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
-import static org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
 import static org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan;
 import static org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
 
@@ -284,7 +284,7 @@ class IndexPlanner {
 
             // Set a index based guess here. Unique would set its own value below
             if (useActualEntryCount && !definition.isEntryCountDefined()) {
-                int maxPossibleNumDocs = getMaxPossibleNumDocs(result.propDefns);
+                int maxPossibleNumDocs = getMaxPossibleNumDocs(result.propDefns, filter);
                 if (maxPossibleNumDocs >= 0) {
                     plan.setEstimatedEntryCount(maxPossibleNumDocs);
                 }
@@ -745,7 +745,7 @@ class IndexPlanner {
         return indexNode.getIndexStatistics().numDocs();
     }
 
-    private int getMaxPossibleNumDocs(Map<String, PropertyDefinition> propDefns) {
+    private int getMaxPossibleNumDocs(Map<String, PropertyDefinition> propDefns, Filter filter) {
         IndexStatistics indexStatistics = indexNode.getIndexStatistics();
         int minNumDocs = indexStatistics.numDocs();
         for (Map.Entry<String, PropertyDefinition> propDef : propDefns.entrySet()) {
@@ -760,6 +760,24 @@ class IndexPlanner {
 
             int weight = propDef.getValue().weight;
 
+            PropertyRestriction pr = filter.getPropertyRestriction(key);
+            if (pr != null) {
+                if (pr.isNotNullRestriction()) {
+                    // don't use weight for "is not null" restrictions
+                    weight = 1;
+                } else {
+                    if (weight > 1) {
+                        // for non-equality conditions such as
+                        // where x > 1, x < 2, x like y,...:
+                        // use a maximum weight of 3,
+                        // so assume we read at least 30%
+                        if (!isEqualityRestriction(pr)) {
+                            weight = Math.min(3, weight);
+                        }
+                    }
+                }
+            }
+
             if (weight > 1) {
                 // use it to scale down the doc count - in broad strokes, we can think of weight
                 // as number of terms for the field with all terms getting equal share of
@@ -778,6 +796,10 @@ class IndexPlanner {
         return minNumDocs;
     }
 
+    private static boolean isEqualityRestriction(PropertyRestriction pr) {
+        return pr.first != null && pr.first == pr.last;
+    }
+
     private List<OrderEntry> createSortOrder(IndexingRule rule) {
         if (sortOrder == null) {
             return Collections.emptyList();

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java?rev=1827895&r1=1827894&r2=1827895&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java Wed Mar 28 07:27:07 2018
@@ -1309,6 +1309,29 @@ public class IndexPlannerTest {
         assertEquals(1.0, plan.getCostPerExecution(), 0);
         assertEquals(1.0, plan.getCostPerEntry(), 0);
 
+        // Query on "foo" is not null
+        filter = createFilter("nt:base");
+        filter.restrictProperty("foo", Operator.NOT_EQUAL, null);
+        planner = new IndexPlanner(node, "/test", filter, Collections.emptyList());
+        plan = planner.getPlan();
+        assertEquals(numOfDocs, plan.getEstimatedEntryCount());
+
+        // Query on "foo" like x
+        filter = createFilter("nt:base");
+        filter.restrictProperty("foo", Operator.LIKE, PropertyValues.newString("bar%"));
+        planner = new IndexPlanner(node, "/test", filter, Collections.emptyList());
+        plan = planner.getPlan();
+        // weight of 3
+        assertEquals(numOfDocs / 3 + 1, plan.getEstimatedEntryCount());
+
+        // Query on "foo" > x
+        filter = createFilter("nt:base");
+        filter.restrictProperty("foo", Operator.GREATER_OR_EQUAL, PropertyValues.newString("bar"));
+        planner = new IndexPlanner(node, "/test", filter, Collections.emptyList());
+        plan = planner.getPlan();
+        // weight of 3
+        assertEquals(numOfDocs / 3 + 1, plan.getEstimatedEntryCount());
+
         // Query on "foo1"
         filter = createFilter("nt:base");
         filter.restrictProperty("foo1", Operator.EQUAL, PropertyValues.newString("bar1"));