Interface PersistentBlockBuffer

All Superinterfaces:
AutoCloseable, Closeable
All Known Implementing Classes:
AbstractPersistentBlockBuffer, DynamicPersistentBlockBuffer, FixedPersistentBlockBuffer

public interface PersistentBlockBuffer extends Closeable
A persistent set of blocks of arbitrary data. Each block may be any 64-bit size. All implementations should have a relatively efficient iteration in forward direction. Some implementations may also have efficient indexed access, and will implement the TODO: Link to RandomAccessPersistentBlockBuffer interface.
Author:
AO Industries, Inc.
  • Method Summary

    Modifier and Type
    Method
    Description
    long
    allocate(long minimumSize)
    Allocates a new block buffer that is at least as large as the requested space.
    void
    barrier(boolean force)
    Ensures that all writes before this barrier occur before all writes after this barrier.
    void
    Closes this buffer.
    void
    deallocate(long id)
    Deallocates the block with the provided id.
    void
    get(long id, long offset, byte[] buff, int off, int len)
    Gets bytes from this block.
    long
    getBlockSize(long id)
    Gets the block size for the provided id.
    getInputStream(long id, long offset, long length)
    Gets an input stream that reads from this buffer.
    int
    getInt(long id, long offset)
    Gets an integer from this block.
    long
    getLong(long id, long offset)
    Gets a long from this block.
    getOutputStream(long id, long offset, long length)
    Gets an output stream that writes to this buffer.
    Gets the protection level currently implemented by the buffer.
    boolean
    Checks if this buffer is closed.
    Iterates over the allocated block IDs in no specific order, with one exception: the first block allocated must be the first block iterated.
    void
    put(long id, long offset, byte[] buff, int off, int len)
    Puts bytes to this block.
    void
    putInt(long id, long offset, int value)
    Puts an integer to this block.
    void
    putLong(long id, long offset, long value)
    Puts a long to this block.
  • Method Details

    • isClosed

      boolean isClosed()
      Checks if this buffer is closed.
    • close

      void close() throws IOException
      Closes this buffer.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException
    • getProtectionLevel

      ProtectionLevel getProtectionLevel()
      Gets the protection level currently implemented by the buffer.
      See Also:
    • barrier

      void barrier(boolean force) throws IOException
      Ensures that all writes before this barrier occur before all writes after this barrier. If force is true, will also commit to physical media synchronously before returning. This request may be ignored or force downgraded to barrier-only depending on the current protection level.
      Throws:
      IOException
      See Also:
    • iterateBlockIds

      Iterator<Long> iterateBlockIds() throws IOException

      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.

      Throws:
      IOException
    • allocate

      long allocate(long minimumSize) throws IOException

      Allocates a new block buffer that is at least as large as the requested space. The id should always be >= 0, higher level data structures may use the negative values for other purposes, such as indicating null with -1.

      In order to ensure the block allocation is completely in persistent storage, barrier must be called. This allows the contents of the block to be written and combined into a single barrier(boolean) call. If the system fails before barrier(boolean) is called, the block may either be allocated or deallocated - it is up to higher-level data structures to determine which is the case. In no event, however, will failing to call barrier(boolean) after allocate(long) cause corruption beyond that just described.

      This call may fail after the id is allocated and before the id is returned. This will manifest itself as an extra allocated block after recovery.

      Throws:
      IOException
    • deallocate

      void deallocate(long id) throws IOException, IllegalStateException

      Deallocates the block with the provided id. The ids of other blocks will not be altered. The space may later be reallocated with the same, or possibly different id. The space may also be reclaimed.

      barrier does not need to be called after a deallocation, but if not called previously deallocated blocks may reappear after a system failure. It is up to higher-level data structures to detect this. In no event, however, will failing to call barrier(boolean) after deallocate(long) cause corruption beyond that just described.

      Throws:
      IllegalStateException - if the block is not allocated.
      IOException
    • getBlockSize

      long getBlockSize(long id) throws IOException
      Gets the block size for the provided id.
      Throws:
      IOException
    • get

      void get(long id, long offset, byte[] buff, int off, int len) throws IOException
      Gets bytes from this block. Bounds checking is performed only when assertions are enabled.
      Throws:
      IOException
    • getInt

      int getInt(long id, long offset) throws IOException
      Gets an integer from this block. Bounds checking is performed only when assertions are enabled.
      Throws:
      IOException
    • getLong

      long getLong(long id, long offset) throws IOException
      Gets a long from this block. Bounds checking is performed only when assertions are enabled.
      Throws:
      IOException
    • getInputStream

      InputStream getInputStream(long id, long offset, long length) throws IOException
      Gets an input stream that reads from this buffer. Bounds checking is performed only when assertions are enabled.
      Throws:
      IOException
    • put

      void put(long id, long offset, byte[] buff, int off, int len) throws IOException
      Puts bytes to this block. Bounds checking is performed only when assertions are enabled.
      Throws:
      BufferOverflowException - when out of range
      IOException
    • putInt

      void putInt(long id, long offset, int value) throws IOException
      Puts an integer to this block. Bounds checking is performed only when assertions are enabled.
      Throws:
      BufferOverflowException - when out of range
      IOException
    • putLong

      void putLong(long id, long offset, long value) throws IOException
      Puts a long to this block. Bounds checking is performed only when assertions are enabled.
      Throws:
      BufferOverflowException - when out of range
      IOException
    • getOutputStream

      OutputStream getOutputStream(long id, long offset, long length) throws IOException
      Gets an output stream that writes to this buffer. Bounds checking is performed only when assertions are enabled.
      Throws:
      BufferOverflowException - when out of range
      IOException