From 13383debe09c3d68372ad346e5c6c610dc7fea73 Mon Sep 17 00:00:00 2001
From: Vikas Saurabh <vsaurabh@adobe.com>
Date: Wed, 10 Dec 2014 21:31:08 +0530
Subject: [PATCH 4/4] OAK-2341: approximately scale property index cost using
 node counts fron counter index if path restriction is available

---
 .../strategy/ContentMirrorStoreStrategy.java       | 54 ++++++++++------------
 .../strategy/ContentMirrorStoreStrategyTest.java   |  1 -
 2 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
index 193aca2..dfd096b 100755
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
@@ -31,6 +31,7 @@ import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.plugins.index.counter.NodeCounterEditor;
+import org.apache.jackrabbit.oak.plugins.index.counter.jmx.NodeCounter;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
 import org.apache.jackrabbit.oak.query.FilterIterators;
 import org.apache.jackrabbit.oak.query.QueryEngineSettings;
@@ -202,8 +203,6 @@ public class ContentMirrorStoreStrategy implements IndexStoreStrategy {
         } else {
             int size = values.size();
             if (size != 0) {
-                long approxMax = 0;
-
                 PropertyState ec = indexMeta.getProperty(ENTRY_COUNT_PROPERTY_NAME);
                 if (ec != null) {
                     count = ec.getValue(Type.LONG);
@@ -223,6 +222,7 @@ public class ContentMirrorStoreStrategy implements IndexStoreStrategy {
                         count = (long) ((double) count / keyCount) + size;
                     }
                 } else {
+                    long approxMax = 0;
                     long approxCount = ApproximateCounter.getCountSync(index);
                     if (approxCount != -1) {
                         for (String p : values) {
@@ -236,20 +236,14 @@ public class ContentMirrorStoreStrategy implements IndexStoreStrategy {
                                 }
                             }
                         }
+
+                        if (approxMax > 0) {
+                            count = approxMax;
+                        }
                     }
                 }
 
                 if (count < 0) {
-                    String filterRootPath = null;
-                    if (filter != null &&
-                            filter.getPathRestriction().equals(Filter.PathRestriction.ALL_CHILDREN)) {
-                        filterRootPath = filter.getPath();
-                    }
-                    if (filterRootPath == null && approxMax > 0) {
-                        // we do have an approximation, and
-                        // there is no path filter
-                        count = approxMax;
-                    } else {
                         count = 0;
                         max = Math.max(10, max / size);
                         int i = 0;
@@ -262,16 +256,6 @@ public class ContentMirrorStoreStrategy implements IndexStoreStrategy {
                                 break;
                             }
                             NodeState s = index.getChildNode(p);
-                            if (filterRootPath != null && s.exists()) {
-                                // Descend directly to path restriction inside index tree
-                                for (String pathFragment : PathUtils
-                                        .elements(filterRootPath)) {
-                                    s = s.getChildNode(pathFragment);
-                                    if (!s.exists()) {
-                                        break;
-                                    }
-                                }
-                            }
                             if (s.exists()) {
                                 CountingNodeVisitor v = new CountingNodeVisitor(max);
                                 v.visit(s);
@@ -279,18 +263,30 @@ public class ContentMirrorStoreStrategy implements IndexStoreStrategy {
                             }
                             i++;
                         }
-                        if (approxMax > 0 && approxMax > count) {
-                            // we do have an approximation, and
-                            // it is higher than what we counted
-                            // (we don't count that far)
-                            count = approxMax;
-                        }
-                    }
                 }
             } else {
                 count = 0;
             }
         }
+
+        {
+            String filterRootPath = null;
+            if (filter != null &&
+                    filter.getPathRestriction().equals(Filter.PathRestriction.ALL_CHILDREN)) {
+                filterRootPath = filter.getPath();
+            }
+
+            if (filterRootPath != null) {
+                //scale cost according to path restriction
+                long totalNodesCount = NodeCounter.getEstimatedNodeCount(root, "/", true);
+                if (totalNodesCount != -1) {
+                    long filterPathCount = NodeCounter.getEstimatedNodeCount(root, filterRootPath, true);
+                    if (filterPathCount != -1) {
+                        count = (long) ((double) count / totalNodesCount * filterPathCount);
+                    }
+                }
+            }
+        }
         return count;
     }
 
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java
index 53bdb65..938be3a 100755
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java
@@ -195,7 +195,6 @@ public class ContentMirrorStoreStrategyTest {
                 store.count(root, indexMeta.getNodeState(), null, MAX_TRAVERSALS));
     }
 
-    @Ignore("OAK-2341")
     @Test
     public void testIndexCountersUsageWithPathRestriction() {
         final String SUB_PATH_NAME = "sub-path";
-- 
2.1.1

