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;
  }
Example #2
0
  /**
   * Add an interval to this node
   *
   * @param newInterval Interval to add to this node
   */
  public void addInterval(HTInterval newInterval) {
    fRwl.writeLock().lock();
    try {
      /* Just in case, should be checked before even calling this function */
      assert (newInterval.getIntervalSize() <= getNodeFreeSpace());

      /* Find the insert position to keep the list sorted */
      int index = fIntervals.size();
      while (index > 0 && newInterval.compareTo(fIntervals.get(index - 1)) < 0) {
        index--;
      }

      fIntervals.add(index, newInterval);
      fSizeOfIntervalSection += newInterval.getIntervalSize();

      /* Update the in-node offset "pointer" */
      fStringSectionOffset -= (newInterval.getStringsEntrySize());
    } finally {
      fRwl.writeLock().unlock();
    }
  }