Package at.jku.sii.sqlitereader.page

Source Code of at.jku.sii.sqlitereader.page.PointerMapPage$TailPayLoadOverflowBackLinkInfo

/*$Id$*/
package at.jku.sii.sqlitereader.page;

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

import at.jku.sii.sqlitereader.DumpUtils;
import at.jku.sii.sqlitereader.Dumpable;
import at.jku.sii.sqlitereader.SqliteDataBase;
import at.jku.sii.sqlitereader.io.ArrayDataInput;

public final class PointerMapPage implements Page {
  public enum PageType {
    ROOT_BTREE, FREELIST, FIRST_PAYLOAD_OVERFLOW, TAIL_PAYLOAD_OVERFLOW, NON_ROOT_BTREE
  }

  private final int number;
  private final List<BackLinkInfo> infos;
  private final int pageOffset;

  public PointerMapPage(int number, int startPage, List<BackLinkInfo> infos) {
    this.infos = infos;
    this.pageOffset = startPage;
    this.number = number;
  }

  @Override
  public int getNumber() {
    return this.number;
  }

  public BackLinkInfo getInfoFor(int pageNum) {
    if (pageNum < this.pageOffset || pageNum > (this.pageOffset + this.infos.size()))
      return null;
    return this.infos.get(pageNum - this.pageOffset);
  }

  public List<BackLinkInfo> getInfos() {
    return this.infos;
  }

  public int getPageOffset() {
    return this.pageOffset;
  }

  public static boolean mustHavePointerMapPage(SqliteDataBase db) {
    return db.getLargestBTreePage() > 0;
  }

  public static boolean mustNotHavePointerMapPage(SqliteDataBase db) {
    return db.getLargestBTreePage() == 0;
  }

  private static PointerMapPage read(int number, int pageOffset, int numEntries, ArrayDataInput block) {
    List<BackLinkInfo> infos = new ArrayList<BackLinkInfo>();
    for (int i = 0; i < numEntries; ++i) {
      PageType type = PageType.values()[block.readByte()];
      block.annotateLastByte("Pagetype", type);
      int pageNumber = block.readInt("pageNumber");
      switch (type) {
      case ROOT_BTREE:
        infos.add(new SimpleBackLinkInfo(type));
        break;
      case FREELIST:
        infos.add(new SimpleBackLinkInfo(type));
        break;
      case FIRST_PAYLOAD_OVERFLOW:
        infos.add(new FirstPayLoadOverflowBackLinkInfo(pageNumber));
        break;
      case TAIL_PAYLOAD_OVERFLOW:
        infos.add(new TailPayLoadOverflowBackLinkInfo(pageNumber));
        break;
      case NON_ROOT_BTREE:
        infos.add(new NonRootBTreeBackLinkInfo(pageNumber));
        break;
      }
      block.annotateLast(5, "BackLinkInfo", infos.get(infos.size() - 1));
    }
    return new PointerMapPage(number, pageOffset, infos);
  }

  public static List<PointerMapPage> readPointerMapPages(SqliteDataBase db) {
    List<PointerMapPage> pages = new ArrayList<PointerMapPage>();
    if (mustNotHavePointerMapPage(db))
      return pages;

    int j = db.getUsableSize() / 5;
    int numPages = db.getNumPages();

    int pmpPage = 2; //start at 2
    int pageOffset = 3;
    while (pmpPage < numPages) {

      ArrayDataInput block = db.getPageBlock(pmpPage);

      PointerMapPage page = read(pmpPage, pageOffset, Math.min(numPages - pageOffset + 1, j), block);
      db.resolvePage(pmpPage, page);

      pages.add(page);
      pageOffset += j+1;
    }
    return pages;
  }

  static BackLinkInfo getBackInfoFor(int pageNum, Iterable<PointerMapPage> pages) {
    if (pageNum <= 3)
      return null;
    for (PointerMapPage p : pages) {
      BackLinkInfo info = p.getInfoFor(pageNum);
      if (info != null)
        return info;
    }
    return null;
  }

  public interface BackLinkInfo extends Dumpable {
    PageType getType();
  }

  public static final class SimpleBackLinkInfo implements BackLinkInfo {
    private final PageType type;

    public SimpleBackLinkInfo(PageType type) {
      this.type = type;
    }
    @Override
    public PageType getType() {
      return this.type;
    }

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

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

  public static final class FirstPayLoadOverflowBackLinkInfo implements BackLinkInfo {
    private final int pageNumber;

    public FirstPayLoadOverflowBackLinkInfo(int pageNumber) {
      this.pageNumber = pageNumber;
    }

    @Override
    public PageType getType() {
      return PageType.FIRST_PAYLOAD_OVERFLOW;
    }

    public int getContainingBTreePageNumber() {
      return this.pageNumber;
    }

    @Override
    public String toString() {
      return String.format("FirstPayLoadOverflowBackLinkInfo [containingBTreePageNumber=%s]", this.getContainingBTreePageNumber());
    }

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

  public static final class TailPayLoadOverflowBackLinkInfo implements BackLinkInfo {
    private final int pageNumber;

    public TailPayLoadOverflowBackLinkInfo(int pageNumber) {
      this.pageNumber = pageNumber;
    }

    @Override
    public PageType getType() {
      return PageType.TAIL_PAYLOAD_OVERFLOW;
    }

    public int getPriorOverflowPageNumber() {
      return this.pageNumber;
    }

    @Override
    public String toString() {
      return String.format("TailPayLoadOverflowBackLinkInfo [priorOverflowPageNumber=%s]", this.getPriorOverflowPageNumber());
    }

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

  }

  public static final class NonRootBTreeBackLinkInfo implements BackLinkInfo {
    private final int pageNumber;

    public NonRootBTreeBackLinkInfo(int pageNumber) {
      this.pageNumber = pageNumber;
    }

    @Override
    public PageType getType() {
      return PageType.NON_ROOT_BTREE;
    }

    public int getParentBTreePageNumber() {
      return this.pageNumber;
    }

    @Override
    public String toString() {
      return String.format("NonRootBTreeBackLinkInfo [parentBTreePageNumber=%s]", this.getParentBTreePageNumber());
    }

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

  }

  @Override
  public String toString() {
    return String.format("PointerMapPage [infos=%s, pageOffset=%s]", this.infos, this.pageOffset);
  }

  @Override
  public void dump(StringBuilder b) {
    b.append("<h3>PointerMap Page ").append(this.number).append("</h3>\n");
    b.append("<pre>");
    b.append(" pageOffset\t= ").append(this.pageOffset);
    b.append(" infos: \n");
    DumpUtils.join(this.infos, b, "\n");
    b.append("</pre>");
  }
}
TOP

Related Classes of at.jku.sii.sqlitereader.page.PointerMapPage$TailPayLoadOverflowBackLinkInfo

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.