org.processmining.framework.log.rfb.io
Class BlockDataStorage

java.lang.Object
  extended by org.processmining.framework.log.rfb.io.BlockDataStorage

public class BlockDataStorage
extends java.lang.Object

This class implements a storage container providing dynamically sized blocks of bytes. Initially, each block data storage contains one single block, which extends on the whole backing operating system file. With the allocation of further blocks, the current blocks are partitioned symmetrically, in a recursive manner. This means, on each partitioning level, each currently contained block is cut in half, yielding a new block each, extending over the prior block's second half. In this way, each partitioning doubles the number of blocks in the block data storage while cutting each block's size in half. We assume that files are allocated or written consecutively, i.e. one after another. If we further assume that files are written in large numbers of the same size of file, this block data storage scales perfectly, adjusting its partitioning dynamically to the size of required byte chunks. The block data storage can be tuned in its behavior with two parameters. One of it being the size of the block data storage, i.e. the number of bytes which is provided in a whole. The other parameter is the partitioning limit. If this limit, as a percentage of each block's inhibited space from the space it can maximally hold, is increased for at least one block in the storage, the storage can no longer be partitioned. This concept is geared towards the idea of a virtual file system, where file metaphors represent abstract sequential byte storages, which can extend over multiple storage blocks as provided by this class.

Author:
Christian W. Guenther (christian at deckfour dot org)

Field Summary
protected  java.util.ArrayList<StorageBlock> blocks
          List of the currently provided storage blocks within this storage.
protected  int blockSize
          Current size of blocks provided by this storage
protected  java.nio.MappedByteBuffer buffer
          This buffer will hold the memory-mapped backing file
protected  java.io.File file
          The operating system level file backing the storage
protected  java.util.ArrayList<StorageBlock> freeBlocks
          List or provided storage blocks in this storage, which can still be allocated, i.e.
protected  int partitionLevel
          The partition level in which this storage currently is in.
protected  double partitionThreshold
          If at least one block in the provided set exceeds a usage percentage given in this threshold, no further partitioning must occur.
protected  int pointer
          Current offset in the storage file, from which will be read or written the next time
protected  int size
          Size of the storage file, in bytes.
 
Constructor Summary
BlockDataStorage(java.io.File aFile, int fileSize)
          Create a new block data storage, based on the given file with the given size.
 
Method Summary
 StorageBlock allocateBlock()
          Allocate a new block of bytes from this block data storage.
 void close()
           
 boolean defragment()
          Attempts to defragment the block data storage, i.e.
 void freeBlock(int index)
          This method registers the given indexed block as free with the storage.
 int getBlockOffset(int blockIndex)
          Returns the offset in bytes of the indexed block, measured from the beginning of the block-partitioned file.
 int getBlockSize()
          Returns the current block size of the partitioned file.
 java.io.File getFile()
          Returns the file which is backing this block data storage.
 BlockDataStorageInfo getInfo()
          Returns information about the current usage of this block data storage's blocks
 int length()
           
protected  boolean partition()
          This method performs a partitioning of the current set of blocks.
protected static int powerOfTwoFloor(int n)
          Returns the largest integer that is a power of two and smaller than the given integer parameter, i.e.
 boolean readBoolean(int blockNumber, int offset)
           
 byte readByte(int blockNumber, int offset)
           
 char readChar(int blockNumber, int offset)
           
 double readDouble(int blockNumber, int offset)
           
 float readFloat(int blockNumber, int offset)
           
 void readFully(int blockNumber, int offset, byte[] b)
           
 void readFully(int blockNumber, int offset, byte[] b, int off, int len)
           
 int readInt(int blockNumber, int offset)
           
 long readLong(int blockNumber, int offset)
           
 short readShort(int blockNumber, int offset)
           
 int readUnsignedByte(int blockNumber, int offset)
           
 int readUnsignedShort(int blockNumber, int offset)
           
protected  int translateOffsetChecking(int blockIndex, int blockOffset, int bytes)
          Internal method to translate block-private file pointer addresses, given as block index and block-private offset, into global, file-wide offsets.
 void write(int blockNumber, int offset, byte[] b)
           
 void write(int blockNumber, int offset, byte[] b, int off, int len)
           
 void write(int blockNumber, int offset, int b)
           
 void writeBoolean(int blockNumber, int offset, boolean v)
           
 void writeByte(int blockNumber, int offset, int v)
           
 void writeBytes(int blockNumber, int offset, java.lang.String s)
           
 void writeChar(int blockNumber, int offset, int v)
           
 void writeChars(int blockNumber, int offset, java.lang.String s)
           
 void writeDouble(int blockNumber, int offset, double v)
           
 void writeFloat(int blockNumber, int offset, float v)
           
 void writeInt(int blockNumber, int offset, int v)
           
 void writeLong(int blockNumber, int offset, long v)
           
 void writeShort(int blockNumber, int offset, int v)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

file

protected java.io.File file
The operating system level file backing the storage


buffer

protected java.nio.MappedByteBuffer buffer
This buffer will hold the memory-mapped backing file


size

protected int size
Size of the storage file, in bytes.


pointer

protected int pointer
Current offset in the storage file, from which will be read or written the next time


blockSize

protected int blockSize
Current size of blocks provided by this storage


partitionLevel

protected int partitionLevel
The partition level in which this storage currently is in. The number of blocks is two to the power of the current partitioning level.


partitionThreshold

protected double partitionThreshold
If at least one block in the provided set exceeds a usage percentage given in this threshold, no further partitioning must occur. As value within [0.0, 0.5].


blocks

protected java.util.ArrayList<StorageBlock> blocks
List of the currently provided storage blocks within this storage.


freeBlocks

protected java.util.ArrayList<StorageBlock> freeBlocks
List or provided storage blocks in this storage, which can still be allocated, i.e. are free.

Constructor Detail

BlockDataStorage

public BlockDataStorage(java.io.File aFile,
                        int fileSize)
                 throws java.io.IOException
Create a new block data storage, based on the given file with the given size.

Parameters:
aFile - File which is to back this block storage.
fileSize - Size of the block data storage in bytes.
Throws:
java.io.IOException
Method Detail

powerOfTwoFloor

protected static int powerOfTwoFloor(int n)
Returns the largest integer that is a power of two and smaller than the given integer parameter, i.e. the power-of-two-floor of n.

Parameters:
n -
Returns:

allocateBlock

public StorageBlock allocateBlock()
Allocate a new block of bytes from this block data storage. If no block is found in the list of free blocks, partitioning the current set of blocks to create free blocks is attempted. If this is successful, one of the newly created blocks is returned. If not, this method will return null.

Returns:

freeBlock

public void freeBlock(int index)
This method registers the given indexed block as free with the storage. It must be ensured by the calling party, that the respectiv block is indeed no longer in use and is safe to be reassigned. The free block will be added to the list of free blocks.

Parameters:
index - Index of the block to be freed from allocation.

getFile

public java.io.File getFile()
Returns the file which is backing this block data storage.

Returns:
File handle to the backing file.

partition

protected boolean partition()
This method performs a partitioning of the current set of blocks. If the set partitioning threshold is exceeded by at least one block in the set, partitioning is aborted and false is returned. If partitioning is successful, true is returned, implying adjustment of all prior contained blocks and creation of all respective new blocks.

Returns:
A success indicator flag.

defragment

public boolean defragment()
Attempts to defragment the block data storage, i.e. to recombine previously partitioned block, so that the storage becomes less scattered.
Notice: This initial implementation will only attempt to restore the initial state of a partitioned storage that is completely empty. Later implementation should improve this situation!

Returns:
Whether defragmentation was successful

getBlockOffset

public int getBlockOffset(int blockIndex)
Returns the offset in bytes of the indexed block, measured from the beginning of the block-partitioned file.

Parameters:
blockIndex - Index of the block, whose offset is requested.
Returns:
The offset of the indexed block from the beginning of the file, in bytes.

translateOffsetChecking

protected int translateOffsetChecking(int blockIndex,
                                      int blockOffset,
                                      int bytes)
                               throws java.io.IOException
Internal method to translate block-private file pointer addresses, given as block index and block-private offset, into global, file-wide offsets. The provided number of bytes allows the method to check, whether the calling method will transcend the given block's boundaries. In this case, an IOException will be thrown. Otherwise the method returns the requested global offset as long.

Parameters:
blockIndex - Index of the requesting block.
blockOffset - Offset within the requesting block.
bytes - Number of bytes to be read or written from the requested offset.
Returns:
The global offset in bytes, translated from the given parameters.
Throws:
java.io.IOException

getBlockSize

public int getBlockSize()
Returns the current block size of the partitioned file.

Returns:
Current block size in bytes.

getInfo

public BlockDataStorageInfo getInfo()
Returns information about the current usage of this block data storage's blocks

Returns:
an aggregated information container

close

public void close()
           throws java.io.IOException
Throws:
java.io.IOException

length

public int length()
           throws java.io.IOException
Throws:
java.io.IOException

write

public void write(int blockNumber,
                  int offset,
                  int b)
           throws java.io.IOException
Throws:
java.io.IOException

write

public void write(int blockNumber,
                  int offset,
                  byte[] b)
           throws java.io.IOException
Throws:
java.io.IOException

write

public void write(int blockNumber,
                  int offset,
                  byte[] b,
                  int off,
                  int len)
           throws java.io.IOException
Throws:
java.io.IOException

writeBoolean

public void writeBoolean(int blockNumber,
                         int offset,
                         boolean v)
                  throws java.io.IOException
Throws:
java.io.IOException

writeByte

public void writeByte(int blockNumber,
                      int offset,
                      int v)
               throws java.io.IOException
Throws:
java.io.IOException

writeBytes

public void writeBytes(int blockNumber,
                       int offset,
                       java.lang.String s)
                throws java.io.IOException
Throws:
java.io.IOException

writeChar

public void writeChar(int blockNumber,
                      int offset,
                      int v)
               throws java.io.IOException
Throws:
java.io.IOException

writeChars

public void writeChars(int blockNumber,
                       int offset,
                       java.lang.String s)
                throws java.io.IOException
Throws:
java.io.IOException

writeDouble

public void writeDouble(int blockNumber,
                        int offset,
                        double v)
                 throws java.io.IOException
Throws:
java.io.IOException

writeFloat

public void writeFloat(int blockNumber,
                       int offset,
                       float v)
                throws java.io.IOException
Throws:
java.io.IOException

writeInt

public void writeInt(int blockNumber,
                     int offset,
                     int v)
              throws java.io.IOException
Throws:
java.io.IOException

writeLong

public void writeLong(int blockNumber,
                      int offset,
                      long v)
               throws java.io.IOException
Throws:
java.io.IOException

writeShort

public void writeShort(int blockNumber,
                       int offset,
                       int v)
                throws java.io.IOException
Throws:
java.io.IOException

readBoolean

public boolean readBoolean(int blockNumber,
                           int offset)
                    throws java.io.IOException
Throws:
java.io.IOException

readByte

public byte readByte(int blockNumber,
                     int offset)
              throws java.io.IOException
Throws:
java.io.IOException

readChar

public char readChar(int blockNumber,
                     int offset)
              throws java.io.IOException
Throws:
java.io.IOException

readDouble

public double readDouble(int blockNumber,
                         int offset)
                  throws java.io.IOException
Throws:
java.io.IOException

readFloat

public float readFloat(int blockNumber,
                       int offset)
                throws java.io.IOException
Throws:
java.io.IOException

readFully

public void readFully(int blockNumber,
                      int offset,
                      byte[] b)
               throws java.io.IOException
Throws:
java.io.IOException

readFully

public void readFully(int blockNumber,
                      int offset,
                      byte[] b,
                      int off,
                      int len)
               throws java.io.IOException
Throws:
java.io.IOException

readInt

public int readInt(int blockNumber,
                   int offset)
            throws java.io.IOException
Throws:
java.io.IOException

readLong

public long readLong(int blockNumber,
                     int offset)
              throws java.io.IOException
Throws:
java.io.IOException

readShort

public short readShort(int blockNumber,
                       int offset)
                throws java.io.IOException
Throws:
java.io.IOException

readUnsignedByte

public int readUnsignedByte(int blockNumber,
                            int offset)
                     throws java.io.IOException
Throws:
java.io.IOException

readUnsignedShort

public int readUnsignedShort(int blockNumber,
                             int offset)
                      throws java.io.IOException
Throws:
java.io.IOException