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 2015/09/25 08:17:36 UTC
svn commit: r1705216 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugin...
Author: thomasm
Date: Fri Sep 25 06:17:35 2015
New Revision: 1705216
URL: http://svn.apache.org/viewvc?rev=1705216&view=rev
Log:
OAK-2679 Query engine: cache execution plans
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/package-info.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexLookup.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexLookup.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/package-info.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/LowCostOrderedPropertyIndexProvider.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexQueryTest.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.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=1705216&r1=1705215&r2=1705216&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 Fri Sep 25 06:17:35 2015
@@ -55,6 +55,11 @@ public class AggregateIndex implements A
}
@Override
+ public double getMinimumCost() {
+ return baseIndex.getMinimumCost();
+ }
+
+ @Override
public double getCost(Filter filter, NodeState rootState) {
throw new UnsupportedOperationException("Not supported as implementing AdvancedQueryIndex");
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/package-info.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/package-info.java Fri Sep 25 06:17:35 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("1.1.0")
+@Version("1.2.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.plugins.index.aggregate;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/UUIDDiffIndex.java Fri Sep 25 06:17:35 2015
@@ -25,6 +25,11 @@ public class UUIDDiffIndex extends DiffI
}
@Override
+ public double getMinimumCost() {
+ return 0;
+ }
+
+ @Override
public String getIndexName() {
return "UUIDDiffIndex";
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java Fri Sep 25 06:17:35 2015
@@ -36,6 +36,11 @@ import org.apache.jackrabbit.oak.spi.sta
class NodeTypeIndex implements QueryIndex, JcrConstants {
@Override
+ public double getMinimumCost() {
+ return NodeTypeIndexLookup.MINIMUM_COST;
+ }
+
+ @Override
public double getCost(Filter filter, NodeState root) {
// TODO don't call getCost for such queries
if (filter.getFullTextConstraint() != null) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexLookup.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexLookup.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexLookup.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndexLookup.java Fri Sep 25 06:17:35 2015
@@ -31,6 +31,11 @@ import com.google.common.collect.Iterabl
*/
class NodeTypeIndexLookup implements JcrConstants {
+ /**
+ * Derived from {@link #getCost(Filter)}
+ */
+ static final double MINIMUM_COST = PropertyIndexLookup.COST_OVERHEAD;
+
private final NodeState root;
public NodeTypeIndexLookup(NodeState root) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndex.java Fri Sep 25 06:17:35 2015
@@ -44,13 +44,29 @@ public class OrderedPropertyIndex implem
private static final Logger LOG = LoggerFactory.getLogger(OrderedPropertyIndex.class);
+ /**
+ * We're local. Low-cost
+ */
+ private static final double COST_PER_EXECUTION = 3;
+
+ private final OrderedPropertyIndexProvider indexProvider;
+
+ public OrderedPropertyIndex(OrderedPropertyIndexProvider indexProvider) {
+ this.indexProvider = indexProvider;
+ }
+
+ @Override
+ public double getMinimumCost() {
+ return COST_PER_EXECUTION;
+ }
+
@Override
public String getIndexName() {
return TYPE;
}
OrderedPropertyIndexLookup getLookup(NodeState root) {
- return new OrderedPropertyIndexLookup(root);
+ return new OrderedPropertyIndexLookup(indexProvider, root);
}
/**
@@ -68,7 +84,7 @@ public class OrderedPropertyIndex implem
*/
static IndexPlan.Builder getIndexPlanBuilder(final Filter filter) {
IndexPlan.Builder b = new IndexPlan.Builder();
- b.setCostPerExecution(1); // we're local. Low-cost
+ b.setCostPerExecution(COST_PER_EXECUTION);
// we're local but slightly more expensive than a standard PropertyIndex
b.setCostPerEntry(1.3);
b.setFulltextIndex(false); // we're never full-text
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexLookup.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexLookup.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexLookup.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexLookup.java Fri Sep 25 06:17:35 2015
@@ -76,18 +76,21 @@ public class OrderedPropertyIndexLookup
*/
private static final int MAX_COST = 100;
+ private final OrderedPropertyIndexProvider indexProvider;
+
private NodeState root;
private String name;
private OrderedPropertyIndexLookup parent;
- public OrderedPropertyIndexLookup(NodeState root) {
- this(root, "", null);
+ public OrderedPropertyIndexLookup(OrderedPropertyIndexProvider indexProvider, NodeState root) {
+ this(indexProvider, root, "", null);
}
- public OrderedPropertyIndexLookup(NodeState root, String name,
+ public OrderedPropertyIndexLookup(OrderedPropertyIndexProvider indexProvider, NodeState root, String name,
OrderedPropertyIndexLookup parent) {
+ this.indexProvider = indexProvider;
this.root = root;
this.name = name;
this.parent = parent;
@@ -106,9 +109,14 @@ public class OrderedPropertyIndexLookup
*/
@Nullable
NodeState getIndexNode(NodeState node, String propertyName, Filter filter) {
+ if (parent == null && !indexProvider.mayHaveRootIndexes()) {
+ return null;
+ }
+
// keep a fallback to a matching index def that has *no* node type constraints
// (initially, there is no fallback)
NodeState fallback = null;
+ boolean hasRootIndexes = false;
NodeState state = node.getChildNode(INDEX_DEFINITIONS_NAME);
for (ChildNodeEntry entry : state.getChildNodeEntries()) {
@@ -117,6 +125,8 @@ public class OrderedPropertyIndexLookup
if (type == null || type.isArray() || !getType().equals(type.getValue(Type.STRING))) {
continue;
}
+ hasRootIndexes = true;
+
if (contains(index.getNames(PROPERTY_NAMES), propertyName)) {
NodeState indexContent = index.getChildNode(INDEX_CONTENT_NODE_NAME);
if (!indexContent.exists()) {
@@ -140,6 +150,10 @@ public class OrderedPropertyIndexLookup
}
}
}
+
+ if (parent == null) {
+ indexProvider.indicateRootIndexes(hasRootIndexes);
+ }
return fallback;
}
@@ -243,7 +257,7 @@ public class OrderedPropertyIndexLookup
for (String element : PathUtils.elements(path)) {
if (lookup == null) {
lookup = new OrderedPropertyIndexLookup(
- root.getChildNode(element), element, this);
+ indexProvider, root.getChildNode(element), element, this);
} else {
remainder = PathUtils.concat(remainder, element);
}
@@ -308,7 +322,7 @@ public class OrderedPropertyIndexLookup
for (String element : PathUtils.elements(path)) {
if (lookup == null) {
lookup = new OrderedPropertyIndexLookup(
- root.getChildNode(element), element, this);
+ indexProvider, root.getChildNode(element), element, this);
} else {
remainder = PathUtils.concat(remainder, element);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexProvider.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexProvider.java Fri Sep 25 06:17:35 2015
@@ -18,6 +18,7 @@
package org.apache.jackrabbit.oak.plugins.index.property;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
@@ -33,9 +34,46 @@ import com.google.common.collect.Immutab
@Service(QueryIndexProvider.class)
public class OrderedPropertyIndexProvider implements QueryIndexProvider {
+ private static final long DEFAULT_NO_INDEX_CACHE_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
+
+ /**
+ * How often it should check for a new ordered property index.
+ */
+ private static long noIndexCacheTimeout = DEFAULT_NO_INDEX_CACHE_TIMEOUT;
+
+ /**
+ * The last time when it checked for the existence of an ordered property index AND could not find any.
+ */
+ private volatile long lastNegativeIndexCheck;
+
@Override
@Nonnull
public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
- return ImmutableList.<QueryIndex> of(new OrderedPropertyIndex());
+ return ImmutableList.<QueryIndex> of(new OrderedPropertyIndex(this));
+ }
+
+ /**
+ * @return <code>true</code> if there may be any ordered indexes below the root path
+ */
+ boolean mayHaveRootIndexes() {
+ return System.currentTimeMillis() - lastNegativeIndexCheck > noIndexCacheTimeout;
+ }
+
+ /**
+ * Indicates whether or not there are ordered indexes below the root path
+ *
+ * @param hasRootIndexes
+ */
+ void indicateRootIndexes(boolean hasRootIndexes) {
+ lastNegativeIndexCheck = hasRootIndexes ? 0 : System.currentTimeMillis();
}
+
+ public static void setCacheTimeoutForTesting(long timeout) {
+ noIndexCacheTimeout = timeout;
+ }
+
+ public static void resetCacheTimeoutForTesting() {
+ noIndexCacheTimeout = DEFAULT_NO_INDEX_CACHE_TIMEOUT;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndex.java Fri Sep 25 06:17:35 2015
@@ -98,6 +98,11 @@ class PropertyIndex implements QueryInde
private static final Logger LOG = LoggerFactory.getLogger(PropertyIndex.class);
+ /**
+ * Cached property index plan
+ */
+ private PropertyIndexPlan plan;
+
static Set<String> encode(PropertyValue value) {
if (value == null) {
return null;
@@ -121,7 +126,22 @@ class PropertyIndex implements QueryInde
return values;
}
- private static PropertyIndexPlan plan(NodeState root, Filter filter) {
+ private PropertyIndexPlan getPlan(NodeState root, Filter filter) {
+ // Reuse cached plan if the filter is the same (which should always be the case). The filter is compared as a
+ // string because it would not be possible to use its equals method since the preparing flag would be different
+ // and creating a separate isSimilar method is not worth the effort since it would not be used anymore once the
+ // PropertyIndex has been refactored to an AdvancedQueryIndex (which will make the plan cache obsolete).
+ PropertyIndexPlan plan = this.plan;
+ if (plan != null && plan.getFilter().toString().equals(filter.toString())) {
+ return plan;
+ } else {
+ plan = createPlan(root, filter);
+ this.plan = plan;
+ return plan;
+ }
+ }
+
+ private static PropertyIndexPlan createPlan(NodeState root, Filter filter) {
PropertyIndexPlan bestPlan = null;
// TODO support indexes on a path
@@ -138,6 +158,10 @@ class PropertyIndex implements QueryInde
plan.getName(), plan.getCost());
if (bestPlan == null || plan.getCost() < bestPlan.getCost()) {
bestPlan = plan;
+ // Stop comparing if the costs are the minimum
+ if (plan.getCost() == PropertyIndexPlan.COST_OVERHEAD) {
+ break;
+ }
}
}
}
@@ -149,6 +173,11 @@ class PropertyIndex implements QueryInde
//--------------------------------------------------------< QueryIndex >--
@Override
+ public double getMinimumCost() {
+ return PropertyIndexPlan.COST_OVERHEAD;
+ }
+
+ @Override
public String getIndexName() {
return PROPERTY;
}
@@ -163,8 +192,12 @@ class PropertyIndex implements QueryInde
// not an appropriate index for native search
return Double.POSITIVE_INFINITY;
}
+ if (filter.getPropertyRestrictions().isEmpty() && filter.getSelector().getSelectorConstraints().isEmpty()) {
+ // not an appropriate index for no property restrictions & selector constraints
+ return Double.POSITIVE_INFINITY;
+ }
- PropertyIndexPlan plan = plan(root, filter);
+ PropertyIndexPlan plan = getPlan(root, filter);
if (plan != null) {
return plan.getCost();
} else {
@@ -174,7 +207,7 @@ class PropertyIndex implements QueryInde
@Override
public Cursor query(Filter filter, NodeState root) {
- PropertyIndexPlan plan = plan(root, filter);
+ PropertyIndexPlan plan = getPlan(root, filter);
checkState(plan != null,
"Property index is used even when no index"
+ " is available for filter " + filter);
@@ -183,7 +216,7 @@ class PropertyIndex implements QueryInde
@Override
public String getPlan(Filter filter, NodeState root) {
- PropertyIndexPlan plan = plan(root, filter);
+ PropertyIndexPlan plan = getPlan(root, filter);
if (plan != null) {
return plan.toString();
} else {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexLookup.java Fri Sep 25 06:17:35 2015
@@ -63,7 +63,7 @@ public class PropertyIndexLookup {
/**
* The cost overhead to use the index in number of read operations.
*/
- private static final double COST_OVERHEAD = 2;
+ public static final double COST_OVERHEAD = 2;
/**
* The maximum cost when the index can be used.
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java Fri Sep 25 06:17:35 2015
@@ -31,7 +31,6 @@ import java.util.Set;
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.index.PathFilter;
-import org.apache.jackrabbit.oak.plugins.index.PathFilter.Result;
import org.apache.jackrabbit.oak.plugins.index.property.strategy.ContentMirrorStoreStrategy;
import org.apache.jackrabbit.oak.plugins.index.property.strategy.IndexStoreStrategy;
import org.apache.jackrabbit.oak.plugins.index.property.strategy.UniqueEntryStoreStrategy;
@@ -58,7 +57,7 @@ public class PropertyIndexPlan {
/**
* The cost overhead to use the index in number of read operations.
*/
- private static final double COST_OVERHEAD = 2;
+ static final double COST_OVERHEAD = 2;
/**
* The maximum cost when the index can be used.
@@ -260,6 +259,10 @@ public class PropertyIndexPlan {
return cursor;
}
+ Filter getFilter() {
+ return filter;
+ }
+
//------------------------------------------------------------< Object >--
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/package-info.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/package-info.java Fri Sep 25 06:17:35 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("1.0.1")
+@Version("2.0.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.plugins.index.property;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java Fri Sep 25 06:17:35 2015
@@ -53,6 +53,13 @@ class ReferenceIndex implements QueryInd
private static final ContentMirrorStoreStrategy STORE = new ContentMirrorStoreStrategy();
+ private static final double COST = 1;
+
+ @Override
+ public double getMinimumCost() {
+ return COST;
+ }
+
@Override
public String getIndexName() {
return NAME;
@@ -72,7 +79,7 @@ class ReferenceIndex implements QueryInd
for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
if (isEqualityRestrictionOnType(pr, REFERENCE) ||
isEqualityRestrictionOnType(pr, WEAKREFERENCE)) {
- return 1;
+ return COST;
}
}
// not an appropriate index
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java Fri Sep 25 06:17:35 2015
@@ -28,6 +28,7 @@ import com.google.common.collect.Abstrac
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Ordering;
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
@@ -122,6 +123,13 @@ public class QueryImpl implements Query
private static final Logger LOG = LoggerFactory.getLogger(QueryImpl.class);
+ private static final Ordering<QueryIndex> MINIMAL_COST_ORDERING = new Ordering<QueryIndex>() {
+ @Override
+ public int compare(QueryIndex left, QueryIndex right) {
+ return Double.compare(left.getMinimumCost(), right.getMinimumCost());
+ }
+ };
+
SourceImpl source;
final String statement;
final HashMap<String, PropertyValue> bindVariableMap = new HashMap<String, PropertyValue>();
@@ -928,7 +936,16 @@ public class QueryImpl implements Query
double bestCost = Double.POSITIVE_INFINITY;
IndexPlan bestPlan = null;
- for (QueryIndex index : indexProvider.getQueryIndexes(rootState)) {
+
+ // Sort the indexes according to their minimum cost to be able to skip the remaining indexes if the cost of the
+ // current index is below the minimum cost of the next index.
+ final List<? extends QueryIndex> queryIndexes = MINIMAL_COST_ORDERING
+ .sortedCopy(indexProvider.getQueryIndexes(rootState));
+
+ for (int i = 0; i < queryIndexes.size(); i++) {
+ final QueryIndex index = queryIndexes.get(i);
+ final QueryIndex nextIndex = (i < queryIndexes.size()) ? queryIndexes.get(i) : null;
+
double cost;
String indexName = index.getIndexName();
IndexPlan indexPlan = null;
@@ -998,6 +1015,10 @@ public class QueryImpl implements Query
bestIndex = index;
bestPlan = indexPlan;
}
+ // Stop looking for a better index if the current best cost is lower than the next minimum cost
+ if (nextIndex != null && bestCost <= nextIndex.getMinimumCost()) {
+ break;
+ }
}
if (traversalEnabled) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java Fri Sep 25 06:17:35 2015
@@ -34,6 +34,11 @@ import org.apache.jackrabbit.oak.spi.sta
public class TraversingIndex implements QueryIndex {
@Override
+ public double getMinimumCost() {
+ return 0;
+ }
+
+ @Override
public Cursor query(Filter filter, NodeState rootState) {
return Cursors.newTraversingCursor(filter, rootState);
}
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=1705216&r1=1705215&r2=1705216&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 Fri Sep 25 06:17:35 2015
@@ -53,7 +53,16 @@ import static org.apache.jackrabbit.oak.
* even thought it will be set in the filter.
*/
public interface QueryIndex {
-
+
+ /**
+ * Returns the minimum cost which {@link #getCost(Filter, NodeState)} would return in the best possible case.
+ * <p>
+ * The implementation should return a static/cached value because it is called very often.
+ *
+ * @return the minimum cost for the index
+ */
+ double getMinimumCost();
+
/**
* Estimate the worst-case cost to query with the given filter. The returned
* cost is a value between 1 (very fast; lookup of a unique node) and the
@@ -336,7 +345,7 @@ public interface QueryIndex {
protected PropertyRestriction propRestriction;
protected String pathPrefix = "/";
protected Map<String, Object> attributes = Maps.newHashMap();
- protected String planName = null;
+ protected String planName;
public Builder setCostPerExecution(double costPerExecution) {
this.costPerExecution = costPerExecution;
@@ -543,7 +552,7 @@ public interface QueryIndex {
}
@Override
- public String getPlanName(){
+ public String getPlanName() {
return planName;
}
};
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java Fri Sep 25 06:17:35 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("3.0.0")
+@Version("4.0.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.spi.query;
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/LowCostOrderedPropertyIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/LowCostOrderedPropertyIndexProvider.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/LowCostOrderedPropertyIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/LowCostOrderedPropertyIndexProvider.java Fri Sep 25 06:17:35 2015
@@ -30,13 +30,22 @@ import com.google.common.collect.Immutab
public class LowCostOrderedPropertyIndexProvider extends OrderedPropertyIndexProvider {
@Override
public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
- return ImmutableList.<QueryIndex> of(new LowCostOrderedPropertyIndex());
+ return ImmutableList.<QueryIndex> of(new LowCostOrderedPropertyIndex(this));
}
private static class LowCostOrderedPropertyIndex extends OrderedPropertyIndex {
+ public LowCostOrderedPropertyIndex(LowCostOrderedPropertyIndexProvider indexProvider) {
+ super(indexProvider);
+ }
+
@Override
- public double getCost(Filter filter, NodeState root) {
+ public double getMinimumCost() {
return 1e-3;
}
+
+ @Override
+ public double getCost(Filter filter, NodeState root) {
+ return getMinimumCost();
+ }
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndexCostTest.java Fri Sep 25 06:17:35 2015
@@ -92,7 +92,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costFullTextConstraint() {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeState root = InitialContent.INITIAL_CONTENT;
Filter filter = EasyMock.createNiceMock(Filter.class);
FullTextExpression fte = EasyMock.createNiceMock(FullTextExpression.class);
@@ -106,7 +106,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costContainsNativeConstraints(){
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeState root = InitialContent.INITIAL_CONTENT;
Filter filter = EasyMock.createNiceMock(Filter.class);
EasyMock.expect(filter.containsNativeConstraint()).andReturn(true).anyTimes();
@@ -124,7 +124,7 @@ public class OrderedIndexCostTest extend
*/
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costGreaterThanAscendingDirection() throws Exception {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineAscendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -148,7 +148,7 @@ public class OrderedIndexCostTest extend
*/
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costGreaterThanEqualAscendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineAscendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -173,7 +173,7 @@ public class OrderedIndexCostTest extend
*/
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costLessThanAscendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineAscendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -192,7 +192,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costLessThanEqualsAscendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineAscendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -212,7 +212,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costGreaterThanDescendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineDescendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -232,7 +232,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costGreaterEqualThanDescendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineDescendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -253,7 +253,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costLessThanDescendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineDescendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -273,7 +273,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costLessThanEqualDescendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineDescendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -294,7 +294,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costBetweenDescendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineDescendingIndex(builder);
NodeState root = builder.getNodeState();
@@ -317,7 +317,7 @@ public class OrderedIndexCostTest extend
@Test @Ignore("As of OAK-622 this should no longer be used. Removing later.")
public void costBetweenAscendingDirection() throws IllegalArgumentException, RepositoryException {
- OrderedPropertyIndex index = new OrderedPropertyIndex();
+ OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
NodeBuilder builder = InitialContent.INITIAL_CONTENT.builder();
defineAscendingIndex(builder);
NodeState root = builder.getNodeState();
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexQueryTest.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexQueryTest.java Fri Sep 25 06:17:35 2015
@@ -507,7 +507,7 @@ public class OrderedPropertyIndexQueryTe
NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
- final OrderedPropertyIndex index = new OrderedPropertyIndex();
+ final OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
final String nodeTypeName = JcrConstants.NT_BASE;
Filter filter = createFilter(indexed, nodeTypeName);
@@ -583,7 +583,7 @@ public class OrderedPropertyIndexQueryTe
NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
- final OrderedPropertyIndex index = new OrderedPropertyIndex();
+ final OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
final String nodeTypeName = JcrConstants.NT_BASE;
Filter filter = createFilter(indexed, nodeTypeName);
@@ -624,7 +624,7 @@ public class OrderedPropertyIndexQueryTe
NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
- final OrderedPropertyIndex index = new OrderedPropertyIndex();
+ final OrderedPropertyIndex index = new OrderedPropertyIndex(new OrderedPropertyIndexProvider());
final String nodeTypeName = JcrConstants.NT_BASE;
FilterImpl filter = createFilter(indexed, nodeTypeName);
filter.restrictProperty("somethingNotIndexed", Operator.EQUAL, PropertyValues.newLong(1L));
Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java Fri Sep 25 06:17:35 2015
@@ -58,6 +58,9 @@ import org.apache.jackrabbit.oak.commons
import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
import org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest;
import org.apache.jackrabbit.oak.jcr.NodeStoreFixture;
+import org.apache.jackrabbit.oak.plugins.index.property.OrderedPropertyIndexProvider;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -69,7 +72,17 @@ public class QueryTest extends AbstractR
public QueryTest(NodeStoreFixture fixture) {
super(fixture);
}
-
+
+ @Before
+ public void disableCaching() {
+ OrderedPropertyIndexProvider.setCacheTimeoutForTesting(0);
+ }
+
+ @After
+ public void enableCaching() {
+ OrderedPropertyIndexProvider.resetCacheTimeoutForTesting();
+ }
+
@Test
public void join() throws Exception {
Session session = getAdminSession();
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java Fri Sep 25 06:17:35 2015
@@ -154,6 +154,7 @@ public class LuceneIndex implements Adva
private static final Logger LOG = LoggerFactory
.getLogger(LuceneIndex.class);
public static final String NATIVE_QUERY_FUNCTION = "native*lucene";
+ private static double MIN_COST = 2.2;
/**
* IndexPaln Attribute name which refers to the path of Lucene index to be used
@@ -178,6 +179,11 @@ public class LuceneIndex implements Adva
}
@Override
+ public double getMinimumCost() {
+ return MIN_COST;
+ }
+
+ @Override
public String getIndexName() {
return "lucene";
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java Fri Sep 25 06:17:35 2015
@@ -163,6 +163,8 @@ import static org.apache.lucene.search.B
*/
public class LucenePropertyIndex implements AdvancedQueryIndex, QueryIndex, NativeQueryIndex,
AdvanceFulltextQueryIndex {
+
+ private static double MIN_COST = 2.1;
private static final Logger LOG = LoggerFactory
.getLogger(LucenePropertyIndex.class);
@@ -191,6 +193,11 @@ public class LucenePropertyIndex impleme
}
@Override
+ public double getMinimumCost() {
+ return MIN_COST;
+ }
+
+ @Override
public String getIndexName() {
return "lucene-property";
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java Fri Sep 25 06:17:35 2015
@@ -36,19 +36,23 @@ public class LowCostLuceneIndexProvider
}
private static class LowCostLuceneIndex extends LuceneIndex {
-
public LowCostLuceneIndex(IndexTracker tracker, NodeAggregator aggregator) {
super(tracker, aggregator);
}
@Override
+ public double getMinimumCost() {
+ return 1e-3;
+ }
+
+ @Override
public List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder, NodeState rootState) {
String indexPath = new LuceneIndexLookup(rootState).getOldFullTextIndexPath(filter, tracker);
if (indexPath == null){
return Collections.emptyList();
}
return Collections.singletonList(planBuilder(filter)
- .setCostPerExecution(1e-3)
+ .setCostPerExecution(getMinimumCost())
.setAttribute(ATTR_INDEX_PATH, indexPath)
.build());
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java Fri Sep 25 06:17:35 2015
@@ -77,6 +77,10 @@ public class SolrQueryIndex implements F
static final String NATIVE_LUCENE_QUERY = "native*lucene";
+ private static double MIN_COST = 2.3;
+
+ private static double COST_FOR_SINGLE_RESTRICTION = 10;
+
private final Logger log = LoggerFactory.getLogger(SolrQueryIndex.class);
private final String name;
@@ -104,6 +108,11 @@ public class SolrQueryIndex implements F
}
@Override
+ public double getMinimumCost() {
+ return MIN_COST;
+ }
+
+ @Override
public String getIndexName() {
return name;
}
@@ -111,7 +120,7 @@ public class SolrQueryIndex implements F
@Override
public double getCost(Filter filter, NodeState root) {
// cost is inverse proportional to the number of matching restrictions, infinite if no restriction matches
- double cost = 10d / getMatchingFilterRestrictions(filter);
+ double cost = COST_FOR_SINGLE_RESTRICTION / getMatchingFilterRestrictions(filter);
if (log.isDebugEnabled()) {
log.debug("Solr: cost for {}Â is {}", name, cost);
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java?rev=1705216&r1=1705215&r2=1705216&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java Fri Sep 25 06:17:35 2015
@@ -17,9 +17,11 @@
package org.apache.jackrabbit.oak.plugins.index.solr.query;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
+import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -49,6 +51,11 @@ import static org.apache.jackrabbit.oak.
*/
public class SolrQueryIndexProvider implements QueryIndexProvider {
+ /**
+ * How often it should check for a new Solr index.
+ */
+ private static final long NO_INDEX_CACHE_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
+
private final Logger log = LoggerFactory.getLogger(getClass());
private final SolrServerProvider solrServerProvider;
@@ -59,6 +66,11 @@ public class SolrQueryIndexProvider impl
private final Map<NodeState, LMSEstimator> estimators = new WeakHashMap<NodeState, LMSEstimator>();
+ /**
+ * The last time when it checked for the existence of a Solr index AND could not find any.
+ */
+ private volatile long lastNegativeIndexCheck = 0;
+
public SolrQueryIndexProvider(@Nonnull SolrServerProvider solrServerProvider, @Nonnull OakSolrConfigurationProvider oakSolrConfigurationProvider,
@Nullable NodeAggregator nodeAggregator) {
this.oakSolrConfigurationProvider = oakSolrConfigurationProvider;
@@ -73,7 +85,19 @@ public class SolrQueryIndexProvider impl
@Nonnull
@Override
public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
+ List<? extends QueryIndex> queryIndexes;
+ // Return immediately if there are not any Solr indexes and the cache timeout has not been exceeded
+ long currentTime = System.currentTimeMillis();
+ if (currentTime - lastNegativeIndexCheck > NO_INDEX_CACHE_TIMEOUT) {
+ queryIndexes = internalGetQueryIndexes(nodeState);
+ lastNegativeIndexCheck = queryIndexes.isEmpty() ? currentTime : 0;
+ } else {
+ queryIndexes = Collections.emptyList();
+ }
+ return queryIndexes;
+ }
+ private List<? extends QueryIndex> internalGetQueryIndexes(NodeState nodeState) {
List<QueryIndex> tempIndexes = new ArrayList<QueryIndex>();
NodeState definitions = nodeState.getChildNode(INDEX_DEFINITIONS_NAME);
for (ChildNodeEntry entry : definitions.getChildNodeEntries()) {