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 2014/06/23 11:54:03 UTC

svn commit: r1604728 - in /jackrabbit/oak/branches/1.0: oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java

Author: thomasm
Date: Mon Jun 23 09:54:02 2014
New Revision: 1604728

URL: http://svn.apache.org/r1604728
Log:
OAK-1898 Query: Incorrect cost calculation for traversal

Modified:
    jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
    jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java

Modified: jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java?rev=1604728&r1=1604727&r2=1604728&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java Mon Jun 23 09:54:02 2014
@@ -49,7 +49,12 @@ public class TraversingIndex implements 
         if (filter.isAlwaysFalse()) {
             return 0;
         }
-        double nodeCount = 10000000;
+        
+        // worst case 100 million nodes
+        double nodeCount = 100000000;
+        // worst case 100 thousand children
+        double nodeCountChildren = 100000;
+        
         // if the path is from a join, then the depth is not correct
         // (the path might be the root node), but that's OK
         String path = filter.getPath();
@@ -62,9 +67,14 @@ public class TraversingIndex implements 
             break;
         case ALL_CHILDREN:
             if (!PathUtils.denotesRoot(path)) {
-                for (int depth = PathUtils.getDepth(path); depth > 0; depth--) {
-                    // estimate 10 child nodes per node
-                    nodeCount /= 10;
+                int depth = PathUtils.getDepth(path);
+                for (int i = depth; i > 0; i--) {
+                    // estimate 10 child nodes per node,
+                    // but higher than the cost for DIRECT_CHILDREN
+                    // (about 100'000)
+                    // in any case, the higher the depth of the path,
+                    // the lower the cost
+                    nodeCount = Math.max(nodeCountChildren * 2 - depth, nodeCount / 10);
                 }
             }
             break;
@@ -76,8 +86,10 @@ public class TraversingIndex implements 
             }
             break;
         case DIRECT_CHILDREN:
-            // we expect 1 million child nodes in the worst case
-            nodeCount = 1000000;
+            // estimate 100'000 children for now, 
+            // to ensure an index is used if there is one
+            // TODO we need to have better estimates, see also OAK-1898
+             nodeCount = nodeCountChildren;
             break;
         default:
             throw new IllegalArgumentException("Unknown restriction: " + restriction);

Modified: jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java?rev=1604728&r1=1604727&r2=1604728&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java (original)
+++ jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java Mon Jun 23 09:54:02 2014
@@ -44,7 +44,40 @@ public class QueryPlanTest extends Abstr
     }
     
     @Test
-    @Ignore("OAK-1155")
+    // OAK-1898
+    public void traversalVersusPropertyIndex() throws Exception {
+        Session session = getAdminSession();
+        QueryManager qm = session.getWorkspace().getQueryManager();
+        Node testRootNode = session.getRootNode().addNode("testroot");
+        Node n = testRootNode;
+        for (int i = 0; i < 20; i++) {
+            n.setProperty("depth", i + 2);
+            n = n.addNode("n", "oak:Unstructured");
+            n.addMixin("mix:referenceable");
+        }
+        session.save();
+       
+        String xpath = "/jcr:root/testroot/n/n/n/n/n/n/n//*[jcr:uuid]";
+        
+        Query q;
+        QueryResult result;
+        RowIterator it;
+        
+        q = qm.createQuery("explain " + xpath, "xpath");
+        result = q.execute();
+        it = result.getRows();
+        assertTrue(it.hasNext());
+        String plan = it.nextRow().getValue("plan").getString();
+        System.out.println("plan: " + plan);
+        // should not use the index on "jcr:uuid"
+        assertEquals("[nt:base] as [a] /* property jcr:uuid " + 
+                "where ([a].[jcr:uuid] is not null) and " + 
+                "(isdescendantnode([a], [/testroot/n/n/n/n/n/n/n])) */", 
+                plan);
+
+    }        
+    
+    @Test
     public void nodeType() throws Exception {
         Session session = getAdminSession();
         QueryManager qm = session.getWorkspace().getQueryManager();