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

org.sirix.page.HashedKeyValuePage 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 org.sirix.page;

import com.google.common.collect.Iterators;
import org.sirix.access.ResourceConfiguration;
import org.sirix.api.PageReadOnlyTrx;
import org.sirix.api.PageTrx;
import org.sirix.exception.SirixIOException;
import org.sirix.index.IndexType;
import org.sirix.node.DeweyIDNode;
import org.sirix.node.SirixDeweyID;
import org.sirix.node.interfaces.DataRecord;
import org.sirix.node.interfaces.NodePersistenter;
import org.sirix.node.interfaces.RecordSerializer;
import org.sirix.page.interfaces.KeyValuePage;

import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

import static org.sirix.node.Utils.getVarLong;
import static org.sirix.node.Utils.putVarLong;

public final class HashedKeyValuePage> implements KeyValuePage {
  private final Map records;
  private final int revision;
  private final long recordPageKey;
  private final PageReadOnlyTrx pageReadOnlyTrx;
  private final IndexType indexType;
  private final ResourceConfiguration resourceConfig;
  private final RecordSerializer recordPersister;

  /**
   * Copy constructor.
   *
   * @param pageReadOnlyTrx the page read-only trx
   * @param pageToClone     the page to clone
   */
  public HashedKeyValuePage(final PageReadOnlyTrx pageReadOnlyTrx, final HashedKeyValuePage pageToClone) {
    resourceConfig = pageReadOnlyTrx.getResourceManager().getResourceConfig();
    this.pageReadOnlyTrx = pageToClone.pageReadOnlyTrx;
    records = pageToClone.records;
    revision = pageToClone.revision;
    recordPageKey = pageToClone.recordPageKey;
    indexType = pageToClone.indexType;
    recordPersister = pageToClone.recordPersister;
  }

  /**
   * Constructor which initializes a new {@link UnorderedKeyValuePage}.
   *
   * @param recordPageKey   base key assigned to this node page
   * @param indexType       the index type
   * @param pageReadOnlyTrx the page reading transaction
   */
  public HashedKeyValuePage(@NonNegative final long recordPageKey, final IndexType indexType,
      final PageReadOnlyTrx pageReadOnlyTrx) {
    // Assertions instead of checkNotNull(...) checks as it's part of the
    // internal flow.
    assert recordPageKey >= 0 : "recordPageKey must not be negative!";
    assert pageReadOnlyTrx != null : "The page reading trx must not be null!";

    resourceConfig = pageReadOnlyTrx.getResourceManager().getResourceConfig();
    recordPersister = resourceConfig.recordPersister;
    this.recordPageKey = recordPageKey;
    records = new LinkedHashMap<>();
    this.pageReadOnlyTrx = pageReadOnlyTrx;
    revision = pageReadOnlyTrx.getRevisionNumber();
    this.indexType = indexType;
  }

  /**
   * Constructor which reads the {@link HashedKeyValuePage} from the storage.
   *
   * @param in              input bytes to read page from
   * @param pageReadOnlyTrx {@link PageReadOnlyTrx} implementation
   */
  protected HashedKeyValuePage(final DataInput in, final PageReadOnlyTrx pageReadOnlyTrx) throws IOException {
    this.pageReadOnlyTrx = pageReadOnlyTrx;

    resourceConfig = pageReadOnlyTrx.getResourceManager().getResourceConfig();
    recordPersister = resourceConfig.recordPersister;
    revision = pageReadOnlyTrx.getRevisionNumber();

    final var size = in.readInt();
    records = new LinkedHashMap<>(size);
    indexType = IndexType.getType(in.readByte());
    recordPageKey = getVarLong(in);

    if (indexType == IndexType.DEWEYID_TO_RECORDID && resourceConfig.areDeweyIDsStored
        && recordPersister instanceof NodePersistenter persistenter) {
      byte[] optionalDeweyId = null;

      for (int index = 0; index < size; index++) {
        final byte[] deweyID = persistenter.deserializeDeweyID(in, optionalDeweyId, resourceConfig);

        optionalDeweyId = deweyID;

        if (deweyID != null) {
          deserializeRecordAndPutIntoMap(in, new SirixDeweyID(deweyID));
        }
      }
    }
  }

  private void deserializeRecordAndPutIntoMap(DataInput in, SirixDeweyID deweyId) {
    try {
      final long nodeKey = getVarLong(in);
      records.put((K) deweyId, new DeweyIDNode(nodeKey, deweyId));
    } catch (final IOException e) {
      throw new SirixIOException(e);
    }
  }

  @Override
  public Set> entrySet() {
    return records.entrySet();
  }

  @Override
  public Collection values() {
    return records.values();
  }

  @Override
  public long getPageKey() {
    return recordPageKey;
  }

  @Override
  public DataRecord getValue(K key) {
    return records.get(key);
  }

  @Override
  public void setRecord(K key, @NonNull DataRecord value) {
    records.put(key, value);
  }

  @Override
  public Set> referenceEntrySet() {
    return Collections.emptySet();
  }

  @Override
  public void setPageReference(K key, @NonNull PageReference reference) {
  }

  @Override
  public PageReference getPageReference(K key) {
    return null;
  }

  @Override
  public > C newInstance(long recordPageKey, @NonNull IndexType indexType,
      @NonNull PageReadOnlyTrx pageReadOnlyTrx) {
    return (C) new HashedKeyValuePage(recordPageKey, indexType, pageReadOnlyTrx);
  }

  @Override
  public PageReadOnlyTrx getPageReadOnlyTrx() {
    return pageReadOnlyTrx;
  }

  @Override
  public IndexType getIndexType() {
    return IndexType.DEWEYID_TO_RECORDID;
  }

  @Override
  public int size() {
    return records.size();
  }

  @Override
  public int getRevision() {
    return revision;
  }

  @Override
  public void serialize(DataOutput out, SerializationType type) throws IOException {
    out.writeInt(records.size());
    out.writeByte(indexType.getID());
    putVarLong(out, recordPageKey);

    // Check for dewey IDs.
    if (indexType == IndexType.DEWEYID_TO_RECORDID && resourceConfig.areDeweyIDsStored
        && recordPersister instanceof NodePersistenter persistence && !records.isEmpty()) {
      final Set recordKeys = records.keySet();
      final K firstRecord = recordKeys.iterator().next();

      if (firstRecord instanceof SirixDeweyID) {
//        // Write dewey IDs.
//        final List ids = new ArrayList<>((Collection) recordKeys);
//        final List sirixDeweyIds = ids.stream().map(SirixDeweyID::toBytes).collect(Collectors.toList());
//        sirixDeweyIds.sort(Comparator.comparingInt((byte[] sirixDeweyID) -> sirixDeweyID.length));
//        final var iter = Iterators.peekingIterator(sirixDeweyIds.iterator());
//        byte[] id = null;
//        if (iter.hasNext()) {
//          id = iter.next();
//          persistence.serializeDeweyID(out, id, null, resourceConfig);
//          serializeDeweyRecord(id, out);
//        }
//        while (iter.hasNext()) {
//          final var nextDeweyID = iter.next();
//          persistence.serializeDeweyID(out, id, nextDeweyID, resourceConfig);
//          serializeDeweyRecord(nextDeweyID, out);
//          id = nextDeweyID;
//        }
      }
    }
  }

  private void serializeDeweyRecord(SirixDeweyID id, DataOutput out) throws IOException {
    final DeweyIDNode node = (DeweyIDNode) records.get(id);
    final long nodeKey = node.getNodeKey();
    putVarLong(out, nodeKey);
  }

  @Override
  public List getReferences() {
    throw new UnsupportedOperationException();
  }

  @Override
  public void commit(@NonNull PageTrx pageTrx) {
  }

  @Override
  public PageReference getOrCreateReference(int offset) {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean setOrCreateReference(int offset, PageReference pageReference) {
    throw new UnsupportedOperationException();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy