Search in sources :

Example 1 with NativeValueIndex

use of org.exist.storage.NativeValueIndex in project exist by eXist-db.

the class FunMatches method evalWithIndex.

/**
 * @param contextSequence the context sequence
 * @param contextItem the context item
 * @param input the value of the $input arg
 * @return The resulting sequence
 * @throws XPathException if an error occurs
 */
private Sequence evalWithIndex(final Sequence contextSequence, final Item contextItem, final Sequence input) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    final int flags;
    if (getSignature().getArgumentCount() == 3) {
        final String flagsArg = getArgument(2).eval(contextSequence, contextItem).getStringValue();
        flags = parseFlags(this, flagsArg);
    } else {
        flags = 0;
    }
    final boolean caseSensitive = !hasCaseInsensitive(flags);
    Sequence result = null;
    final String pattern;
    if (isCalledAs("matches-regex")) {
        pattern = getArgument(1).eval(contextSequence, contextItem).getStringValue();
    } else {
        final boolean literal = hasLiteral(flags);
        if (literal) {
            // no need to change anything
            pattern = getArgument(1).eval(contextSequence, contextItem).getStringValue();
        } else {
            final boolean ignoreWhitespace = hasIgnoreWhitespace(flags);
            final boolean caseBlind = !caseSensitive;
            pattern = translateRegexp(this, getArgument(1).eval(contextSequence, contextItem).getStringValue(), ignoreWhitespace, caseBlind);
        }
    }
    final NodeSet nodes = input.toNodeSet();
    // get the type of a possible index
    final int indexType = nodes.getIndexType();
    if (LOG.isTraceEnabled()) {
        LOG.trace("found an index of type: {}", Type.getTypeName(indexType));
    }
    if (Type.subTypeOf(indexType, Type.STRING)) {
        boolean indexScan = false;
        if (contextSequence != null) {
            final GeneralComparison.IndexFlags iflags = GeneralComparison.checkForQNameIndex(idxflags, context, contextSequence, contextQName);
            boolean indexFound = false;
            if (!iflags.indexOnQName()) {
                // if contextQName != null and no index is defined on
                // contextQName, we don't need to scan other QName indexes
                // and can just use the generic range index
                indexFound = contextQName != null;
                // set contextQName to null so the index lookup below is not
                // restricted to that QName
                contextQName = null;
            }
            if (!indexFound && contextQName == null) {
                // we need to check them all
                if (iflags.hasIndexOnQNames()) {
                    indexScan = true;
                }
            // else use range index defined on path by default
            }
        } else {
            result = evalFallback(nodes, pattern, flags, indexType);
        }
        if (result == null) {
            final DocumentSet docs = nodes.getDocumentSet();
            try {
                final NativeValueIndex index = context.getBroker().getValueIndex();
                hasUsedIndex = true;
                // TODO : check index' case compatibility with flags' one ? -pb
                if (context.isProfilingEnabled()) {
                    context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "Using value index '" + index.toString() + "'", "Regex: " + pattern);
                }
                if (LOG.isTraceEnabled()) {
                    LOG.trace("Using range index for fn:matches expression: {}", pattern);
                }
                if (indexScan) {
                    result = index.matchAll(context.getWatchDog(), docs, nodes, NodeSet.ANCESTOR, pattern, DBBroker.MATCH_REGEXP, flags, caseSensitive);
                } else {
                    result = index.match(context.getWatchDog(), docs, nodes, NodeSet.ANCESTOR, pattern, contextQName, DBBroker.MATCH_REGEXP, flags, caseSensitive);
                }
            } catch (final EXistException e) {
                throw new XPathException(this, e);
            }
        }
    } else {
        result = evalFallback(nodes, pattern, flags, indexType);
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) NativeValueIndex(org.exist.storage.NativeValueIndex) Sequence(org.exist.xquery.value.Sequence) DocumentSet(org.exist.dom.persistent.DocumentSet) EXistException(org.exist.EXistException)

Example 2 with NativeValueIndex

use of org.exist.storage.NativeValueIndex in project exist by eXist-db.

the class QNameIndexLookup method eval.

public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (contextSequence == null || contextSequence.isEmpty()) {
        // if the context sequence is empty, we create a default context
        final RootNode rootNode = new RootNode(context);
        contextSequence = rootNode.eval(null, null);
    }
    final Sequence[] args = getArguments(null, null);
    final Item item = args[0].itemAt(0);
    final QNameValue qval;
    try {
        // attempt to convert the first argument to a QName
        qval = (QNameValue) item.convertTo(Type.QNAME);
    } catch (final XPathException e) {
        // wrong type: generate a diagnostic error
        throw new XPathException(this, Messages.formatMessage(Error.FUNC_PARAM_TYPE, new Object[] { "1", getSignature().toString(), null, Type.getTypeName(Type.QNAME), Type.getTypeName(item.getType()) }));
    }
    QName qname = qval.getQName();
    if (args.length == 3 && !(args[2].itemAt(0).toJavaObject(boolean.class))) {
        qname = new QName(qname.getLocalPart(), qname.getNamespaceURI(), qname.getPrefix(), ElementValue.ATTRIBUTE);
    }
    final AtomicValue comparisonCriterion = args[1].itemAt(0).atomize();
    final NativeValueIndex valueIndex = context.getBroker().getValueIndex();
    final Sequence result = valueIndex.find(context.getWatchDog(), Comparison.EQ, contextSequence.getDocumentSet(), null, NodeSet.ANCESTOR, qname, comparisonCriterion);
    return result;
}
Also used : RootNode(org.exist.xquery.RootNode) Item(org.exist.xquery.value.Item) XPathException(org.exist.xquery.XPathException) QName(org.exist.dom.QName) QNameValue(org.exist.xquery.value.QNameValue) AtomicValue(org.exist.xquery.value.AtomicValue) NativeValueIndex(org.exist.storage.NativeValueIndex) Sequence(org.exist.xquery.value.Sequence)

Aggregations

NativeValueIndex (org.exist.storage.NativeValueIndex)2 Sequence (org.exist.xquery.value.Sequence)2 EXistException (org.exist.EXistException)1 QName (org.exist.dom.QName)1 DocumentSet (org.exist.dom.persistent.DocumentSet)1 ExtArrayNodeSet (org.exist.dom.persistent.ExtArrayNodeSet)1 NodeSet (org.exist.dom.persistent.NodeSet)1 RootNode (org.exist.xquery.RootNode)1 XPathException (org.exist.xquery.XPathException)1 AtomicValue (org.exist.xquery.value.AtomicValue)1 Item (org.exist.xquery.value.Item)1 QNameValue (org.exist.xquery.value.QNameValue)1