jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thom...@apache.org
Subject svn commit: r1574491 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java
Date Wed, 05 Mar 2014 13:58:19 GMT
Author: thomasm
Date: Wed Mar  5 13:58:19 2014
New Revision: 1574491

URL: http://svn.apache.org/r1574491
Log:
OAK-622 Improve QueryIndex interface (WIP)

Added:
    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/spi/query/QueryIndex.java

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=1574491&r1=1574490&r2=1574491&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 Mar  5 13:58:19 2014
@@ -18,8 +18,12 @@
  */
 package org.apache.jackrabbit.oak.spi.query;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.annotation.CheckForNull;
 
+import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
@@ -125,104 +129,279 @@ public interface QueryIndex {
 
     }
 
-//    /**
-//     * Return the possible index plans for the given filter and sort order.
-//     * Please note this method is supposed to run quickly. That means it should
-//     * usually not read any data from the storage.
-//     *
-//     * @param filter the filter
-//     * @param sortOrder the sort order or null if no sorting is required
-//     * @param rootState root state of the current repository snapshot
-//     * @return the list of index plans (null if none)
-//     */
-//    List<IndexPlan> getPlans(Filter filter, List<Order> sortOrder, NodeState
rootState);
-//    
-//    /**
-//     * Get the query plan description (for logging purposes).
-//     *
-//     * @param plan the index plan
-//     * @return the query plan description
-//     */
-//    String getPlanDescription(IndexPlan plan);
-//    
-//    /**
-//     * Start a query. The filter and sort order of the index plan is to be used.
-//     *
-//     * @param plan the index plan to use
-//     * @param rootState root state of the current repository snapshot
-//     * @return a cursor to iterate over the result
-//     */
-//    Cursor query(IndexPlan plan, NodeState rootState);
-//    
-//    /**
-//     * An index plan.
-//     */
-//    public static class IndexPlan {
-//        
-//        /**
-//         * The cost to execute the query once. The returned value should
-//         * approximately match the number of disk read operations plus the
-//         * number of network roundtrips (worst case).
-//         */
-//        double costPerExecution;
-//        
-//        /**
-//         * The cost to read one entry from the cursor. The returned value should
-//         * approximately match the number of disk read operations plus the
-//         * number of network roundtrips (worst case).
-//         */
-//        double costPerEntry;
-//        
-//        /**
-//         * The estimated number of entries. This value does not have to be
-//         * accurate.
-//         */
-//        long estimatedEntryCount;
-//        
-//        /**
-//         * The filter to use.
-//         */
-//        Filter filter;
-//
-//        /**
-//         * Whether the index is not always up-to-date.
-//         */
-//        boolean isDelayed;
-//        
-//        /**
-//         * Whether the fulltext part of the filter is evaluated (possibly with
-//         * an extended syntax). If set, the fulltext part of the filter is not
-//         * evaluated any more within the query engine.
-//         */
-//        boolean isFulltextIndex;
-//        
-//        /**
-//         * Whether the cursor is able to read all properties from a node.
-//         */
-//        boolean includesNodeData;
-//        
-//        /**
-//         * The sort order of the returned entries, or null if unsorted.
-//         */
-//        List<Order> sortOrder;
-//        
-//    }
-//    
-//    /**
-//     * A sort order entry.
-//     */
-//    static class Order {
-//        
-//        /**
-//         * The property name on where to sort.
-//         */
-//        String propertyName;
-//
-//        /**
-//         * True for descending, false for ascending.
-//         */
-//        boolean descending;
-//        
-//    }
+    /**
+     * An query index that may support using multiple access orders
+     * (returning the rows in a specific order), and that can provide detailed
+     * information about the cost.
+     */
+    public interface AdvancedQueryIndex {
+
+        /**
+         * Return the possible index plans for the given filter and sort order.
+         * Please note this method is supposed to run quickly. That means it
+         * should usually not read any data from the storage.
+         * 
+         * @param filter the filter
+         * @param sortOrder the sort order or null if no sorting is required
+         * @param rootState root state of the current repository snapshot
+         * @return the list of index plans (null if none)
+         */
+        List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder,
+                NodeState rootState);
+
+        /**
+         * Get the query plan description (for logging purposes).
+         * 
+         * @param plan the index plan
+         * @return the query plan description
+         */
+        String getPlanDescription(IndexPlan plan);
+
+        /**
+         * Start a query. The filter and sort order of the index plan is to be
+         * used.
+         * 
+         * @param plan the index plan to use
+         * @param rootState root state of the current repository snapshot
+         * @return a cursor to iterate over the result
+         */
+        Cursor query(IndexPlan plan, NodeState rootState);
+
+    }
+
+    /**
+     * An index plan.
+     */
+    public interface IndexPlan {
+
+        /**
+         * The cost to execute the query once. The returned value should
+         * approximately match the number of disk read operations plus the
+         * number of network roundtrips (worst case).
+         * 
+         * @return the cost per execution, in estimated number of I/O operations
+         */
+        double getCostPerExecution();
+
+        /**
+         * The cost to read one entry from the cursor. The returned value should
+         * approximately match the number of disk read operations plus the
+         * number of network roundtrips (worst case).
+         * 
+         * @return the lookup cost per entry, in estimated number of I/O operations
+         */
+        double getCostPerEntry();
+
+        /**
+         * The estimated number of entries. This value does not have to be
+         * accurate.
+         * 
+         * @return the estimated number of entries
+         */
+        long getEstimatedEntryCount();
+
+        /**
+         * The filter to use.
+         * 
+         * @return the filter
+         */
+        Filter getFilter();
+
+        /**
+         * Whether the index is not always up-to-date.
+         * 
+         * @return whether the index might be updated asynchronously
+         */
+        boolean isDelayed();
+
+        /**
+         * Whether the fulltext part of the filter is evaluated (possibly with
+         * an extended syntax). If set, the fulltext part of the filter is not
+         * evaluated any more within the query engine.
+         * 
+         * @return whether the index supports full-text extraction
+         */
+        boolean isFulltextIndex();
+
+        /**
+         * Whether the cursor is able to read all properties from a node.
+         * If yes, then the query engine will not have to read the data itself.
+         * 
+         * @return wheter node data is returned
+         */
+        boolean includesNodeData();
+
+        /**
+         * The sort order of the returned entries, or null if unsorted.
+         * 
+         * @return the sort order
+         */
+        List<OrderEntry> getSortOrder();
+        
+        /**
+         * A builder for index plans.
+         */
+        public class Builder {
+
+            protected double costPerExecution = 1.0;
+            protected double costPerEntry = 1.0;
+            protected long estimatedEntryCount = 1000000;
+            protected Filter filter;
+            protected boolean isDelayed;
+            protected boolean isFulltextIndex;
+            protected boolean includesNodeData;
+            protected List<OrderEntry> sortOrder;
+
+            public Builder setCostPerExecution(double costPerExecution) {
+                this.costPerExecution = costPerExecution;
+                return this;
+            }
+
+            public Builder setCostPerEntry(double costPerEntry) {
+                this.costPerEntry = costPerEntry;
+                return this;
+            }
+
+            public Builder setEstimatedEntryCount(long estimatedEntryCount) {
+                this.estimatedEntryCount = estimatedEntryCount;
+                return this;
+            }
+
+            public Builder setFilter(Filter filter) {
+                this.filter = filter;
+                return this;
+            }
+
+            public Builder setDelayed(boolean isDelayed) {
+                this.isDelayed = isDelayed;
+                return this;
+            }
+
+            public Builder setFulltextIndex(boolean isFulltextIndex) {
+                this.isFulltextIndex = isFulltextIndex;
+                return this;
+            }
+
+            public Builder setIncludesNodeData(boolean includesNodeData) {
+                this.includesNodeData = includesNodeData;
+                return this;
+            }
+
+            public Builder setSortOrder(List<OrderEntry> sortOrder) {
+                this.sortOrder = sortOrder;
+                return this;
+            }
+            
+            public IndexPlan build() {
+                
+                return new IndexPlan() {
+                    
+                    private final double costPerExecution = 
+                            Builder.this.costPerExecution;
+                    private final double costPerEntry = 
+                            Builder.this.costPerEntry;
+                    private final long estimatedEntryCount = 
+                            Builder.this.estimatedEntryCount;
+                    private final Filter filter = 
+                            Builder.this.filter;
+                    private final boolean isDelayed = 
+                            Builder.this.isDelayed;
+                    private final boolean isFulltextIndex = 
+                            Builder.this.isFulltextIndex;
+                    private final boolean includesNodeData = 
+                            Builder.this.includesNodeData;
+                    private final List<OrderEntry> sortOrder = 
+                            Builder.this.sortOrder == null ?
+                            null : new ArrayList<OrderEntry>(
+                                    Builder.this.sortOrder);                  
+
+                    @Override
+                    public double getCostPerExecution() {
+                        return costPerExecution;
+                    }
+
+                    @Override
+                    public double getCostPerEntry() {
+                        return costPerEntry;
+                    }
+
+                    @Override
+                    public long getEstimatedEntryCount() {
+                        return estimatedEntryCount;
+                    }
+
+                    @Override
+                    public Filter getFilter() {
+                        return filter;
+                    }
+
+                    @Override
+                    public boolean isDelayed() {
+                        return isDelayed;
+                    }
+
+                    @Override
+                    public boolean isFulltextIndex() {
+                        return isFulltextIndex;
+                    }
+
+                    @Override
+                    public boolean includesNodeData() {
+                        return includesNodeData;
+                    }
+
+                    @Override
+                    public List<OrderEntry> getSortOrder() {
+                        return sortOrder;
+                    }
+                    
+                };
+            }
+                
+        }
+
+    }
+
+    /**
+     * A sort order entry.
+     */
+    static class OrderEntry {
+
+        /**
+         * The property name on where to sort.
+         */
+        private final String propertyName;
+        
+        /**
+         * The property type. Null if not known.
+         */
+        private final Type<?> propertyType;
+        
+        /**
+         * The sort order (ascending or descending).
+         */
+        public enum Order { ASCENDING, DESCENDING };
+        
+        private final Order order;
+        
+        OrderEntry(String propertyName, Type<?> propertyType, Order order) {
+            this.propertyName = propertyName;
+            this.propertyType = propertyType;
+            this.order = order;
+        }
+
+        public String getPropertyName() {
+            return propertyName;
+        }
+
+        public Order getOrder() {
+            return order;
+        }
+
+        public Type<?> getPropertyType() {
+            return propertyType;
+        }
+
+    }
 
 }

Added: 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=1574491&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/AdvancedIndexTest.java
Wed Mar  5 13:58:19 2014
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.query.index;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan;
+import org.junit.Test;
+
+/**
+ * Test the advanced query index feature.
+ */
+public class AdvancedIndexTest {
+
+    @Test
+    public void builder() {
+        IndexPlan.Builder b = new IndexPlan.Builder();
+        IndexPlan plan = b.setEstimatedEntryCount(10).build();
+        assertEquals(10, plan.getEstimatedEntryCount());
+        b.setEstimatedEntryCount(20);
+        assertEquals(10, plan.getEstimatedEntryCount());
+    }
+    
+}



Mime
View raw message