Search in sources :

Example 1 with RangeIndexWorker

use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.

the class FieldLookup method eval.

@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (contextItem != null)
        contextSequence = contextItem.toSequence();
    if (contextSequence != null && !contextSequence.isPersistentSet())
        // in-memory docs won't have an index
        if (fallback == null) {
            return Sequence.EMPTY_SEQUENCE;
        } else {
            return fallback.eval(contextSequence, contextItem);
        }
    NodeSet result;
    if (preselectResult == null) {
        long start = System.currentTimeMillis();
        DocumentSet docs;
        if (contextSequence == null)
            docs = context.getStaticallyKnownDocuments();
        else
            docs = contextSequence.getDocumentSet();
        NodeSet contextSet = null;
        if (contextSequence != null)
            contextSet = contextSequence.toNodeSet();
        Sequence fields = getArgument(0).eval(contextSequence);
        RangeIndex.Operator[] operators = null;
        int j = 1;
        if (isCalledAs("field")) {
            Sequence operatorSeq = getArgument(1).eval(contextSequence);
            operators = new RangeIndex.Operator[operatorSeq.getItemCount()];
            int i = 0;
            for (SequenceIterator si = operatorSeq.iterate(); si.hasNext(); i++) {
                operators[i] = RangeIndexModule.OPERATOR_MAP.get(si.nextItem().getStringValue());
            }
            j++;
        } else {
            RangeIndex.Operator operator = getOperator();
            operators = new RangeIndex.Operator[fields.getItemCount()];
            Arrays.fill(operators, operator);
        }
        if (operators.length != fields.getItemCount()) {
            throw new XPathException(this, "Number of operators specified must correspond to number of fields queried");
        }
        Sequence[] keys = new Sequence[getArgumentCount() - j];
        SequenceIterator fieldIter = fields.unorderedIterator();
        for (int i = j; i < getArgumentCount(); i++) {
            keys[i - j] = getArgument(i).eval(contextSequence);
            int targetType = Type.ITEM;
            if (fieldIter.hasNext()) {
                String field = fieldIter.nextItem().getStringValue();
                targetType = getType(contextSequence, field);
            }
            if (targetType != Type.ITEM && !Type.subTypeOf(keys[i - j].getItemType(), targetType)) {
                if (keys[i - j].hasMany()) {
                    final Sequence temp = new ValueSequence(keys[i - j].getItemCount());
                    for (final SequenceIterator iterator = keys[i - j].unorderedIterator(); iterator.hasNext(); ) {
                        temp.add(iterator.nextItem().convertTo(targetType));
                    }
                    keys[i - j] = temp;
                } else {
                    keys[i - j] = keys[i - j].convertTo(targetType);
                }
            }
        }
        if (keys.length < fields.getItemCount()) {
            throw new XPathException(this, "Number of keys to look up must correspond to number of fields specified");
        }
        RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
        try {
            result = index.queryField(getExpressionId(), docs, contextSet, fields, keys, operators, NodeSet.DESCENDANT);
            if (contextSet != null) {
                if (fallback != null && (fallback.getPrimaryAxis() == Constants.CHILD_AXIS || fallback.getPrimaryAxis() == Constants.ATTRIBUTE_AXIS)) {
                    result = result.selectParentChild(contextSet, NodeSet.DESCENDANT, getContextId());
                } else {
                    result = result.selectAncestorDescendant(contextSet, NodeSet.DESCENDANT, true, getContextId(), true);
                }
            }
        } catch (IOException e) {
            throw new XPathException(this, e.getMessage());
        }
        if (context.getProfiler().traceFunctions()) {
            context.getProfiler().traceIndexUsage(context, "new-range", this, PerformanceStats.OPTIMIZED_INDEX, System.currentTimeMillis() - start);
        }
    // LOG.info("eval plain took " + (System.currentTimeMillis() - start));
    } else {
        result = preselectResult.selectAncestorDescendant(contextSequence.toNodeSet(), NodeSet.DESCENDANT, true, getContextId(), true);
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) IOException(java.io.IOException) RangeIndexWorker(org.exist.indexing.range.RangeIndexWorker) DocumentSet(org.exist.dom.persistent.DocumentSet) RangeIndex(org.exist.indexing.range.RangeIndex)

Example 2 with RangeIndexWorker

use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.

the class FieldLookup method preSelect.

@Override
public NodeSet preSelect(Sequence contextSequence, boolean useContext) throws XPathException {
    if (contextSequence != null && !contextSequence.isPersistentSet())
        // in-memory docs won't have an index
        return NodeSet.EMPTY_SET;
    long start = System.currentTimeMillis();
    // the expression can be called multiple times, so we need to clear the previous preselectResult
    preselectResult = null;
    Sequence fieldSeq = getArgument(0).eval(contextSequence);
    RangeIndex.Operator[] operators = null;
    int j = 1;
    if (isCalledAs("field")) {
        Sequence operatorSeq = getArgument(1).eval(contextSequence);
        operators = new RangeIndex.Operator[operatorSeq.getItemCount()];
        int i = 0;
        for (SequenceIterator si = operatorSeq.iterate(); si.hasNext(); i++) {
            operators[i] = RangeIndexModule.OPERATOR_MAP.get(si.nextItem().getStringValue());
        }
        j++;
    } else {
        RangeIndex.Operator operator = getOperator();
        operators = new RangeIndex.Operator[fieldSeq.getItemCount()];
        Arrays.fill(operators, operator);
    }
    Sequence[] keys = new Sequence[getArgumentCount() - j];
    for (int i = j; i < getArgumentCount(); i++) {
        keys[i - j] = Atomize.atomize(getArgument(i).eval(contextSequence));
    }
    DocumentSet docs = contextSequence.getDocumentSet();
    RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
    try {
        preselectResult = index.queryField(getExpressionId(), docs, useContext ? contextSequence.toNodeSet() : null, fieldSeq, keys, operators, NodeSet.DESCENDANT);
    } catch (IOException e) {
        throw new XPathException(this, "Error while querying full text index: " + e.getMessage(), e);
    }
    LOG.info("preselect for {} on {}returned {} and took {}", Arrays.toString(keys), contextSequence.getItemCount(), preselectResult.getItemCount(), System.currentTimeMillis() - start);
    if (context.getProfiler().traceFunctions()) {
        context.getProfiler().traceIndexUsage(context, "new-range", this, PerformanceStats.OPTIMIZED_INDEX, System.currentTimeMillis() - start);
    }
    // preselectResult.setSelfAsContext(getContextId());
    return preselectResult;
}
Also used : IOException(java.io.IOException) RangeIndexWorker(org.exist.indexing.range.RangeIndexWorker) DocumentSet(org.exist.dom.persistent.DocumentSet) RangeIndex(org.exist.indexing.range.RangeIndex)

Example 3 with RangeIndexWorker

use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.

the class IndexKeys method eval.

@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
    int arg = 0;
    final String field = args[arg++].getStringValue();
    String start = null;
    if (args.length == 4) {
        start = args[arg++].getStringValue();
    }
    try (final FunctionReference ref = (FunctionReference) args[arg++].itemAt(0)) {
        int max = -1;
        if (!args[arg].isEmpty()) {
            max = ((IntegerValue) args[arg].itemAt(0)).getInt();
        }
        final Sequence result = new ValueSequence();
        final RangeIndexWorker worker = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexName("range-index");
        Occurrences[] occur = worker.scanIndexByField(field, contextSequence == null ? context.getStaticallyKnownDocuments() : contextSequence.getDocumentSet(), start, max);
        final int len = (max != -1 && occur.length > max ? max : occur.length);
        final Sequence[] params = new Sequence[2];
        ValueSequence data = new ValueSequence();
        for (int j = 0; j < len; j++) {
            params[0] = new StringValue(occur[j].getTerm().toString());
            data.add(new IntegerValue(occur[j].getOccurrences(), Type.UNSIGNED_INT));
            data.add(new IntegerValue(occur[j].getDocuments(), Type.UNSIGNED_INT));
            data.add(new IntegerValue(j + 1, Type.UNSIGNED_INT));
            params[1] = data;
            result.addAll(ref.evalFunction(Sequence.EMPTY_SEQUENCE, null, params));
            data.clear();
        }
        return result;
    }
}
Also used : RangeIndexWorker(org.exist.indexing.range.RangeIndexWorker) Occurrences(org.exist.util.Occurrences)

Example 4 with RangeIndexWorker

use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.

the class Optimize method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    if (!context.getSubject().hasDbaRole())
        throw new XPathException(this, "user has to be a member of the dba group to call " + "the optimize function. Calling user was " + context.getSubject().getName());
    RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
    index.optimize();
    return Sequence.EMPTY_SEQUENCE;
}
Also used : RangeIndexWorker(org.exist.indexing.range.RangeIndexWorker)

Example 5 with RangeIndexWorker

use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.

the class Lookup method eval.

@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (!canOptimize && fallback != null) {
        return fallback.eval(contextSequence, contextItem);
    }
    if (contextItem != null)
        contextSequence = contextItem.toSequence();
    if (contextSequence != null && !contextSequence.isPersistentSet()) {
        // in-memory docs won't have an index
        if (fallback == null) {
            return Sequence.EMPTY_SEQUENCE;
        } else {
            return fallback.eval(contextSequence, contextItem);
        }
    }
    NodeSet result;
    if (preselectResult == null) {
        long start = System.currentTimeMillis();
        Sequence input = getArgument(0).eval(contextSequence);
        if (!(input instanceof VirtualNodeSet) && input.isEmpty())
            result = NodeSet.EMPTY_SET;
        else {
            RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
            AtomicValue[] keys = getKeys(contextSequence);
            if (keys.length == 0) {
                return NodeSet.EMPTY_SET;
            }
            List<QName> qnames = null;
            if (contextQName != null) {
                qnames = new ArrayList<>(1);
                qnames.add(contextQName);
            }
            final RangeIndex.Operator operator = getOperator();
            // throw an exception if substring match operation is applied to collated index
            if (usesCollation && !operator.supportsCollation()) {
                throw new XPathException(this, RangeIndexModule.EXXQDYFT0001, "Index defines a collation which cannot be " + "used with the '" + operator + "' operation.");
            }
            try {
                NodeSet inNodes = input.toNodeSet();
                DocumentSet docs = inNodes.getDocumentSet();
                result = index.query(getExpressionId(), docs, inNodes, qnames, keys, operator, NodeSet.ANCESTOR);
            } catch (IOException e) {
                throw new XPathException(this, e.getMessage());
            }
        }
        if (context.getProfiler().traceFunctions()) {
            context.getProfiler().traceIndexUsage(context, "new-range", this, PerformanceStats.BASIC_INDEX, System.currentTimeMillis() - start);
        }
    // LOG.info("eval plain took " + (System.currentTimeMillis() - start));
    } else {
        // long start = System.currentTimeMillis();
        contextStep.setPreloadedData(preselectResult.getDocumentSet(), preselectResult);
        result = getArgument(0).eval(contextSequence).toNodeSet();
    // LOG.info("eval took " + (System.currentTimeMillis() - start));
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet) QName(org.exist.dom.QName) IOException(java.io.IOException) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet) RangeIndexWorker(org.exist.indexing.range.RangeIndexWorker) DocumentSet(org.exist.dom.persistent.DocumentSet) RangeIndex(org.exist.indexing.range.RangeIndex)

Aggregations

RangeIndexWorker (org.exist.indexing.range.RangeIndexWorker)6 IOException (java.io.IOException)4 DocumentSet (org.exist.dom.persistent.DocumentSet)4 RangeIndex (org.exist.indexing.range.RangeIndex)4 QName (org.exist.dom.QName)2 NodeSet (org.exist.dom.persistent.NodeSet)2 VirtualNodeSet (org.exist.dom.persistent.VirtualNodeSet)1 Occurrences (org.exist.util.Occurrences)1