Class FixedPersistentBlockBuffer

All Implemented Interfaces:
PersistentBlockBuffer, Closeable, AutoCloseable

public class FixedPersistentBlockBuffer extends AbstractPersistentBlockBuffer

Treats a PersistentBuffer as a set of allocatable blocks. Each block is stored in a block of fixed size. The first block has an id of zero, and the blocks go up by ones. The storage address is determined from this logical id on the fly. The storage address and the block address are not the same.

One block of free space map preceeds a set of blocks. However, with exceptionally large block sizes, the free space map will be smaller. The free space map is the maximum size of the block size and 2^n, where n+(ceil(log(2)(blockSize)))=63. The result is that the minimum free space map size will be used to address the entire 2^63-1 address space.

The switchover point is at one gigabyte block size (2^30). The total of 2^63 address space may contain a maximum of 2^33 of these blocks. Each block consumes one bit of the space, the 2^30 bitmap block may contain a total of 2^33 bits, an exact match for the number of blocks.

A final example is for a 16 GB block size (2^34). The total of 2^63 address space may contain a maximum of 2^29 of these blocks. Each block consumes one bit of the space, thus the free space map only needs to contain 2^26 bytes to cover the entire address space.

AO Industries, Inc.
  • Constructor Details

    • FixedPersistentBlockBuffer

      public FixedPersistentBlockBuffer(PersistentBuffer pbuffer, long blockSize)
      Creates a persistent buffer with the provided block size. There may be performance advantages to block sizes that match or are multiples of the system page size. For smaller block sizes, there may also be reliability advantages to block sizes that are fractions of the system page size or the physical media block size. A good overall approach would be to select even powers of two (1, 2, 4, 8, ...).
  • Method Details

    • getBlockAddress

      protected long getBlockAddress(long id)
      Gets the address that stores the beginning of the block with the provided id. This is algorithmic and may be beyond the end of the buffer capacity.
      Specified by:
      getBlockAddress in class AbstractPersistentBlockBuffer
    • allocate

      public long allocate(long minimumSize) throws IOException
      Allocates a block. This does not directly cause any barriers.
    • deallocate

      public void deallocate(long id) throws IOException
      Deallocates the block for the provided id. This does not directly cause any barriers.
    • iterateBlockIds

      public Iterator<Long> iterateBlockIds()
      Description copied from interface: PersistentBlockBuffer

      Iterates over the allocated block IDs in no specific order, with one exception: the first block allocated must be the first block iterated. This block may contain critical higher-level data structure meta data. If all blocks are deallocated, then the first one added has this same requirement.

      The Iterator.remove() method may be used from the iterator in order to deallocate a block. The block allocation should not be modified during the iteration through any means other than the iterator itself. An attempt will be made to throw ConcurrentModificationException in this case, but this is only intended to catch bugs.

    • getBlockSize

      public long getBlockSize(long id)
      Description copied from interface: PersistentBlockBuffer
      Gets the block size for the provided id.
    • expandCapacity

      protected void expandCapacity(long oldCapacity, long newCapacity) throws IOException
    • ensureCapacity

      protected void ensureCapacity(long capacity) throws IOException
      This class takes a lazy approach on allocating buffer space. It will allocate additional space as needed here, rounding up to the next 4096-byte boundary.
      Specified by:
      ensureCapacity in class AbstractPersistentBlockBuffer