Reusable Java library of general tools with minimal external dependencies.
For questions or support, please contact us:
Email: support@aoindustries.com
Phone: 1-800-519-9541
Phone: +1-251-607-9556
Web: https://www.aoindustries.com/contact
public class DynamicPersistentBlockBuffer extends AbstractPersistentBlockBuffer
Treats a PersistentBuffer as a set of allocatable blocks.
Each block is stored in a 2^n area of the buffer, where the usable
space is 2^n-1 (the first byte of that area of the buffer indicates
the block size and allocated status).
Free space maps are generated upon instantiation. This means that startup costs can be fairly high. This class is designed for long-lifetime situations.
Blocks that are allocated take no space in memory, while blocks that are deallocated consume space. Adjacent blocks are automatically merged into a larger free block of twice the size. Blocks are also split into smaller blocks before allocating additional space.
Fragmentation may occur in the file over time, but is minimized by the use of per-block size free space maps along with block merging and splitting. There is currently no compaction tool.
Each entry has a one-byte header:
bits 0-5: maxBits (0-63) the power of two of the size of this block (max data size is (2^maxBits)-1).
bit 6: reserved, should be 0
bit 7: allocated flag
There is a selectable FreeSpacePolicy. The persistent data will be compatible between
different free space policies. It is safe to write the data with one policy and later open it
with a different policy.
This class is not thread-safe.
pbuffer| Constructor and Description |
|---|
DynamicPersistentBlockBuffer(PersistentBuffer pbuffer)
Creates a buffer.
|
| Modifier and Type | Method and Description |
|---|---|
long |
allocate(long minimumSize)
This will call
barrier as necessary during block splitting. |
void |
deallocate(long id)
Deallocates the block with the provided id.
|
protected void |
ensureCapacity(long capacity)
The capacity should always be enough because the capacity ensured here is
constrained to a single block, and blocks are always allocated fully.
|
protected long |
getBlockAddress(long id)
Gets the address of the block in the underlying persistent buffer.
|
long |
getBlockSize(long id)
Gets the maximum amount of data that may be stored in the entry.
|
Iterator<Long> |
iterateBlockIds()
Iterates over the allocated block IDs in no specific order, with one
exception: the first block allocated must be the first block iterated.
|
barrier, close, get, getInputStream, getInt, getLong, getOutputStream, getProtectionLevel, isClosed, isInBounds, put, putInt, putLongpublic DynamicPersistentBlockBuffer(PersistentBuffer pbuffer) throws IOException
IOExceptionpublic long allocate(long minimumSize)
throws IOException
barrier as necessary during block splitting.IOExceptionpublic void deallocate(long id)
throws IOException,
IllegalStateException
PersistentBlockBufferDeallocates 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.
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 barrierbarrier
after deallocate cause corruption beyond that just described.
IllegalStateException - if the block is not allocated.IOExceptionpublic Iterator<Long> iterateBlockIds() throws IOException
PersistentBlockBufferIterates 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 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.
IOExceptionpublic long getBlockSize(long id)
throws IOException
IOExceptionprotected long getBlockAddress(long id)
throws IOException
AbstractPersistentBlockBuffergetBlockAddress in class AbstractPersistentBlockBufferIOExceptionprotected void ensureCapacity(long capacity)
throws IOException
ensureCapacity in class AbstractPersistentBlockBufferIOExceptionCopyright © 2000–2016 AO Industries, Inc.. All rights reserved.