Search in sources :

Example 41 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class IndexKeyOccurrences method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) 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);
        }
    }
    Sequence result;
    if (args[0].isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        final NodeSet nodes = args[0].toNodeSet();
        final DocumentSet docs = nodes.getDocumentSet();
        if (this.getArgumentCount() == 3) {
            final IndexWorker indexWorker = context.getBroker().getIndexController().getWorkerByIndexName(args[2].itemAt(0).getStringValue());
            // IndexWorker indexWorker = context.getBroker().getBrokerPool().getIndexManager().getIndexByName(args[2].itemAt(0).getStringValue()).getWorker();
            if (indexWorker == null) {
                throw new XPathException(this, "Unknown index: " + args[2].itemAt(0).getStringValue());
            }
            final Map<String, Object> hints = new HashMap<>();
            if (indexWorker instanceof OrderedValuesIndex) {
                hints.put(OrderedValuesIndex.START_VALUE, args[1]);
            } else {
                logger.warn("{} isn't an instance of org.exist.indexing.OrderedIndexWorker. Start value '{}' ignored.", indexWorker.getClass().getName(), args[1]);
            }
            final Occurrences[] occur = indexWorker.scanIndex(context, docs, nodes, hints);
            if (occur.length == 0) {
                result = Sequence.EMPTY_SEQUENCE;
            } else {
                result = new IntegerValue(occur[0].getOccurrences());
            }
        } else {
            ValueOccurrences[] occur = context.getBroker().getValueIndex().scanIndexKeys(docs, nodes, (Indexable) (args[1].itemAt(0)));
            if (occur.length == 0) {
                occur = context.getBroker().getValueIndex().scanIndexKeys(docs, nodes, null, (Indexable) (args[1].itemAt(0)));
            }
            if (occur.length == 0) {
                result = Sequence.EMPTY_SEQUENCE;
            } else {
                result = new IntegerValue(occur[0].getOccurrences());
            }
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) XPathException(org.exist.xquery.XPathException) HashMap(java.util.HashMap) IntegerValue(org.exist.xquery.value.IntegerValue) ValueOccurrences(org.exist.util.ValueOccurrences) OrderedValuesIndex(org.exist.indexing.OrderedValuesIndex) Occurrences(org.exist.util.Occurrences) ValueOccurrences(org.exist.util.ValueOccurrences) Sequence(org.exist.xquery.value.Sequence) IndexWorker(org.exist.indexing.IndexWorker) Indexable(org.exist.storage.Indexable) DocumentSet(org.exist.dom.persistent.DocumentSet)

Example 42 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class QueryField method eval.

public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (contextItem != null)
        contextSequence = contextItem.toSequence();
    NodeSet result;
    if (preselectResult == null) {
        long start = System.currentTimeMillis();
        String field = getArgument(0).eval(contextSequence).getStringValue();
        Item query = getKey(contextSequence, null);
        DocumentSet docs = null;
        if (contextSequence == null)
            docs = context.getStaticallyKnownDocuments();
        else
            docs = contextSequence.getDocumentSet();
        NodeSet contextSet = null;
        if (contextSequence != null)
            contextSet = contextSequence.toNodeSet();
        LuceneIndexWorker index = (LuceneIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(LuceneIndex.ID);
        QueryOptions options = parseOptions(this, contextSequence, contextItem, 3);
        try {
            if (Type.subTypeOf(query.getType(), Type.ELEMENT))
                result = index.queryField(getExpressionId(), docs, contextSet, field, (Element) ((NodeValue) query).getNode(), NodeSet.ANCESTOR, options);
            else
                result = index.queryField(context, getExpressionId(), docs, contextSet, field, query.getStringValue(), NodeSet.ANCESTOR, options);
        } catch (IOException e) {
            throw new XPathException(this, e.getMessage());
        }
        if (context.getProfiler().traceFunctions()) {
            context.getProfiler().traceIndexUsage(context, "lucene", this, PerformanceStats.BASIC_INDEX, System.currentTimeMillis() - start);
        }
    } else {
        result = preselectResult.selectAncestorDescendant(contextSequence.toNodeSet(), NodeSet.DESCENDANT, true, getContextId(), true);
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) DocumentSet(org.exist.dom.persistent.DocumentSet) IOException(java.io.IOException) LuceneIndexWorker(org.exist.indexing.lucene.LuceneIndexWorker)

Example 43 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class Predicate method selectByNodeSet.

/**
 * @param contextSequence the context sequence
 *
 * @return The result of the node set evaluation of the predicate.
 *
 * @throws XPathException if an error occurs
 */
private Sequence selectByNodeSet(final Sequence contextSequence) throws XPathException {
    final NewArrayNodeSet result = new NewArrayNodeSet();
    final NodeSet contextSet = contextSequence.toNodeSet();
    final boolean contextIsVirtual = contextSet instanceof VirtualNodeSet;
    contextSet.setTrackMatches(false);
    final NodeSet nodes = super.eval(contextSet, null).toNodeSet();
    /*
         * if the predicate expression returns results from the cache we can
         * also return the cached result.
         */
    if (cached != null && cached.isValid(contextSequence, null) && nodes.isCached()) {
        if (context.getProfiler().isEnabled()) {
            context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "Using cached results", result);
        }
        return cached.getResult();
    }
    DocumentImpl lastDoc = null;
    for (final NodeProxy currentNode : nodes) {
        int sizeHint = Constants.NO_SIZE_HINT;
        if (lastDoc == null || currentNode.getOwnerDocument() != lastDoc) {
            lastDoc = currentNode.getOwnerDocument();
            sizeHint = nodes.getSizeHint(lastDoc);
        }
        ContextItem contextItem = currentNode.getContext();
        if (contextItem == null) {
            throw new XPathException(this, "Internal evaluation error: context is missing for node " + currentNode.getNodeId() + " !");
        }
        // TODO : review to consider transverse context
        while (contextItem != null) {
            if (contextItem.getContextId() == getExpressionId()) {
                final NodeProxy next = contextItem.getNode();
                if (contextIsVirtual || contextSet.contains(next)) {
                    next.addMatches(currentNode);
                    result.add(next, sizeHint);
                }
            }
            contextItem = contextItem.getNextDirect();
        }
    }
    if (contextSequence.isCacheable()) {
        cached = new CachedResult(contextSequence, null, result);
    }
    contextSet.setTrackMatches(true);
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) ContextItem(org.exist.dom.persistent.ContextItem) DocumentImpl(org.exist.dom.persistent.DocumentImpl) NodeProxy(org.exist.dom.persistent.NodeProxy) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet)

Example 44 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class Predicate method evalBoolean.

/**
 * Evaluate the inner part of the predicate as a boolean.
 *
 * @param contextSequence the context sequence
 * @param inner the inner expression
 *
 * @return The result of the boolean evaluation of the predicate.
 *
 * @throws XPathException if an error occurs
 */
private Sequence evalBoolean(final Sequence contextSequence, final Expression inner, final int mode) throws XPathException {
    final Sequence result = new ValueSequence();
    int p;
    if (contextSequence instanceof NodeSet && ((NodeSet) contextSequence).getProcessInReverseOrder()) {
        // This one may be expensive...
        p = contextSequence.getItemCount();
        for (final SequenceIterator i = contextSequence.iterate(); i.hasNext(); p--) {
            // 0-based
            context.setContextSequencePosition(p - 1, contextSequence);
            final Item item = i.nextItem();
            final Sequence innerSeq = inner.eval(contextSequence, item);
            if (innerSeq.effectiveBooleanValue()) {
                result.add(item);
            }
        }
    } else {
        // 0-based
        p = 0;
        final boolean reverseAxis = Type.subTypeOf(contextSequence.getItemType(), Type.NODE) && (mode == Constants.ANCESTOR_AXIS || mode == Constants.ANCESTOR_SELF_AXIS || mode == Constants.PARENT_AXIS || mode == Constants.PRECEDING_AXIS || mode == Constants.PRECEDING_SIBLING_AXIS);
        // ... but grab some context positions ! -<8-P
        if (Type.subTypeOfUnion(inner.returnsType(), Type.NUMBER) && Dependency.dependsOn(inner, Dependency.CONTEXT_ITEM)) {
            final Set<NumericValue> positions = new TreeSet<>();
            for (final SequenceIterator i = contextSequence.iterate(); i.hasNext(); p++) {
                context.setContextSequencePosition(p, contextSequence);
                final Item item = i.nextItem();
                final Sequence innerSeq = inner.eval(contextSequence, item);
                if (innerSeq.hasOne()) {
                    final NumericValue nv = (NumericValue) innerSeq.itemAt(0);
                    // Non integers return... nothing, not even an error !
                    if (!nv.hasFractionalPart() && !nv.isZero()) {
                        positions.add(nv);
                    }
                }
            // XXX: else error or nothing?
            }
            for (final NumericValue pos : positions) {
                final int position = (reverseAxis ? contextSequence.getItemCount() - pos.getInt() : pos.getInt() - 1);
                // TODO : move this test above ?
                if (position <= contextSequence.getItemCount()) {
                    result.add(contextSequence.itemAt(position));
                }
            }
        } else {
            final Set<NumericValue> positions = new TreeSet<>();
            for (final SequenceIterator i = contextSequence.iterate(); i.hasNext(); p++) {
                context.setContextSequencePosition((reverseAxis ? contextSequence.getItemCount() - p - 1 : p), contextSequence);
                final Item item = i.nextItem();
                final Sequence innerSeq = inner.eval(contextSequence, item);
                if (innerSeq.hasOne() && Type.subTypeOfUnion(innerSeq.getItemType(), Type.NUMBER)) {
                    // TODO : introduce a check in innerSeq.hasOne() ?
                    final NumericValue nv = (NumericValue) innerSeq;
                    // Non integers return... nothing, not even an error !
                    if (!nv.hasFractionalPart() && !nv.isZero()) {
                        positions.add(nv);
                    }
                } else if (innerSeq.effectiveBooleanValue()) {
                    result.add(item);
                }
            }
            for (final NumericValue pos : positions) {
                final int position = (reverseAxis ? contextSequence.getItemCount() - pos.getInt() : pos.getInt() - 1);
                // TODO : move this test above ?
                if (position <= contextSequence.getItemCount()) {
                    result.add(contextSequence.itemAt(position));
                }
            }
        }
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) Item(org.exist.xquery.value.Item) ContextItem(org.exist.dom.persistent.ContextItem) SequenceIterator(org.exist.xquery.value.SequenceIterator) TreeSet(java.util.TreeSet) ValueSequence(org.exist.xquery.value.ValueSequence) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) NumericValue(org.exist.xquery.value.NumericValue)

Example 45 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class GeneralComparison method nodeSetCompare.

/**
 * Optimized implementation, which can be applied if the left operand returns a node set. In this case, the left expression is executed first. All
 * matching context nodes are then passed to the right expression.
 *
 * @param   nodes            DOCUMENT ME!
 * @param   contextSequence  DOCUMENT ME!
 *
 * @return  DOCUMENT ME!
 *
 * @throws  XPathException  DOCUMENT ME!
 */
protected Sequence nodeSetCompare(NodeSet nodes, Sequence contextSequence) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().message(this, Profiler.OPTIMIZATION_FLAGS, "OPTIMIZATION CHOICE", "nodeSetCompare");
    }
    if (LOG.isTraceEnabled()) {
        LOG.trace("No index: fall back to nodeSetCompare");
    }
    final long start = System.currentTimeMillis();
    final NodeSet result = new NewArrayNodeSet();
    final Collator collator = getCollator(contextSequence);
    if ((contextSequence != null) && !contextSequence.isEmpty() && !contextSequence.getDocumentSet().contains(nodes.getDocumentSet())) {
        for (final NodeProxy item : nodes) {
            ContextItem context = item.getContext();
            if (context == null) {
                throw (new XPathException(this, "Internal error: context node missing"));
            }
            final AtomicValue lv = item.atomize();
            do {
                final Sequence rs = getRight().eval(context.getNode().toSequence());
                for (final SequenceIterator i2 = Atomize.atomize(rs).iterate(); i2.hasNext(); ) {
                    final AtomicValue rv = i2.nextItem().atomize();
                    if (compareAtomic(collator, lv, rv)) {
                        result.add(item);
                    }
                }
            } while ((context = context.getNextDirect()) != null);
        }
    } else {
        for (final NodeProxy item : nodes) {
            final AtomicValue lv = item.atomize();
            final Sequence rs = getRight().eval(contextSequence);
            for (final SequenceIterator i2 = Atomize.atomize(rs).iterate(); i2.hasNext(); ) {
                final AtomicValue rv = i2.nextItem().atomize();
                if (compareAtomic(collator, lv, rv)) {
                    result.add(item);
                }
            }
        }
    }
    if (context.getProfiler().traceFunctions()) {
        context.getProfiler().traceIndexUsage(context, PerformanceStats.RANGE_IDX_TYPE, this, PerformanceStats.NO_INDEX, System.currentTimeMillis() - start);
    }
    return (result);
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) ContextItem(org.exist.dom.persistent.ContextItem) SequenceIterator(org.exist.xquery.value.SequenceIterator) AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) NodeProxy(org.exist.dom.persistent.NodeProxy) Collator(com.ibm.icu.text.Collator)

Aggregations

NodeSet (org.exist.dom.persistent.NodeSet)49 NodeProxy (org.exist.dom.persistent.NodeProxy)18 Sequence (org.exist.xquery.value.Sequence)18 DocumentSet (org.exist.dom.persistent.DocumentSet)14 NewArrayNodeSet (org.exist.dom.persistent.NewArrayNodeSet)12 QName (org.exist.dom.QName)11 ExtArrayNodeSet (org.exist.dom.persistent.ExtArrayNodeSet)10 VirtualNodeSet (org.exist.dom.persistent.VirtualNodeSet)9 ContextItem (org.exist.dom.persistent.ContextItem)8 IOException (java.io.IOException)7 XPathException (org.exist.xquery.XPathException)7 Collator (com.ibm.icu.text.Collator)4 EXistException (org.exist.EXistException)4 DocumentImpl (org.exist.dom.persistent.DocumentImpl)4 EmptyNodeSet (org.exist.dom.persistent.EmptyNodeSet)4 Indexable (org.exist.storage.Indexable)4 SequenceIterator (org.exist.xquery.value.SequenceIterator)4 StringValue (org.exist.xquery.value.StringValue)4 NodeImpl (org.exist.dom.memtree.NodeImpl)3 Match (org.exist.dom.persistent.Match)3