io.sirix.access.trx.node.AbstractIndexController 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.access.trx.node;
import io.sirix.api.*;
import io.sirix.index.*;
import io.brackit.query.atomic.Atomic;
import io.brackit.query.atomic.QNm;
import io.brackit.query.jdm.DocumentException;
import io.brackit.query.util.path.Path;
import io.brackit.query.util.path.PathException;
import io.brackit.query.util.serialize.SubtreePrinter;
import org.checkerframework.checker.nullness.qual.NonNull;
import io.sirix.exception.SirixRuntimeException;
import io.sirix.index.cas.CASFilter;
import io.sirix.index.cas.CASFilterRange;
import io.sirix.index.cas.CASIndex;
import io.sirix.index.name.NameFilter;
import io.sirix.index.name.NameIndex;
import io.sirix.index.path.PCRCollector;
import io.sirix.index.path.PathFilter;
import io.sirix.index.path.PathIndex;
import io.sirix.index.path.summary.PathSummaryReader;
import io.sirix.index.redblacktree.keyvalue.NodeReferences;
import io.sirix.node.interfaces.immutable.ImmutableNode;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import static java.util.Objects.requireNonNull;
public abstract class AbstractIndexController
implements IndexController {
/**
* The index types.
*/
protected final Indexes indexes;
/**
* Set of {@link ChangeListener}.
*/
private final Set listeners;
/**
* Used to provide path indexes.
*/
protected final PathIndex, ?> pathIndex;
/**
* Used to provide CAS indexes.
*/
protected final CASIndex, ?, R> casIndex;
/**
* Used to provide name indexes.
*/
protected final NameIndex, ?> nameIndex;
/**
* Constructor.
*
* @param indexes the index definitions
* @param listeners the set of listeners
* @param pathIndex the path index manager
* @param casIndex the CAS index manager
* @param nameIndex the name index manager
*/
public AbstractIndexController(final Indexes indexes, final Set listeners,
final PathIndex, ?> pathIndex, final CASIndex, ?, R> casIndex, final NameIndex, ?> nameIndex) {
this.indexes = indexes;
this.listeners = listeners;
this.pathIndex = pathIndex;
this.casIndex = casIndex;
this.nameIndex = nameIndex;
}
@Override
public boolean containsIndex(final IndexType type) {
for (final IndexDef indexDef : indexes.getIndexDefs()) {
if (indexDef.getType() == type)
return true;
}
return false;
}
@Override
public Indexes getIndexes() {
return indexes;
}
@Override
public void serialize(final OutputStream out) {
try {
final SubtreePrinter serializer = new SubtreePrinter(new PrintStream(requireNonNull(out)));
serializer.print(indexes.materialize());
serializer.end();
} catch (final DocumentException e) {
throw new SirixRuntimeException(e);
}
}
@Override
public void notifyChange(final ChangeType type, @NonNull final ImmutableNode node, final long pathNodeKey) {
if (listeners.isEmpty()) {
return;
}
for (final ChangeListener listener : listeners) {
listener.listen(type, node, pathNodeKey);
}
}
@Override
public IndexController createIndexListeners(final Set indexDefs, final W nodeWriteTrx) {
requireNonNull(nodeWriteTrx);
// Save for upcoming modifications.
for (final IndexDef indexDef : indexDefs) {
indexes.add(indexDef);
switch (indexDef.getType()) {
case PATH ->
listeners.add(createPathIndexListener(nodeWriteTrx.getPageWtx(), nodeWriteTrx.getPathSummary(), indexDef));
case CAS ->
listeners.add(createCASIndexListener(nodeWriteTrx.getPageWtx(), nodeWriteTrx.getPathSummary(), indexDef));
case NAME -> listeners.add(createNameIndexListener(nodeWriteTrx.getPageWtx(), indexDef));
default -> {
}
}
}
return this;
}
private ChangeListener createPathIndexListener(final PageTrx pageWriteTrx, final PathSummaryReader pathSummaryReader,
final IndexDef indexDef) {
return pathIndex.createListener(pageWriteTrx, pathSummaryReader, indexDef);
}
private ChangeListener createCASIndexListener(final PageTrx pageWriteTrx, final PathSummaryReader pathSummaryReader,
final IndexDef indexDef) {
return casIndex.createListener(pageWriteTrx, pathSummaryReader, indexDef);
}
private ChangeListener createNameIndexListener(final PageTrx pageWriteTrx, final IndexDef indexDef) {
return nameIndex.createListener(pageWriteTrx, indexDef);
}
@Override
public NameFilter createNameFilter(final Set names) {
final Set includes = new HashSet<>(names.size());
for (final String name : names) {
// TODO: Prefix/NspURI
includes.add(new QNm(name));
}
return new NameFilter(includes, Collections.emptySet());
}
@Override
public CASFilter createCASFilter(final Set stringPaths, final Atomic key, final SearchMode mode,
final PCRCollector pcrCollector) throws PathException {
final Set> paths = new HashSet<>(stringPaths.size());
if (!stringPaths.isEmpty()) {
for (final String path : stringPaths) {
paths.add(parsePath(path));
}
}
return new CASFilter(paths, key, mode, pcrCollector);
}
protected abstract Path parsePath(String path);
@Override
public CASFilterRange createCASFilterRange(final Set thePaths, final Atomic min, final Atomic max,
final boolean incMin, final boolean incMax, final PCRCollector pcrCollector) throws PathException {
final Set> paths = new HashSet<>(thePaths.size());
if (!thePaths.isEmpty()) {
for (final String path : thePaths) {
paths.add(parsePath(path));
}
}
return new CASFilterRange(paths, min, max, incMin, incMax, pcrCollector);
}
@Override
public Iterator openPathIndex(final PageReadOnlyTrx pageRtx, final IndexDef indexDef,
final PathFilter filter) {
if (pathIndex == null) {
throw new IllegalStateException("This document does not support path indexes.");
}
return pathIndex.openIndex(pageRtx, indexDef, filter);
}
@Override
public Iterator openNameIndex(final PageReadOnlyTrx pageRtx, final IndexDef indexDef,
final NameFilter filter) {
if (nameIndex == null) {
throw new IllegalStateException("This document does not support name indexes.");
}
return nameIndex.openIndex(pageRtx, indexDef, filter);
}
@Override
public Iterator openCASIndex(final PageReadOnlyTrx pageRtx, final IndexDef indexDef,
final CASFilter filter) {
if (casIndex == null) {
throw new IllegalStateException("This document does not support CAS indexes.");
}
return casIndex.openIndex(pageRtx, indexDef, filter);
}
@Override
public Iterator openCASIndex(final PageReadOnlyTrx pageRtx, final IndexDef indexDef,
final CASFilterRange filter) {
if (casIndex == null) {
throw new IllegalStateException("This document does not support path indexes.");
}
return casIndex.openIndex(pageRtx, indexDef, filter);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy