Package at.jku.sii.sqlitereader.btree

Source Code of at.jku.sii.sqlitereader.btree.PayloadCell

package at.jku.sii.sqlitereader.btree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import at.jku.sii.sqlitereader.SqliteDataBase;
import at.jku.sii.sqlitereader.io.AdvancedDataInput.Varint;
import at.jku.sii.sqlitereader.io.ArrayDataInput;
import at.jku.sii.sqlitereader.io.ChainedArrayDataInput;
import at.jku.sii.sqlitereader.page.PayloadOverflowPage;
import at.jku.sii.sqlitereader.record.Record;

public abstract class PayloadCell implements Cell {

  private final long numPayloadBytes;
  private final ArrayDataInput payload;

  private final int overflowPage;
  private final List<PayloadOverflowPage> overflowPages;

  private Record record;

  PayloadCell(Varint numPayloadBytes, Type type, ArrayDataInput in, SqliteDataBase db) {
    this.numPayloadBytes = numPayloadBytes.value;
    int payloadSize = getInternalPayloadSize(type, db, this.numPayloadBytes);
    byte[] data = new byte[payloadSize];
    in.readFully(data);
    this.payload = new ArrayDataInput(data, in.createLastSubAnnotator(payloadSize));
    in.annotateLast(payloadSize, "Payload");

    if (payloadSize < this.numPayloadBytes) {
      this.overflowPage = in.readInt("overflowPage");
      this.overflowPages = new ArrayList<PayloadOverflowPage>();
    } else {
      this.overflowPage = -1;
      this.overflowPages = Collections.emptyList();
    }
  }

  protected static int getInternalPayloadSize(Type type, SqliteDataBase db, long numPayloadBytes) {
    long p = numPayloadBytes;
    int u = db.getUsableSize();
    long m = ((u - 12) * 32 / 255) - 23;
    switch (type) {
    case TABLE_LEAF:
      if (p <= u - 35) { // everything in cell
        return (int) p;
      } else {
        return (int) (Math.min(m + ((p - m) % (u - 4)), u - 35));
      }
    case TABLE_INTERIOR:
      return 0; // no payload
    case INDEX_INTERIOR:
    case INDEX_LEAF:
      long x = ((u - 12) * 64 / 255) - 23;
      if (p <= x)
        return (int) p;
      else {
        return (int) (Math.min(m + ((p - m) % (u - 4)), x));
      }
    }
    throw new IllegalStateException();
  }

  public final void resolveOverflowPages(SqliteDataBase db) {
    if (this.overflowPage <= 0)
      return;
    this.overflowPages.addAll(PayloadOverflowPage.readOverflowPages(db, this.overflowPage));

  }

  public final long getNumPlayloadBytes() {
    return this.numPayloadBytes;
  }

  public final Record getRecord() {
    return this.record;
  }

  private boolean resolvedOveflowPages() {
    return this.overflowPage <= 0 || !this.overflowPages.isEmpty();
  }

  public final void readRecords(SqliteDataBase db) {
    assert (this.resolvedOveflowPages());
    List<ArrayDataInput> l = new ArrayList<ArrayDataInput>();
    l.add(this.payload);
    for (PayloadOverflowPage o : this.overflowPages)
      l.add(o.getData());
    final ChainedArrayDataInput in = new ChainedArrayDataInput(l);
    this.record = Record.read(in, db.getEncoding());
    in.annotateLast((int) in.currentPosition(), "Record");
    // TODO clean up?
  }

  @Override
  public String toString() {
    return String.format("PayloadCell [%s]", this.toStringAttr());
  }

  protected final String toStringAttr() {
    return String.format("numPayloadBytes=%s, overflowPage=%s, overflowPages=%s", this.numPayloadBytes, this.overflowPage, this.overflowPages);
  }

  @Override
  public void dump(StringBuilder b) {
    b.append(this.toString());
  }
}
TOP

Related Classes of at.jku.sii.sqlitereader.btree.PayloadCell

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.