Search in sources :

Example 1 with StructuralIndex

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

the class LocationStep method getAttributes.

protected Sequence getAttributes(final XQueryContext context, final Sequence contextSequence) throws XPathException {
    if (!contextSequence.isPersistentSet()) {
        final MemoryNodeSet nodes = contextSequence.toMemNodeSet();
        if (axis == Constants.DESCENDANT_ATTRIBUTE_AXIS) {
            return nodes.getDescendantAttributes(test);
        } else {
            return nodes.getAttributes(test);
        }
    }
    final NodeSet contextSet = contextSequence.toNodeSet();
    if (!hasPreloadedData() && test.isWildcardTest()) {
        final NodeSet result = new VirtualNodeSet(context.getBroker(), axis, test, contextId, contextSet);
        ((VirtualNodeSet) result).setInPredicate(Expression.NO_CONTEXT_ID != contextId);
        return result;
    // if there's just a single known node in the context, it is faster
    // do directly search for the attribute in the parent node.
    }
    if (hasPreloadedData()) {
        final DocumentSet docs = getDocumentSet(contextSet);
        synchronized (context) {
            if (currentSet == null || currentDocs == null || (!optimized && !(docs == currentDocs || docs.equalDocs(currentDocs)))) {
                final StructuralIndex index = context.getBroker().getStructuralIndex();
                if (context.getProfiler().isEnabled()) {
                    context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "OPTIMIZATION", "Using structural index '" + index.toString() + "'");
                }
                // TODO : why a null selector here ? We have one below !
                currentSet = index.findElementsByTagName(ElementValue.ATTRIBUTE, docs, test.getName(), null, this);
                currentDocs = docs;
                registerUpdateListener();
            }
            switch(axis) {
                case Constants.ATTRIBUTE_AXIS:
                    return currentSet.selectParentChild(contextSet, NodeSet.DESCENDANT, contextId);
                case Constants.DESCENDANT_ATTRIBUTE_AXIS:
                    return currentSet.selectAncestorDescendant(contextSet, NodeSet.DESCENDANT, false, contextId, true);
                default:
                    throw new IllegalArgumentException("Unsupported axis specified");
            }
        }
    } else {
        final DocumentSet docs = getDocumentSet(contextSet);
        final StructuralIndex index = context.getBroker().getStructuralIndex();
        if (context.getProfiler().isEnabled()) {
            context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "OPTIMIZATION", "Using structural index '" + index.toString() + "'");
        }
        if (!contextSet.getProcessInReverseOrder()) {
            return index.findDescendantsByTagName(ElementValue.ATTRIBUTE, test.getName(), axis, docs, contextSet, contextId, this);
        } else {
            final NodeSelector selector;
            switch(axis) {
                case Constants.ATTRIBUTE_AXIS:
                    selector = new ChildSelector(contextSet, contextId);
                    break;
                case Constants.DESCENDANT_ATTRIBUTE_AXIS:
                    selector = new DescendantSelector(contextSet, contextId);
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported axis specified");
            }
            return index.findElementsByTagName(ElementValue.ATTRIBUTE, docs, test.getName(), selector, this);
        }
    }
}
Also used : InMemoryNodeSet(org.exist.dom.memtree.InMemoryNodeSet) InMemoryNodeSet(org.exist.dom.memtree.InMemoryNodeSet) StructuralIndex(org.exist.indexing.StructuralIndex)

Example 2 with StructuralIndex

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

the class LocationStep method getSiblings.

/**
 * Get's the sibling nodes of the context set
 *
 * @param context         a <code>XQueryContext</code> value
 * @param contextSequence a <code>NodeSet</code> value
 * @return a <code>NodeSet</code> value
 * @throws XPathException in case of dynamic error
 */
protected Sequence getSiblings(final XQueryContext context, final Sequence contextSequence) throws XPathException {
    if (!contextSequence.isPersistentSet()) {
        final MemoryNodeSet nodes = contextSequence.toMemNodeSet();
        if (axis == Constants.PRECEDING_SIBLING_AXIS) {
            return nodes.getPrecedingSiblings(test);
        } else {
            return nodes.getFollowingSiblings(test);
        }
    }
    final NodeSet contextSet = contextSequence.toNodeSet();
    // similar way ? -pb
    if (test.getType() == Type.PROCESSING_INSTRUCTION) {
        final VirtualNodeSet vset = new VirtualNodeSet(context.getBroker(), axis, test, contextId, contextSet);
        vset.setInPredicate(Expression.NO_CONTEXT_ID != contextId);
        return vset;
    }
    if (test.isWildcardTest()) {
        final AVLTreeNodeSet result = new AVLTreeNodeSet();
        try {
            final int limit = computeLimit();
            for (final NodeProxy current : contextSet) {
                // document-node() does not have any preceding or following elements
                if (NodeId.DOCUMENT_NODE.equals(current.getNodeId())) {
                    continue;
                }
                final IEmbeddedXMLStreamReader reader;
                final StreamFilter filter;
                if (axis == Constants.PRECEDING_SIBLING_AXIS) {
                    final NodeId startNodeId;
                    if (NodeId.DOCUMENT_NODE.equals(current.getNodeId().getParentId())) {
                        // parent would be document-node(), start from document-node()/node()[1]
                        startNodeId = NodeId.ROOT_NODE;
                    } else {
                        startNodeId = current.getNodeId().getParentId().getChild(1);
                    }
                    final NodeProxy startNode = new NodeProxy(current.getOwnerDocument(), startNodeId);
                    reader = context.getBroker().getXMLStreamReader(startNode, false);
                    filter = new PrecedingSiblingFilter(test, startNode, current, result, contextId);
                } else {
                    reader = context.getBroker().getXMLStreamReader(current, false);
                    filter = new FollowingSiblingFilter(test, current, result, contextId, limit);
                }
                reader.filter(filter);
            }
        } catch (final IOException | XMLStreamException e) {
            throw new XPathException(this, e);
        }
        return result;
    } else {
        // TODO : no test on preloaded data ?
        final DocumentSet docs = getDocumentSet(contextSet);
        synchronized (context) {
            if (currentSet == null || currentDocs == null || !(docs.equalDocs(currentDocs))) {
                final StructuralIndex index = context.getBroker().getStructuralIndex();
                if (context.getProfiler().isEnabled()) {
                    context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "OPTIMIZATION", "Using structural index '" + index.toString() + "'");
                }
                currentSet = index.findElementsByTagName(ElementValue.ELEMENT, docs, test.getName(), null, this);
                currentDocs = docs;
                registerUpdateListener();
            }
            switch(axis) {
                case Constants.PRECEDING_SIBLING_AXIS:
                    return currentSet.selectPrecedingSiblings(contextSet, contextId);
                case Constants.FOLLOWING_SIBLING_AXIS:
                    return currentSet.selectFollowingSiblings(contextSet, contextId);
                default:
                    throw new IllegalArgumentException("Unsupported axis specified");
            }
        }
    }
}
Also used : InMemoryNodeSet(org.exist.dom.memtree.InMemoryNodeSet) InMemoryNodeSet(org.exist.dom.memtree.InMemoryNodeSet) StructuralIndex(org.exist.indexing.StructuralIndex) IOException(java.io.IOException) StreamFilter(javax.xml.stream.StreamFilter) XMLStreamException(javax.xml.stream.XMLStreamException) NodeId(org.exist.numbering.NodeId)

Example 3 with StructuralIndex

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

the class LocationStep method getAncestors.

/**
 * Get the ancestor axis nodes
 *
 * @param context the xquery context
 * @param contextSequence the context sequence
 *
 * @return the ancestor nodes
 *
 * @throws XPathException if an error occurs
 */
protected Sequence getAncestors(final XQueryContext context, final Sequence contextSequence) throws XPathException {
    if (!contextSequence.isPersistentSet()) {
        final MemoryNodeSet nodes = contextSequence.toMemNodeSet();
        return nodes.getAncestors(axis == Constants.ANCESTOR_SELF_AXIS, test);
    }
    final NodeSet contextSet = contextSequence.toNodeSet();
    if (test.isWildcardTest()) {
        final NodeSet result = new NewArrayNodeSet();
        result.setProcessInReverseOrder(true);
        for (final NodeProxy current : contextSet) {
            NodeProxy ancestor;
            if (axis == Constants.ANCESTOR_SELF_AXIS && test.matches(current)) {
                ancestor = new NodeProxy(current);
                ancestor.setNodeType(Node.ELEMENT_NODE);
                final NodeProxy t = result.get(ancestor);
                if (t == null) {
                    if (Expression.NO_CONTEXT_ID != contextId) {
                        ancestor.addContextNode(contextId, current);
                    } else {
                        ancestor.copyContext(current);
                    }
                    ancestor.addMatches(current);
                    result.add(ancestor);
                } else {
                    t.addContextNode(contextId, current);
                    t.addMatches(current);
                }
            }
            NodeId parentID = current.getNodeId().getParentId();
            while (parentID != null) {
                ancestor = new NodeProxy(current.getOwnerDocument(), parentID, Node.ELEMENT_NODE);
                // Filter out the temporary nodes wrapper element
                if (parentID != NodeId.DOCUMENT_NODE && !(parentID.getTreeLevel() == 1 && current.getOwnerDocument().getCollection().isTempCollection())) {
                    if (test.matches(ancestor)) {
                        final NodeProxy t = result.get(ancestor);
                        if (t == null) {
                            if (Expression.NO_CONTEXT_ID != contextId) {
                                ancestor.addContextNode(contextId, current);
                            } else {
                                ancestor.copyContext(current);
                            }
                            ancestor.addMatches(current);
                            result.add(ancestor);
                        } else {
                            t.addContextNode(contextId, current);
                            t.addMatches(current);
                        }
                    }
                }
                parentID = parentID.getParentId();
            }
        }
        return result;
    } else if (hasPreloadedData()) {
        final DocumentSet docs = getDocumentSet(contextSet);
        synchronized (context) {
            if (currentSet == null || currentDocs == null || (!optimized && !(docs == currentDocs || docs.equalDocs(currentDocs)))) {
                final StructuralIndex index = context.getBroker().getStructuralIndex();
                if (context.getProfiler().isEnabled()) {
                    context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "OPTIMIZATION", "Using structural index '" + index.toString() + "'");
                }
                currentSet = index.findElementsByTagName(ElementValue.ELEMENT, docs, test.getName(), null, this);
                currentDocs = docs;
                registerUpdateListener();
            }
            switch(axis) {
                case Constants.ANCESTOR_SELF_AXIS:
                    return currentSet.selectAncestors(contextSet, true, contextId);
                case Constants.ANCESTOR_AXIS:
                    return currentSet.selectAncestors(contextSet, false, contextId);
                default:
                    throw new IllegalArgumentException("Unsupported axis specified");
            }
        }
    } else {
        final DocumentSet docs = getDocumentSet(contextSet);
        final StructuralIndex index = context.getBroker().getStructuralIndex();
        if (context.getProfiler().isEnabled()) {
            context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "OPTIMIZATION", "Using structural index '" + index.toString() + "'");
        }
        return index.findAncestorsByTagName(ElementValue.ELEMENT, test.getName(), axis, docs, contextSet, contextId);
    }
}
Also used : InMemoryNodeSet(org.exist.dom.memtree.InMemoryNodeSet) InMemoryNodeSet(org.exist.dom.memtree.InMemoryNodeSet) StructuralIndex(org.exist.indexing.StructuralIndex) NodeId(org.exist.numbering.NodeId)

Example 4 with StructuralIndex

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

the class MoveOverwriteCollectionTest method checkIndex.

private void checkIndex(final DBBroker broker, final DocumentSet docs) throws Exception {
    final StructuralIndex index = broker.getStructuralIndex();
    final NodeSelector selector = NodeProxy::new;
    NodeSet nodes;
    nodes = index.findElementsByTagName(ELEMENT, docs, new QName("test2"), selector);
    assertTrue(nodes.isEmpty());
    nodes = index.findElementsByTagName(ELEMENT, docs, new QName("test1"), selector);
    assertTrue(nodes.isEmpty());
    nodes = index.findElementsByTagName(ELEMENT, docs, new QName("test3"), selector);
    assertFalse(nodes.isEmpty());
}
Also used : StructuralIndex(org.exist.indexing.StructuralIndex) QName(org.exist.dom.QName) NodeSelector(org.exist.xquery.NodeSelector)

Example 5 with StructuralIndex

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

the class VirtualNodeSet method getNodesFromIndex.

/**
 * Realize the node set by scanning the structural index.
 * This is usually cheaper than calling {@link #getNodes()}.
 *
 * Not used right now because the method seems to dramatically slow down
 * some expressions instead of improving performance. To be checked.
 */
private NodeSet getNodesFromIndex() {
    final StructuralIndex index = broker.getStructuralIndex();
    final byte type = test.getType() == Type.ELEMENT ? ElementValue.ELEMENT : ElementValue.ATTRIBUTE;
    final NodeSet result = index.scanByType(type, axis, test, useSelfAsContext && inPredicate, context.getDocumentSet(), context, contextId);
    realDocumentSet = result.getDocumentSet();
    return result;
}
Also used : StructuralIndex(org.exist.indexing.StructuralIndex)

Aggregations

StructuralIndex (org.exist.indexing.StructuralIndex)11 InMemoryNodeSet (org.exist.dom.memtree.InMemoryNodeSet)8 IOException (java.io.IOException)2 StreamFilter (javax.xml.stream.StreamFilter)2 XMLStreamException (javax.xml.stream.XMLStreamException)2 QName (org.exist.dom.QName)2 NodeId (org.exist.numbering.NodeId)2 NodeSet (org.exist.dom.persistent.NodeSet)1 NodeSelector (org.exist.xquery.NodeSelector)1 Sequence (org.exist.xquery.value.Sequence)1 NodeList (org.w3c.dom.NodeList)1