Search in sources :

Example 1 with QueryIndex

use of org.apache.jackrabbit.oak.spi.query.QueryIndex in project jackrabbit-oak by apache.

the class SelectorImpl method getPlan.

@Override
public String getPlan(NodeState rootState) {
    StringBuilder buff = new StringBuilder();
    buff.append(toString());
    buff.append(" /* ");
    QueryIndex index = getIndex();
    if (index != null) {
        if (index instanceof AdvancedQueryIndex) {
            AdvancedQueryIndex adv = (AdvancedQueryIndex) index;
            IndexPlan p = plan.getIndexPlan();
            buff.append(adv.getPlanDescription(p, rootState));
        } else {
            buff.append(index.getPlan(createFilter(true), rootState));
        }
    } else {
        buff.append("no-index");
    }
    if (!selectorConstraints.isEmpty()) {
        buff.append(" where ").append(new AndImpl(selectorConstraints).toString());
    }
    buff.append(" */");
    return buff.toString();
}
Also used : AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex) IndexPlan(org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan) QueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex)

Example 2 with QueryIndex

use of org.apache.jackrabbit.oak.spi.query.QueryIndex in project jackrabbit-oak by apache.

the class SelectorImpl method execute.

@Override
public void execute(NodeState rootState) {
    QueryIndex index = plan.getIndex();
    if (index == null) {
        cursor = Cursors.newPathCursor(new ArrayList<String>(), query.getSettings());
        return;
    }
    IndexPlan p = plan.getIndexPlan();
    if (p != null) {
        p.setFilter(createFilter(false));
        AdvancedQueryIndex adv = (AdvancedQueryIndex) index;
        cursor = adv.query(p, rootState);
    } else {
        cursor = index.query(createFilter(false), rootState);
    }
}
Also used : AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex) IndexPlan(org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan) ArrayList(java.util.ArrayList) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) QueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex)

Example 3 with QueryIndex

use of org.apache.jackrabbit.oak.spi.query.QueryIndex in project jackrabbit-oak by apache.

the class LuceneIndexTest method indexNodeLockHandling.

@Test
public void indexNodeLockHandling() throws Exception {
    tracker = new IndexTracker();
    // Create 2 indexes. /oak:index/lucene and /test/oak:index/lucene
    // The way LuceneIndexLookup works is. It collect child first and then
    // parent
    NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
    NodeBuilder nb = newLuceneIndexDefinitionV2(index, "lucene", of(TYPENAME_STRING));
    nb.setProperty(LuceneIndexConstants.FULL_TEXT_ENABLED, false);
    nb.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo"), STRINGS));
    index = builder.child("test").child(INDEX_DEFINITIONS_NAME);
    NodeBuilder nb2 = newLuceneIndexDefinitionV2(index, "lucene", of(TYPENAME_STRING));
    nb2.setProperty(LuceneIndexConstants.FULL_TEXT_ENABLED, false);
    nb2.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo"), STRINGS));
    NodeState before = builder.getNodeState();
    builder.child("test").setProperty("foo", "fox is jumping");
    NodeState after = builder.getNodeState();
    NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
    tracker.update(indexed);
    QueryIndex.AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker);
    FilterImpl filter = createFilter(NT_BASE);
    filter.restrictPath("/test", Filter.PathRestriction.EXACT);
    filter.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("bar"));
    builder = indexed.builder();
    NodeBuilder dir = builder.child("oak:index").child("lucene").child(":data");
    // Mutate the blob to fail on access i.e. create corrupt index
    List<Blob> blobs = new ArrayList<Blob>();
    Blob b = dir.child("segments_1").getProperty(JCR_DATA).getValue(Type.BINARY, 0);
    FailingBlob fb = new FailingBlob(IOUtils.toByteArray(b.getNewStream()));
    blobs.add(fb);
    dir.child("segments_1").setProperty(JCR_DATA, blobs, BINARIES);
    indexed = builder.getNodeState();
    tracker.update(indexed);
    List<IndexPlan> list = queryIndex.getPlans(filter, null, indexed);
    assertEquals("There must be only one plan", 1, list.size());
    IndexPlan plan = list.get(0);
    assertEquals("Didn't get the expected plan", "/test/oak:index/lucene", plan.getPlanName());
}
Also used : Blob(org.apache.jackrabbit.oak.api.Blob) ArrayBasedBlob(org.apache.jackrabbit.oak.plugins.memory.ArrayBasedBlob) NodeState(org.apache.jackrabbit.oak.spi.state.NodeState) FilterImpl(org.apache.jackrabbit.oak.query.index.FilterImpl) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) NodeBuilder(org.apache.jackrabbit.oak.spi.state.NodeBuilder) IndexPlan(org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan) QueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex) Test(org.junit.Test)

Example 4 with QueryIndex

use of org.apache.jackrabbit.oak.spi.query.QueryIndex 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) {
                long entryCount = p.getEstimatedEntryCount();
                if (p.getSupportsPathRestriction()) {
                    entryCount = scaleEntryCount(rootState, filter, entryCount);
                }
                if (sortOrder == null || p.getSortOrder() != null) {
                    // if the query is unordered, or
                    // if the query contains "order by" and the index can sort on that,
                    // then we don't need to read all entries from the index
                    entryCount = Math.min(maxEntryCount, entryCount);
                }
                double c = p.getCostPerExecution() + entryCount * p.getCostPerEntry();
                if (LOG.isDebugEnabled()) {
                    String plan = advIndex.getPlanDescription(p, rootState);
                    String msg = String.format("cost for [%s] of type (%s) with plan [%s] is %1.2f", p.getPlanName(), indexName, plan, c);
                    logDebug(msg);
                }
                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 5 with QueryIndex

use of org.apache.jackrabbit.oak.spi.query.QueryIndex in project jackrabbit-oak by apache.

the class SelectorImpl method getIndexCostInfo.

@Override
public String getIndexCostInfo(NodeState rootState) {
    StringBuilder buff = new StringBuilder();
    buff.append(quoteJson(selectorName)).append(": ");
    QueryIndex index = getIndex();
    if (index != null) {
        if (index instanceof AdvancedQueryIndex) {
            IndexPlan p = plan.getIndexPlan();
            buff.append("{ perEntry: ").append(p.getCostPerEntry());
            buff.append(", perExecution: ").append(p.getCostPerExecution());
            buff.append(", count: ").append(p.getEstimatedEntryCount());
            buff.append(" }");
        } else {
            buff.append(index.getCost(createFilter(true), rootState));
        }
    }
    return buff.toString();
}
Also used : AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex) IndexPlan(org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan) QueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex)

Aggregations

QueryIndex (org.apache.jackrabbit.oak.spi.query.QueryIndex)6 AdvancedQueryIndex (org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex)5 IndexPlan (org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan)5 ArrayList (java.util.ArrayList)3 Lists.newArrayList (com.google.common.collect.Lists.newArrayList)2 Nonnull (javax.annotation.Nonnull)1 Blob (org.apache.jackrabbit.oak.api.Blob)1 ArrayBasedBlob (org.apache.jackrabbit.oak.plugins.memory.ArrayBasedBlob)1 FilterImpl (org.apache.jackrabbit.oak.query.index.FilterImpl)1 TraversingIndex (org.apache.jackrabbit.oak.query.index.TraversingIndex)1 SelectorExecutionPlan (org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan)1 AdvanceFulltextQueryIndex (org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvanceFulltextQueryIndex)1 OrderEntry (org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry)1 NodeBuilder (org.apache.jackrabbit.oak.spi.state.NodeBuilder)1 NodeState (org.apache.jackrabbit.oak.spi.state.NodeState)1 Test (org.junit.Test)1