use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class WildcardedExpressionSequence method eval.
@Override
public NodeSet eval(final NGramIndexWorker index, final DocumentSet docs, final List<QName> qnames, final NodeSet nodeSet, final int axis, final int expressionId) throws XPathException {
boolean startAnchorPresent = false;
if (!expressions.isEmpty() && expressions.get(0) instanceof StartAnchor) {
startAnchorPresent = true;
expressions.remove(0);
}
Wildcard leadingWildcard = null;
if (!expressions.isEmpty() && expressions.get(0) instanceof Wildcard)
leadingWildcard = (Wildcard) expressions.remove(0);
boolean endAnchorPresent = false;
if (!expressions.isEmpty() && expressions.get(expressions.size() - 1) instanceof EndAnchor) {
endAnchorPresent = true;
expressions.remove(expressions.size() - 1);
}
Wildcard trailingWildcard = null;
if (!expressions.isEmpty() && expressions.get(expressions.size() - 1) instanceof Wildcard)
trailingWildcard = (Wildcard) expressions.remove(expressions.size() - 1);
while (expressions.size() >= 3) {
formEvaluatableTriples(expressionId);
}
if (expressions.isEmpty())
return new EmptyNodeSet();
if (expressions.size() != 1 || !(expressions.get(0) instanceof EvaluatableExpression)) {
// Should not happen.
LOG.error("Expression {} could not be evaluated", toString());
throw new XPathException("Could not evaluate wildcarded query.");
}
LOG.trace("Evaluating expression {}", toString());
NodeSet result = ((EvaluatableExpression) expressions.get(0)).eval(index, docs, qnames, nodeSet, axis, expressionId);
if (leadingWildcard != null)
result = expandMatchesBackward(leadingWildcard, result, expressionId);
if (startAnchorPresent)
result = NodeSets.getNodesMatchingAtStart(result, expressionId);
if (trailingWildcard != null)
result = expandMatchesForward(trailingWildcard, result, expressionId);
if (endAnchorPresent)
result = NodeSets.getNodesMatchingAtEnd(result, expressionId);
return result;
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class PreorderedValueSequence method processAll.
private void processAll() throws XPathException {
for (int i = 0; i < orderSpecs.length; i++) {
final Expression expr = orderSpecs[i].getSortExpression();
final NodeSet result = expr.eval(null).toNodeSet();
for (final NodeProxy p : result) {
ContextItem context = p.getContext();
// TODO : review to consider transverse context
while (context != null) {
if (context.getNode() instanceof OrderedNodeProxy) {
final OrderedNodeProxy cp = (OrderedNodeProxy) context.getNode();
cp.values[i] = p.atomize();
}
context = context.getNextDirect();
}
}
}
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class OrderedValueSequence method toNodeSet.
@Override
public NodeSet toNodeSet() throws XPathException {
// return early
if (isEmpty()) {
return NodeSet.EMPTY_SET;
}
// for this method to work, all items have to be nodes
if (itemType != Type.ANY_TYPE && Type.subTypeOf(itemType, Type.NODE)) {
// Was ExtArrayNodeset() which orders the nodes in document order
// The order seems to change between different invocations !!!
final NodeSet set = new AVLTreeNodeSet();
// NodeSet set = new ArraySet(100);
for (int i = 0; i < count; i++) {
NodeValue v = (NodeValue) items[i].item;
if (v.getImplementationType() != NodeValue.PERSISTENT_NODE) {
// found an in-memory document
final org.exist.dom.memtree.DocumentImpl doc = v.getType() == Type.DOCUMENT ? (org.exist.dom.memtree.DocumentImpl) v : ((NodeImpl) v).getOwnerDocument();
if (doc == null) {
continue;
}
// make this document persistent: doc.makePersistent()
// returns a map of all root node ids mapped to the corresponding
// persistent node. We scan the current sequence and replace all
// in-memory nodes with their new persistent node objects.
final DocumentImpl expandedDoc = doc.expandRefs(null);
final org.exist.dom.persistent.DocumentImpl newDoc = expandedDoc.makePersistent();
if (newDoc != null) {
final NodeId rootId = newDoc.getBrokerPool().getNodeFactory().createInstance();
for (int j = i; j < count; j++) {
v = (NodeValue) items[j].item;
if (v.getImplementationType() != NodeValue.PERSISTENT_NODE) {
NodeImpl node = (NodeImpl) v;
final Document nodeOwnerDoc = node.getNodeType() == Node.DOCUMENT_NODE ? (org.exist.dom.memtree.DocumentImpl) v : ((NodeImpl) v).getOwnerDocument();
if (nodeOwnerDoc == doc) {
node = expandedDoc.getNode(node.getNodeNumber());
NodeId nodeId = node.getNodeId();
if (nodeId == null) {
throw new XPathException("Internal error: nodeId == null");
}
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeId = rootId;
} else {
nodeId = rootId.append(nodeId);
}
final NodeProxy p = new NodeProxy(newDoc, nodeId, node.getNodeType());
if (p != null) {
// replace the node by the NodeProxy
items[j].item = p;
}
}
}
}
}
set.add((NodeProxy) items[i].item);
} else {
set.add((NodeProxy) v);
}
}
return set;
} else {
throw new XPathException("Type error: the sequence cannot be converted into" + " a node set. Item type is " + Type.getTypeName(itemType));
}
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class Lookup method eval.
@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (!canOptimize && fallback != null) {
return fallback.eval(contextSequence, contextItem);
}
if (contextItem != null)
contextSequence = contextItem.toSequence();
if (contextSequence != null && !contextSequence.isPersistentSet()) {
// in-memory docs won't have an index
if (fallback == null) {
return Sequence.EMPTY_SEQUENCE;
} else {
return fallback.eval(contextSequence, contextItem);
}
}
NodeSet result;
if (preselectResult == null) {
long start = System.currentTimeMillis();
Sequence input = getArgument(0).eval(contextSequence);
if (!(input instanceof VirtualNodeSet) && input.isEmpty())
result = NodeSet.EMPTY_SET;
else {
RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
AtomicValue[] keys = getKeys(contextSequence);
if (keys.length == 0) {
return NodeSet.EMPTY_SET;
}
List<QName> qnames = null;
if (contextQName != null) {
qnames = new ArrayList<>(1);
qnames.add(contextQName);
}
final RangeIndex.Operator operator = getOperator();
// throw an exception if substring match operation is applied to collated index
if (usesCollation && !operator.supportsCollation()) {
throw new XPathException(this, RangeIndexModule.EXXQDYFT0001, "Index defines a collation which cannot be " + "used with the '" + operator + "' operation.");
}
try {
NodeSet inNodes = input.toNodeSet();
DocumentSet docs = inNodes.getDocumentSet();
result = index.query(getExpressionId(), docs, inNodes, qnames, keys, operator, NodeSet.ANCESTOR);
} catch (IOException e) {
throw new XPathException(this, e.getMessage());
}
}
if (context.getProfiler().traceFunctions()) {
context.getProfiler().traceIndexUsage(context, "new-range", this, PerformanceStats.BASIC_INDEX, System.currentTimeMillis() - start);
}
// LOG.info("eval plain took " + (System.currentTimeMillis() - start));
} else {
// long start = System.currentTimeMillis();
contextStep.setPreloadedData(preselectResult.getDocumentSet(), preselectResult);
result = getArgument(0).eval(contextSequence).toNodeSet();
// LOG.info("eval took " + (System.currentTimeMillis() - start));
}
return result;
}
use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.
the class FunIdRef method getIdRef.
private void getIdRef(NodeSet result, DocumentSet docs, String id) throws XPathException {
final NodeSet attribs = context.getBroker().getValueIndex().find(context.getWatchDog(), Comparison.EQ, docs, null, -1, null, new StringValue(id, Type.IDREF));
for (final NodeProxy n : attribs) {
n.setNodeType(Node.ATTRIBUTE_NODE);
result.add(n);
}
}
Aggregations