use of org.sirix.index.SearchMode in project sirix by sirixdb.
the class CASIndexImpl method openIndex.
@Override
public Iterator<NodeReferences> openIndex(PageReadTrx pageReadTrx, IndexDef indexDef, CASFilter filter) {
final AVLTreeReader<CASValue, NodeReferences> reader = AVLTreeReader.getInstance(pageReadTrx, indexDef.getType(), indexDef.getID());
// PCRs requested.
final Set<Long> pcrsRequested = filter.getPCRs();
// PCRs available in index.
final Set<Long> pcrsAvailable = filter.getPCRCollector().getPCRsForPaths(indexDef.getPaths()).getPCRs();
// CASValue.
if (pcrsAvailable.size() <= 1 && pcrsRequested.size() == 1) {
final Atomic atomic = filter.getKey();
final long pcr = pcrsRequested.iterator().next();
final SearchMode mode = filter.getMode();
final CASValue value = new CASValue(atomic, atomic.type(), pcr);
if (mode == SearchMode.EQUAL) {
// Compare for equality by PCR and atomic value.
final Optional<AVLNode<CASValue, NodeReferences>> node = reader.getAVLNode(value, mode);
if (node.isPresent()) {
return Iterators.forArray(node.get().getValue());
}
return Collections.emptyIterator();
} else {
// Compare for search criteria by PCR and atomic value.
final Optional<AVLNode<CASValue, NodeReferences>> node = reader.getAVLNode(value, mode);
if (node.isPresent()) {
// Iterate over subtree.
final Iterator<AVLNode<CASValue, NodeReferences>> iter = reader.new AVLNodeIterator(node.get().getNodeKey());
return Iterators.concat(Iterators.forArray(node.get().getValue()), new IndexFilterAxis<CASValue>(iter, ImmutableSet.of(filter)));
}
return Collections.emptyIterator();
}
} else if (pcrsRequested.size() == 1) {
final Atomic atomic = filter.getKey();
final long pcr = pcrsRequested.iterator().next();
final SearchMode mode = filter.getMode();
final CASValue value = new CASValue(atomic, atomic.type(), pcr);
if (mode == SearchMode.EQUAL) {
// Compare for equality by PCR and atomic value.
final Optional<AVLNode<CASValue, NodeReferences>> node = reader.getAVLNode(value, mode);
if (node.isPresent()) {
// Iterate over subtree.
final Iterator<AVLNode<CASValue, NodeReferences>> iter = reader.new AVLNodeIterator(node.get().getNodeKey());
return Iterators.concat(Iterators.forArray(node.get().getValue()), new IndexFilterAxis<CASValue>(iter, ImmutableSet.of(filter)));
}
return Collections.emptyIterator();
} else {
// Compare for equality only by PCR.
final Optional<AVLNode<CASValue, NodeReferences>> node = reader.getAVLNode(value, SearchMode.EQUAL, (CASValue v1, CASValue v2) -> ((Long) v1.getPathNodeKey()).compareTo(v2.getPathNodeKey()));
if (node.isPresent()) {
// Now compare for equality by PCR and atomic value and find first
// node which satisfies criteria.
final Optional<AVLNode<CASValue, NodeReferences>> firstFoundNode = reader.getAVLNode(node.get().getNodeKey(), value, mode);
if (firstFoundNode.isPresent()) {
// Iterate over subtree.
final Iterator<AVLNode<CASValue, NodeReferences>> iter = reader.new AVLNodeIterator(firstFoundNode.get().getNodeKey());
return Iterators.concat(Iterators.forArray(firstFoundNode.get().getValue()), new IndexFilterAxis<CASValue>(iter, ImmutableSet.of(filter)));
} else {
return Iterators.forArray(firstFoundNode.get().getValue());
}
}
return Collections.emptyIterator();
}
} else {
final Iterator<AVLNode<CASValue, NodeReferences>> iter = reader.new AVLNodeIterator(Fixed.DOCUMENT_NODE_KEY.getStandardProperty());
return new IndexFilterAxis<CASValue>(iter, ImmutableSet.of(filter));
}
}
use of org.sirix.index.SearchMode in project sirix by sirixdb.
the class ScanCASIndex method execute.
@Override
public Sequence execute(StaticContext sctx, QueryContext ctx, Sequence[] args) throws QueryException {
final DBNode doc = (DBNode) args[0];
final XdmNodeReadTrx rtx = doc.getTrx();
final IndexController controller = rtx.getResourceManager().getRtxIndexController(rtx.getRevisionNumber());
if (controller == null) {
throw new QueryException(new QNm("Document not found: " + ((Str) args[1]).stringValue()));
}
final int idx = FunUtil.getInt(args, 1, "$idx-no", -1, null, true);
final IndexDef indexDef = controller.getIndexes().getIndexDef(idx, IndexType.CAS);
if (indexDef == null) {
throw new QueryException(SDBFun.ERR_INDEX_NOT_FOUND, "Index no %s for collection %s and document %s not found.", idx, doc.getCollection().getName(), doc.getTrx().getResourceManager().getResourceConfig().getResource().getFileName().toString());
}
if (indexDef.getType() != IndexType.CAS) {
throw new QueryException(SDBFun.ERR_INVALID_INDEX_TYPE, "Index no %s for collection %s and document %s is not a CAS index.", idx, doc.getCollection().getName(), doc.getTrx().getResourceManager().getResourceConfig().getResource().getFileName().toString());
}
final Type keyType = indexDef.getContentType();
final Atomic key = Cast.cast(sctx, (Atomic) args[2], keyType, true);
FunUtil.getBoolean(args, 3, "$include-low-key", true, true);
final int[] searchModes = new int[] { -2, -1, 0, 1, 2 };
final int searchMode = FunUtil.getInt(args, 4, "$search-mode", 0, searchModes, true);
final SearchMode mode;
switch(searchMode) {
case -2:
mode = SearchMode.LESS;
break;
case -1:
mode = SearchMode.LESS_OR_EQUAL;
break;
case 0:
mode = SearchMode.EQUAL;
break;
case 1:
mode = SearchMode.GREATER;
break;
case 2:
mode = SearchMode.GREATER_OR_EQUAL;
break;
default:
// May never happen.
mode = SearchMode.EQUAL;
}
final String paths = FunUtil.getString(args, 5, "$paths", null, null, false);
final CASFilter filter = (paths != null) ? controller.createCASFilter(paths.split(";"), key, mode, new PCRCollectorImpl(rtx)) : controller.createCASFilter(new String[] {}, key, mode, new PCRCollectorImpl(rtx));
final IndexController ic = controller;
final DBNode node = doc;
return new LazySequence() {
@Override
public Iter iterate() {
return new BaseIter() {
Stream<?> s;
@Override
public Item next() throws QueryException {
if (s == null) {
s = new SirixNodeKeyStream(ic.openCASIndex(node.getTrx().getPageTrx(), indexDef, filter), node.getCollection(), node.getTrx());
}
return (Item) s.next();
}
@Override
public void close() {
if (s != null) {
s.close();
}
}
};
}
};
}
Aggregations