use of org.exist.dom.persistent.NewArrayNodeSet in project exist by eXist-db.
the class NativeStructuralIndexWorker method findAncestorsByTagName.
public NodeSet findAncestorsByTagName(byte type, QName qname, int axis, DocumentSet docs, NodeSet contextSet, int contextId) {
final NewArrayNodeSet result = new NewArrayNodeSet();
try (final ManagedLock<ReentrantLock> btreeLock = index.lockManager.acquireBtreeReadLock(index.btree.getLockName())) {
for (final NodeProxy descendant : contextSet) {
NodeId parentId;
if (axis == Constants.ANCESTOR_SELF_AXIS || axis == Constants.SELF_AXIS) {
parentId = descendant.getNodeId();
} else {
parentId = descendant.getNodeId().getParentId();
}
final DocumentImpl doc = descendant.getOwnerDocument();
while (parentId != NodeId.DOCUMENT_NODE) {
final byte[] key = computeKey(type, qname, doc.getDocId(), parentId);
final long address = index.btree.findValue(new Value(key));
if (address != -1) {
final NodeProxy storedNode = new NodeProxy(doc, parentId, type == ElementValue.ATTRIBUTE ? Node.ATTRIBUTE_NODE : Node.ELEMENT_NODE, address);
result.add(storedNode);
if (Expression.NO_CONTEXT_ID != contextId) {
storedNode.deepCopyContext(descendant, contextId);
} else {
storedNode.copyContext(descendant);
}
if (contextSet.getTrackMatches()) {
storedNode.addMatches(descendant);
}
}
// stop after first iteration if we are on the self axis
if (axis == Constants.SELF_AXIS || axis == Constants.PARENT_AXIS) {
break;
}
// continue with the parent of the parent
parentId = parentId.getParentId();
}
}
} catch (final LockException e) {
NativeStructuralIndex.LOG.warn("Lock problem while searching structural index: {}", e.getMessage(), e);
} catch (final Exception e) {
NativeStructuralIndex.LOG.error("Error while searching structural index: {}", e.getMessage(), e);
}
result.sort(true);
return result;
}
use of org.exist.dom.persistent.NewArrayNodeSet 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;
}
use of org.exist.dom.persistent.NewArrayNodeSet 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);
}
use of org.exist.dom.persistent.NewArrayNodeSet in project exist by eXist-db.
the class FindLastModified method eval.
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
final NodeSet nodes = args[0].toNodeSet();
if (nodes.isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
final NodeSet result = new NewArrayNodeSet();
final DateTimeValue dtv = (DateTimeValue) args[1].itemAt(0);
final long lastModified = dtv.getDate().getTime();
for (final NodeProxy proxy : nodes) {
final DocumentImpl doc = proxy.getOwnerDocument();
final long modified = doc.getLastModified();
boolean matches;
if (this.isCalledAs("find-last-modified-since")) {
matches = modified > lastModified;
} else {
matches = modified <= lastModified;
}
if (matches) {
result.add(proxy);
}
}
return result;
}
Aggregations