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);
}
}
}
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");
}
}
}
}
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);
}
}
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());
}
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;
}
Aggregations