/** 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 (!isSlotUsed(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.getFieldType(j).parse(dis);
        t.setField(j, f);
      }
    } catch (java.text.ParseException e) {
      e.printStackTrace();
      throw new NoSuchElementException("parsing error!");
    }

    return t;
  }