Search in sources :

Example 1 with SelectorExecutionPlan

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);
}
Also used : SelectorExecutionPlan(org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex) OrderEntry(org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry) IndexPlan(org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan) TraversingIndex(org.apache.jackrabbit.oak.query.index.TraversingIndex) QueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex)

Example 2 with SelectorExecutionPlan

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;
}
Also used : SelectorExecutionPlan(org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan)

Aggregations

SelectorExecutionPlan (org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan)2 TraversingIndex (org.apache.jackrabbit.oak.query.index.TraversingIndex)1 QueryIndex (org.apache.jackrabbit.oak.spi.query.QueryIndex)1 AdvancedQueryIndex (org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex)1 IndexPlan (org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan)1 OrderEntry (org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry)1