io.sirix.index.cas.CASIndex Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sirix-core Show documentation
Show all versions of sirix-core Show documentation
SirixDB is a hybrid on-disk and in-memory document oriented, versioned database system. It has a lightweight buffer manager, stores everything in a huge persistent and durable tree and allows efficient reconstruction of every revision. Furthermore, SirixDB implements change tracking, diffing and supports time travel queries.
package io.sirix.index.cas;
import com.google.common.collect.Iterators;
import io.sirix.api.NodeCursor;
import io.sirix.api.NodeReadOnlyTrx;
import io.sirix.api.PageReadOnlyTrx;
import io.sirix.api.PageTrx;
import io.sirix.index.ChangeListener;
import io.sirix.index.IndexDef;
import io.sirix.index.IndexFilterAxis;
import io.sirix.index.SearchMode;
import io.sirix.index.redblacktree.RBNodeKey;
import io.sirix.index.redblacktree.RBNodeValue;
import io.sirix.index.redblacktree.RBTreeReader;
import io.sirix.index.redblacktree.keyvalue.CASValue;
import io.sirix.index.redblacktree.keyvalue.NodeReferences;
import io.sirix.settings.Fixed;
import io.brackit.query.atomic.Atomic;
import io.sirix.index.path.summary.PathSummaryReader;
import java.util.*;
import java.util.function.Function;
public interface CASIndex {
B createBuilder(R rtx, PageTrx pageWriteTrx, PathSummaryReader pathSummaryReader, IndexDef indexDef);
L createListener(PageTrx pageWriteTrx, PathSummaryReader pathSummaryReader, IndexDef indexDef);
default Iterator openIndex(PageReadOnlyTrx pageRtx, IndexDef indexDef, CASFilterRange filter) {
final RBTreeReader reader =
RBTreeReader.getInstance(pageRtx.getResourceSession().getIndexCache(),
pageRtx,
indexDef.getType(),
indexDef.getID());
final Iterator> iter = reader.new RBNodeIterator(Fixed.DOCUMENT_NODE_KEY.getStandardProperty());
return new IndexFilterAxis<>(reader, iter, Set.of(filter));
}
default Iterator openIndex(PageReadOnlyTrx pageRtx, IndexDef indexDef, CASFilter filter) {
final RBTreeReader reader =
RBTreeReader.getInstance(pageRtx.getResourceSession().getIndexCache(),
pageRtx,
indexDef.getType(),
indexDef.getID());
// PCRs requested.
final Set pcrsRequested = filter == null ? Set.of() : filter.getPCRs();
// PCRs available in index.
final Set pcrsAvailable = filter == null
? Collections.emptySet()
: filter.getPCRCollector().getPCRsForPaths(indexDef.getPaths()).getPCRs();
// Only one path indexed and requested. All PCRs are the same in each 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 != null ? atomic.type() : null, pcr);
if (mode == SearchMode.EQUAL) {
// Compare for equality by PCR and atomic value.
final Optional> optionalNode = reader.getCurrentNodeAsRBNodeKey(value, mode);
return optionalNode.map(node -> {
reader.moveTo(node.getValueNodeKey());
final RBNodeValue currentNodeAsRBNodeValue = reader.getCurrentNodeAsRBNodeValue();
assert currentNodeAsRBNodeValue != null;
return Iterators.forArray(currentNodeAsRBNodeValue.getValue());
}).orElse(Iterators.unmodifiableIterator(Collections.emptyIterator()));
} else {
// Compare for search criteria by PCR and atomic value.
final Optional> optionalNode = reader.getCurrentNodeAsRBNodeKey(value, mode);
return optionalNode.map(concatWithFilterAxis(filter, reader)).orElse(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> optionalNode = reader.getCurrentNodeAsRBNodeKey(value, mode);
return optionalNode.map(concatWithFilterAxis(filter, reader)).orElse(Collections.emptyIterator());
} else {
// Compare for equality only by PCR.
final Optional> optionalNode = reader.getCurrentNodeAsRBNodeKey(value,
SearchMode.EQUAL,
Comparator.comparingLong(
CASValue::getPathNodeKey));
return optionalNode.map(findFirstNodeWithMatchingPCRAndAtomicValue(filter, reader, mode, value))
.orElse(Collections.emptyIterator());
}
} else {
final Iterator> iter =
reader.new RBNodeIterator(Fixed.DOCUMENT_NODE_KEY.getStandardProperty());
return new IndexFilterAxis<>(reader, iter, filter == null ? Set.of() : Set.of(filter));
}
}
private Function, Iterator> findFirstNodeWithMatchingPCRAndAtomicValue(
CASFilter filter, RBTreeReader reader, SearchMode mode, CASValue value) {
return node -> {
// Now compare for equality by PCR and atomic value and find first
// node which satisfies criteria.
final Optional> firstFoundNode =
reader.getCurrentNodeAsRBNodeKey(node.getNodeKey(), value, mode);
return firstFoundNode.map(theNode -> {
// Iterate over subtree.
final Iterator> iter = reader.new RBNodeIterator(theNode.getNodeKey());
return (Iterator) new IndexFilterAxis<>(reader, iter, Set.of(filter));
}).orElse(Collections.emptyIterator());
};
}
private Function, Iterator> concatWithFilterAxis(CASFilter filter,
RBTreeReader reader) {
return node -> {
// Iterate over subtree.
final Iterator> iter = reader.new RBNodeIterator(node.getNodeKey());
return new IndexFilterAxis<>(reader, iter, Set.of(filter));
};
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy