use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.
the class FieldLookup method eval.
@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
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();
DocumentSet docs;
if (contextSequence == null)
docs = context.getStaticallyKnownDocuments();
else
docs = contextSequence.getDocumentSet();
NodeSet contextSet = null;
if (contextSequence != null)
contextSet = contextSequence.toNodeSet();
Sequence fields = getArgument(0).eval(contextSequence);
RangeIndex.Operator[] operators = null;
int j = 1;
if (isCalledAs("field")) {
Sequence operatorSeq = getArgument(1).eval(contextSequence);
operators = new RangeIndex.Operator[operatorSeq.getItemCount()];
int i = 0;
for (SequenceIterator si = operatorSeq.iterate(); si.hasNext(); i++) {
operators[i] = RangeIndexModule.OPERATOR_MAP.get(si.nextItem().getStringValue());
}
j++;
} else {
RangeIndex.Operator operator = getOperator();
operators = new RangeIndex.Operator[fields.getItemCount()];
Arrays.fill(operators, operator);
}
if (operators.length != fields.getItemCount()) {
throw new XPathException(this, "Number of operators specified must correspond to number of fields queried");
}
Sequence[] keys = new Sequence[getArgumentCount() - j];
SequenceIterator fieldIter = fields.unorderedIterator();
for (int i = j; i < getArgumentCount(); i++) {
keys[i - j] = getArgument(i).eval(contextSequence);
int targetType = Type.ITEM;
if (fieldIter.hasNext()) {
String field = fieldIter.nextItem().getStringValue();
targetType = getType(contextSequence, field);
}
if (targetType != Type.ITEM && !Type.subTypeOf(keys[i - j].getItemType(), targetType)) {
if (keys[i - j].hasMany()) {
final Sequence temp = new ValueSequence(keys[i - j].getItemCount());
for (final SequenceIterator iterator = keys[i - j].unorderedIterator(); iterator.hasNext(); ) {
temp.add(iterator.nextItem().convertTo(targetType));
}
keys[i - j] = temp;
} else {
keys[i - j] = keys[i - j].convertTo(targetType);
}
}
}
if (keys.length < fields.getItemCount()) {
throw new XPathException(this, "Number of keys to look up must correspond to number of fields specified");
}
RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
try {
result = index.queryField(getExpressionId(), docs, contextSet, fields, keys, operators, NodeSet.DESCENDANT);
if (contextSet != null) {
if (fallback != null && (fallback.getPrimaryAxis() == Constants.CHILD_AXIS || fallback.getPrimaryAxis() == Constants.ATTRIBUTE_AXIS)) {
result = result.selectParentChild(contextSet, NodeSet.DESCENDANT, getContextId());
} else {
result = result.selectAncestorDescendant(contextSet, NodeSet.DESCENDANT, true, getContextId(), true);
}
}
} catch (IOException e) {
throw new XPathException(this, e.getMessage());
}
if (context.getProfiler().traceFunctions()) {
context.getProfiler().traceIndexUsage(context, "new-range", this, PerformanceStats.OPTIMIZED_INDEX, System.currentTimeMillis() - start);
}
// LOG.info("eval plain took " + (System.currentTimeMillis() - start));
} else {
result = preselectResult.selectAncestorDescendant(contextSequence.toNodeSet(), NodeSet.DESCENDANT, true, getContextId(), true);
}
return result;
}
use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.
the class FieldLookup method preSelect.
@Override
public NodeSet preSelect(Sequence contextSequence, boolean useContext) throws XPathException {
if (contextSequence != null && !contextSequence.isPersistentSet())
// in-memory docs won't have an index
return NodeSet.EMPTY_SET;
long start = System.currentTimeMillis();
// the expression can be called multiple times, so we need to clear the previous preselectResult
preselectResult = null;
Sequence fieldSeq = getArgument(0).eval(contextSequence);
RangeIndex.Operator[] operators = null;
int j = 1;
if (isCalledAs("field")) {
Sequence operatorSeq = getArgument(1).eval(contextSequence);
operators = new RangeIndex.Operator[operatorSeq.getItemCount()];
int i = 0;
for (SequenceIterator si = operatorSeq.iterate(); si.hasNext(); i++) {
operators[i] = RangeIndexModule.OPERATOR_MAP.get(si.nextItem().getStringValue());
}
j++;
} else {
RangeIndex.Operator operator = getOperator();
operators = new RangeIndex.Operator[fieldSeq.getItemCount()];
Arrays.fill(operators, operator);
}
Sequence[] keys = new Sequence[getArgumentCount() - j];
for (int i = j; i < getArgumentCount(); i++) {
keys[i - j] = Atomize.atomize(getArgument(i).eval(contextSequence));
}
DocumentSet docs = contextSequence.getDocumentSet();
RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
try {
preselectResult = index.queryField(getExpressionId(), docs, useContext ? contextSequence.toNodeSet() : null, fieldSeq, keys, operators, NodeSet.DESCENDANT);
} catch (IOException e) {
throw new XPathException(this, "Error while querying full text index: " + e.getMessage(), e);
}
LOG.info("preselect for {} on {}returned {} and took {}", Arrays.toString(keys), contextSequence.getItemCount(), preselectResult.getItemCount(), System.currentTimeMillis() - start);
if (context.getProfiler().traceFunctions()) {
context.getProfiler().traceIndexUsage(context, "new-range", this, PerformanceStats.OPTIMIZED_INDEX, System.currentTimeMillis() - start);
}
// preselectResult.setSelfAsContext(getContextId());
return preselectResult;
}
use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.
the class IndexKeys method eval.
@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
int arg = 0;
final String field = args[arg++].getStringValue();
String start = null;
if (args.length == 4) {
start = args[arg++].getStringValue();
}
try (final FunctionReference ref = (FunctionReference) args[arg++].itemAt(0)) {
int max = -1;
if (!args[arg].isEmpty()) {
max = ((IntegerValue) args[arg].itemAt(0)).getInt();
}
final Sequence result = new ValueSequence();
final RangeIndexWorker worker = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexName("range-index");
Occurrences[] occur = worker.scanIndexByField(field, contextSequence == null ? context.getStaticallyKnownDocuments() : contextSequence.getDocumentSet(), start, max);
final int len = (max != -1 && occur.length > max ? max : occur.length);
final Sequence[] params = new Sequence[2];
ValueSequence data = new ValueSequence();
for (int j = 0; j < len; j++) {
params[0] = new StringValue(occur[j].getTerm().toString());
data.add(new IntegerValue(occur[j].getOccurrences(), Type.UNSIGNED_INT));
data.add(new IntegerValue(occur[j].getDocuments(), Type.UNSIGNED_INT));
data.add(new IntegerValue(j + 1, Type.UNSIGNED_INT));
params[1] = data;
result.addAll(ref.evalFunction(Sequence.EMPTY_SEQUENCE, null, params));
data.clear();
}
return result;
}
}
use of org.exist.indexing.range.RangeIndexWorker in project exist by eXist-db.
the class Optimize method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
if (!context.getSubject().hasDbaRole())
throw new XPathException(this, "user has to be a member of the dba group to call " + "the optimize function. Calling user was " + context.getSubject().getName());
RangeIndexWorker index = (RangeIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(RangeIndex.ID);
index.optimize();
return Sequence.EMPTY_SEQUENCE;
}
use of org.exist.indexing.range.RangeIndexWorker 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;
}
Aggregations