use of org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan in project jackrabbit-oak by apache.
the class QueryImpl method getBestSelectorExecutionPlan.
private SelectorExecutionPlan getBestSelectorExecutionPlan(NodeState rootState, FilterImpl filter, QueryIndexProvider indexProvider, boolean traversalEnabled) {
QueryIndex bestIndex = null;
if (LOG.isDebugEnabled()) {
logDebug("cost using filter " + filter);
}
double bestCost = Double.POSITIVE_INFINITY;
IndexPlan bestPlan = null;
// 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.
List<? extends QueryIndex> queryIndexes = MINIMAL_COST_ORDERING.sortedCopy(indexProvider.getQueryIndexes(rootState));
List<OrderEntry> sortOrder = getSortOrder(filter);
for (int i = 0; i < queryIndexes.size(); i++) {
QueryIndex index = queryIndexes.get(i);
double minCost = index.getMinimumCost();
if (minCost > bestCost) {
// Stop looking if the minimum cost is higher than the current best cost
break;
}
double cost;
String indexName = index.getIndexName();
IndexPlan indexPlan = null;
if (index instanceof AdvancedQueryIndex) {
AdvancedQueryIndex advIndex = (AdvancedQueryIndex) index;
long maxEntryCount = limit;
if (offset > 0) {
if (offset + limit < 0) {
// long overflow
maxEntryCount = Long.MAX_VALUE;
} else {
maxEntryCount = offset + limit;
}
}
List<IndexPlan> ipList = advIndex.getPlans(filter, sortOrder, rootState);
cost = Double.POSITIVE_INFINITY;
for (IndexPlan p : ipList) {
// TODO limit is after all conditions
long entryCount = Math.min(maxEntryCount, p.getEstimatedEntryCount());
double c = p.getCostPerExecution() + entryCount * p.getCostPerEntry();
if (c < cost) {
cost = c;
indexPlan = p;
}
}
if (indexPlan != null && indexPlan.getPlanName() != null) {
indexName += "[" + indexPlan.getPlanName() + "]";
}
} else {
cost = index.getCost(filter, rootState);
}
if (LOG.isDebugEnabled()) {
logDebug("cost for " + indexName + " is " + cost);
}
if (cost < 0) {
LOG.error("cost below 0 for " + indexName + " is " + cost);
}
if (cost < bestCost) {
bestCost = cost;
bestIndex = index;
bestPlan = indexPlan;
}
}
potentiallySlowTraversalQuery = bestIndex == null;
if (traversalEnabled) {
TraversingIndex traversal = new TraversingIndex();
double cost = traversal.getCost(filter, rootState);
if (LOG.isDebugEnabled()) {
logDebug("cost for " + traversal.getIndexName() + " is " + cost);
}
if (cost < bestCost || bestCost == Double.POSITIVE_INFINITY) {
bestCost = cost;
bestPlan = null;
bestIndex = traversal;
if (potentiallySlowTraversalQuery) {
potentiallySlowTraversalQuery = traversal.isPotentiallySlow(filter, rootState);
}
}
}
return new SelectorExecutionPlan(filter.getSelector(), bestIndex, bestPlan, bestCost);
}
use of org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan in project jackrabbit-oak by apache.
the class SelectorImpl method prepare.
@Override
public void prepare(ExecutionPlan p) {
if (!(p instanceof SelectorExecutionPlan)) {
throw new IllegalArgumentException("Not a selector plan");
}
SelectorExecutionPlan selectorPlan = (SelectorExecutionPlan) p;
if (selectorPlan.getSelector() != this) {
throw new IllegalArgumentException("Not a plan for this selector");
}
pushDown();
this.plan = selectorPlan;
}
Aggregations