Example #1
0
  /**
   * Reader factory method. Build a Node object (of the right type) by reading a block in the file.
   *
   * @param config Configuration of the History Tree
   * @param fc FileChannel to the history file, ALREADY SEEKED at the start of the node.
   * @return The node object
   * @throws IOException If there was an error reading from the file channel
   */
  public static final HTNode readNode(HTConfig config, FileChannel fc) throws IOException {
    HTNode newNode = null;
    int res, i;

    ByteBuffer buffer = ByteBuffer.allocate(config.getBlockSize());
    buffer.order(ByteOrder.LITTLE_ENDIAN);
    buffer.clear();
    res = fc.read(buffer);
    assert (res == config.getBlockSize());
    buffer.flip();

    /* Read the common header part */
    byte typeByte = buffer.get();
    NodeType type = NodeType.fromByte(typeByte);
    long start = buffer.getLong();
    long end = buffer.getLong();
    int seqNb = buffer.getInt();
    int parentSeqNb = buffer.getInt();
    int intervalCount = buffer.getInt();
    int stringSectionOffset = buffer.getInt();
    buffer.get(); // TODO Used to be "isDone", to be removed from the header

    /* Now the rest of the header depends on the node type */
    switch (type) {
      case CORE:
        /* Core nodes */
        newNode = new CoreNode(config, seqNb, parentSeqNb, start);
        newNode.readSpecificHeader(buffer);
        break;

      case LEAF:
        /* Leaf nodes */
        newNode = new LeafNode(config, seqNb, parentSeqNb, start);
        newNode.readSpecificHeader(buffer);
        break;

      default:
        /* Unrecognized node type */
        throw new IOException();
    }

    /*
     * At this point, we should be done reading the header and 'buffer'
     * should only have the intervals left
     */
    for (i = 0; i < intervalCount; i++) {
      HTInterval interval = HTInterval.readFrom(buffer);
      newNode.fIntervals.add(interval);
      newNode.fSizeOfIntervalSection += interval.getIntervalSize();
    }

    /* Assign the node's other information we have read previously */
    newNode.fNodeEnd = end;
    newNode.fStringSectionOffset = stringSectionOffset;
    newNode.fIsOnDisk = true;

    return newNode;
  }