All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.sirix.access.trx.node.AbstractIndexController Maven / Gradle / Ivy

Go to download

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.

There is a newer version: 0.11.0
Show newest version
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 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 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