/** Suck up tuples from the source file. */
  private Tuple readNextTuple(DataInputStream dis, int slotId) throws NoSuchElementException {
    // if associated bit is not set, read forward to the next tuple, and
    // return null.
    if (!getSlot(slotId)) {
      for (int i = 0; i < td.getSize(); i++) {
        try {
          dis.readByte();
        } catch (IOException e) {
          throw new NoSuchElementException("error reading empty tuple");
        }
      }
      return null;
    }

    // read fields in the tuple
    Tuple t = new Tuple(td);
    RecordID rid = new RecordID(pid, slotId);
    t.setRecordID(rid);
    try {
      for (int j = 0; j < td.numFields(); j++) {
        Field f = td.getType(j).parse(dis);
        t.setField(j, f);
      }
    } catch (java.text.ParseException e) {
      // e.printStackTrace();
      throw new NoSuchElementException("parsing error!");
    }

    return t;
  }
  /**
   * Generates a byte array representing the contents of this page. Used to serialize this page to
   * disk.
   *
   * <p>The invariant here is that it should be possible to pass the byte array generated by
   * getPageData to the HeapPage constructor and have it produce an identical HeapPage object.
   *
   * @see #HeapPage
   * @return A byte array correspond to the bytes of this page.
   */
  public byte[] getPageData() {
    // int len = header.length*4 + BufferPool.PAGE_SIZE;
    int len = BufferPool.PAGE_SIZE;
    ByteArrayOutputStream baos = new ByteArrayOutputStream(len);
    DataOutputStream dos = new DataOutputStream(baos);

    // create the header of the page
    try {
      dos.write(header.getHeader());
    } catch (IOException e) {
      // this really shouldn't happen
      e.printStackTrace();
    }

    // create the tuples
    for (int i = 0; i < numSlots; i++) {

      // empty slot
      if (!getSlot(i)) {
        for (int j = 0; j < td.getSize(); j++) {
          try {
            dos.writeByte(0);
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        continue;
      }

      // non-empty slot
      for (int j = 0; j < td.numFields(); j++) {
        Field f = tuples[i].getField(j);
        try {
          f.serialize(dos);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

    // padding
    int zerolen = BufferPool.PAGE_SIZE - numSlots * td.getSize() - header.length();
    byte[] zeroes = new byte[zerolen];
    try {
      dos.write(zeroes, 0, zerolen);
    } catch (IOException e) {
      e.printStackTrace();
    }

    try {
      dos.flush();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return baos.toByteArray();
  }
Beispiel #3
0
 public Tuple getNext() throws NoSuchElementException, TransactionAbortedException {
   try {
     Tuple tuple = new Tuple(td);
     for (int i = 0; i < td.numFields(); i++) {
       IntField intf = IntField.createIntField(in.readInt());
       tuple.setField(i, intf);
     }
     return tuple;
   } catch (EOFException eof) {
     throw new NoSuchElementException(eof.getMessage());
   } catch (Exception e) {
     e.printStackTrace();
     BufferPool.Instance().abortTransaction(tid);
     closeConnection();
     throw new TransactionAbortedException(e);
   }
 }
 /**
  * Adds the specified tuple to the page; the tuple should be updated to reflect that it is now
  * stored on this page.
  *
  * @throws DbException if the page is full (no empty slots) or tupledesc is mismatch.
  * @param t The tuple to add.
  */
 public void insertTuple(Tuple t) throws DbException {
   // some code goes here
   // not necessary for lab1
   RecordId targetrid = t.getRecordId();
   if (getNumEmptySlots() == 0 || !td.equals(t.getTupleDesc())) {
     throw new DbException("Either page is full or tuple desc doesn't match");
   }
   for (int i = 0; i < getNumTuples(); i++) {
     if (!isSlotUsed(i)) {
       markSlotUsed(i, true);
       RecordId rid = new RecordId(pid, i);
       t.setRecordId(rid);
       tuples[i] = t;
       return;
     }
   }
 }
  /**
   * Helper constructor to create a heap page to be used as buffer.
   *
   * @param data - Data to be put in tmp page
   * @param td - Tuple description for the corresponding table.
   * @throws IOException
   */
  private HeapPage(byte[] data, TupleDesc td) throws IOException {
    this.pid =
        null; // No need of a pid here as this page serves as a dummy buffer page and is meant to be
              // used independent of BufferManager.
    this.td = td;
    this.numSlots = (BufferPool.PAGE_SIZE * 8) / ((td.getSize() * 8) + 1);

    DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
    this.header = new Header(dis);

    try {
      // allocate and read the actual records of this page
      tuples = new Tuple[numSlots];
      for (int i = 0; i < numSlots; i++) {
        tuples[i] = readNextTuple(dis, i);
      }
    } catch (NoSuchElementException e) {
      e.printStackTrace();
    }

    dis.close();
  }
  /**
   * Create a HeapPage from a set of bytes of data read from disk. The format of a HeapPage is a set
   * of 32-bit header words indicating the slots of the page that are in use, plus
   * (BufferPool.PAGE_SIZE/tuple size) tuple slots, where tuple size is the size of tuples in this
   * database table, which can be determined via {@link Catalog#getTupleDesc}.
   *
   * <p>The number of 32-bit header words is equal to:
   *
   * <p>(no. tuple slots / 32) + 1
   *
   * <p>
   *
   * @see Database#getCatalog
   * @see Catalog#getTupleDesc
   * @see BufferPool#PAGE_SIZE
   */
  public HeapPage(HeapPageId id, byte[] data) throws IOException {
    this.pid = id;
    this.td = Database.getCatalog().getTupleDesc(id.tableid());
    // this.numSlots = (BufferPool.PAGE_SIZE) / (td.getSize());
    this.numSlots = (BufferPool.PAGE_SIZE * 8) / ((td.getSize() * 8) + 1);
    // System.out.println(this.numSlots);
    DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));

    // allocate and read the header slots of this page
    header = new Header(dis);

    try {
      // allocate and read the actual records of this page
      tuples = new Tuple[numSlots];
      for (int i = 0; i < numSlots; i++) {
        tuples[i] = readNextTuple(dis, i);
      }
    } catch (NoSuchElementException e) {
      // e.printStackTrace();
    }

    dis.close();
  }
 /**
  * Retrieve the number of tuples on this page.
  *
  * @return the number of tuples on this page
  */
 private int getNumTuples() {
   // some code goes here
   int tupsPerPage = (BufferPool.PAGE_SIZE * 8) / ((td.getSize() * 8) + 1); // default to be floor
   return tupsPerPage;
 }
Beispiel #8
0
 /**
  * Retrieve the number of tuples on this page.
  *
  * @return the number of tuples on this page
  */
 private int getNumTuples() {
   // hdj
   return BufferPool.PAGE_SIZE * 8 / (td.getSize() * 8 + 1);
 }