com.caucho.db.store
Class Store

java.lang.Object
  extended by com.caucho.db.store.Store
Direct Known Subclasses:
Table

public class Store
extends java.lang.Object

The store manages the block-based persistent store file. Each table will have its own store file, table.db. The store is block-based, where each block is 64k. Block allocation is tracked by a free block, block 0. Each block is represented as a two-byte value. The first byte is the allocation code: free, row, or used. The second byte is a fragment allocation mask. Since 64k stores 32k entries, the allocation block can handle a 2G database size. If the database is larger, another free block occurs at block 32k handling another 2G. The blocks are marked as free (00), row (01), used (10) or fragment(11). Row-blocks are table rows, so a table iterator will only look at the row blocks. Used blocks are for special blocks like the free list. Fragments are for blobs. Each store has a unique id in the database. The store id is merged with the block number in the store to create a unique block id. There are 64k allowed stores (and therefore 64k tables), leaving 64 - 16 = 48 bits for the blocks in a table, i.e. 2 ^ 48 blocks = 256T blocks. block index: the block number in the file. address: the address of a byte within the store, treating the file as a flat file. block id: the unique id of the block in the database.

Blobs and fragments

Fragments are stored in 8k chunks with a single byte prefix indicating its use.

Transactions

Fragments are not associated with transactions. The rollback is associated with a transaction.


Field Summary
protected  BlockManager _blockManager
           
protected  Database _database
           
static int ALLOC_FRAGMENT
           
static int ALLOC_FREE
           
static int ALLOC_INDEX
           
static int ALLOC_MASK
           
static int ALLOC_MINI_FRAG
           
static int ALLOC_ROW
           
static int ALLOC_USED
           
static int BLOCK_BITS
           
static long BLOCK_INDEX_MASK
           
static long BLOCK_MASK
           
static long BLOCK_OFFSET_MASK
           
static int BLOCK_SIZE
           
static long DATA_START
           
static int FRAGMENT_PER_BLOCK
           
static int FRAGMENT_SIZE
           
static int MINI_FRAG_ALLOC_OFFSET
           
static int MINI_FRAG_PER_BLOCK
           
static int MINI_FRAG_SIZE
           
static int STORE_CREATE_END
           
 
Constructor Summary
Store(Database database, java.lang.String name, Lock tableLock)
           
Store(Database database, java.lang.String name, Lock rowLock, Path path)
          Creates a new store.
 
Method Summary
 long addressToBlockId(long address)
          Converts from the block index to the unique block id.
 Block allocateBlock()
          Allocates a new block for a non-row.
 long allocateFragment(StoreTransaction xa)
          Allocates a new fragment.
 Block allocateIndexBlock()
          Allocates a new block for an index
 long allocateMiniFragment(StoreTransaction xa)
          Allocates a new miniFragment.
 Block allocateRow()
          Allocates a new block for a row.
protected  void assertStoreActive()
          Check that an allocated block is valid.
static long blockIdToAddress(long blockId)
          Converts from the block index to the unique block id.
static long blockIdToAddress(long blockId, int offset)
          Converts from the block index to the unique block id.
 void close()
          Closes the store.
static java.lang.String codeToName(int code)
          Debug names for the allocation.
 void create()
          Creates the store.
static Store create(Path path)
          Creates an independent store.
 void deleteFragment(StoreTransaction xa, long fragmentAddress)
          Deletes a fragment.
 void deleteMiniFragment(StoreTransaction xa, long fragmentAddress)
          Deletes a miniFragment.
 long firstBlock(long blockId, int type)
          Returns the first block id which contains a row.
 long firstFragment(long blockId)
          Returns the first block id which contains a fragment.
 long firstRow(long blockId)
          Returns the first block id which contains a row.
 void flush()
          Flush the store.
protected  void freeBlock(long blockId)
          Frees a block.
 byte[] getAllocationTable()
          Returns a copy of the allocation table.
 long getBlockCount()
          Returns the block count.
 BlockManager getBlockManager()
          Returns the block manager.
 long getFileSize()
          Returns the file size.
 int getId()
          Returns the store's id.
 Lock getLock()
          Returns the table's lock.
 java.lang.String getName()
          Returns the store's name.
 long getTotalFragmentSize()
          Returns the current number of fragments used.
 void init()
           
 boolean isClosed()
          True if destroyed.
 boolean isCorrupted()
           
 boolean isFlushDirtyBlocksOnCommit()
          If true, dirty blocks are written at commit time.
 boolean isIndexBlock(long blockAddress)
          Return true if the block is an index block.
 boolean isRowBlock(long blockAddress)
          Return true if the block is a row block.
 Block readBlock(long blockAddress)
          Returns the matching block.
 void readBlock(long blockId, byte[] buffer, int offset, int length)
          Reads a block into the buffer.
 int readBlock(long blockAddress, int blockOffset, byte[] buffer, int offset, int length)
          Reads a block.
 int readBlock(long blockAddress, int blockOffset, char[] buffer, int offset, int length)
          Reads a block for a clob.
 long readBlockLong(long blockAddress, int offset)
          Reads a long value from a block.
 int readFragment(long fragmentAddress, int fragmentOffset, byte[] buffer, int offset, int length)
          Reads a fragment.
 int readFragment(long fragmentAddress, int fragmentOffset, char[] buffer, int offset, int length)
          Reads a fragment for a clob.
 long readFragmentLong(long fragmentAddress, int fragmentOffset)
          Reads a long value from a fragment.
static long readLong(byte[] buffer, int offset)
          Reads the long.
 int readMiniFragment(long fragmentAddress, int fragmentOffset, byte[] buffer, int offset, int length)
          Reads a fragment.
 int readMiniFragment(long fragmentAddress, int fragmentOffset, char[] buffer, int offset, int length)
          Reads a miniFragment for a clob.
 long readMiniFragmentLong(long fragmentAddress, int fragmentOffset)
          Reads a long value from a miniFragment.
 void remove()
           
 void setCorrupted(boolean isCorrupted)
           
 void setFlushDirtyBlocksOnCommit(boolean flushOnCommit)
          If true, dirty blocks are written at commit time.
 java.lang.String toString()
           
protected  void validateBlockId(long blockId)
          Check that an allocated block is valid.
 void writeBlock(long blockAddress, byte[] buffer, int offset, int length)
          Saves the buffer to the database.
 void writeBlock(StoreTransaction xa, long blockAddress, int blockOffset, byte[] buffer, int offset, int length)
          Writes a blockfragment.
 void writeBlock(StoreTransaction xa, long blockAddress, int blockOffset, char[] buffer, int offset, int length)
          Writes a character based block
 void writeBlockLong(StoreTransaction xa, long blockAddress, int offset, long value)
          Writes a long value to a block
 void writeFragment(StoreTransaction xa, long fragmentAddress, int fragmentOffset, byte[] buffer, int offset, int length)
          Writes a fragment.
 void writeFragment(StoreTransaction xa, long fragmentAddress, int fragmentOffset, char[] buffer, int offset, int length)
          Writes a character based
 void writeFragmentLong(StoreTransaction xa, long fragmentAddress, int fragmentOffset, long value)
          Writes a long value to a fragment.
static void writeLong(byte[] buffer, int offset, long v)
          Writes the long.
 void writeMiniFragment(StoreTransaction xa, long fragmentAddress, int fragmentOffset, byte[] buffer, int offset, int length)
          Writes a miniFragment.
 void writeMiniFragment(StoreTransaction xa, long fragmentAddress, int fragmentOffset, char[] buffer, int offset, int length)
          Writes a character based
 void writeMiniFragmentLong(StoreTransaction xa, long fragmentAddress, int fragmentOffset, long value)
          Writes a long value to a miniFragment.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

BLOCK_BITS

public static final int BLOCK_BITS
See Also:
Constant Field Values

BLOCK_SIZE

public static final int BLOCK_SIZE
See Also:
Constant Field Values

BLOCK_INDEX_MASK

public static final long BLOCK_INDEX_MASK
See Also:
Constant Field Values

BLOCK_MASK

public static final long BLOCK_MASK
See Also:
Constant Field Values

BLOCK_OFFSET_MASK

public static final long BLOCK_OFFSET_MASK
See Also:
Constant Field Values

ALLOC_FREE

public static final int ALLOC_FREE
See Also:
Constant Field Values

ALLOC_ROW

public static final int ALLOC_ROW
See Also:
Constant Field Values

ALLOC_USED

public static final int ALLOC_USED
See Also:
Constant Field Values

ALLOC_FRAGMENT

public static final int ALLOC_FRAGMENT
See Also:
Constant Field Values

ALLOC_INDEX

public static final int ALLOC_INDEX
See Also:
Constant Field Values

ALLOC_MINI_FRAG

public static final int ALLOC_MINI_FRAG
See Also:
Constant Field Values

ALLOC_MASK

public static final int ALLOC_MASK
See Also:
Constant Field Values

FRAGMENT_SIZE

public static final int FRAGMENT_SIZE
See Also:
Constant Field Values

FRAGMENT_PER_BLOCK

public static final int FRAGMENT_PER_BLOCK
See Also:
Constant Field Values

MINI_FRAG_SIZE

public static final int MINI_FRAG_SIZE
See Also:
Constant Field Values

MINI_FRAG_PER_BLOCK

public static final int MINI_FRAG_PER_BLOCK
See Also:
Constant Field Values

MINI_FRAG_ALLOC_OFFSET

public static final int MINI_FRAG_ALLOC_OFFSET
See Also:
Constant Field Values

DATA_START

public static final long DATA_START
See Also:
Constant Field Values

STORE_CREATE_END

public static final int STORE_CREATE_END
See Also:
Constant Field Values

_database

protected final Database _database

_blockManager

protected final BlockManager _blockManager
Constructor Detail

Store

public Store(Database database,
             java.lang.String name,
             Lock tableLock)

Store

public Store(Database database,
             java.lang.String name,
             Lock rowLock,
             Path path)
Creates a new store.

Parameters:
database - the owning database.
name - the store name
lock - the table lock
path - the path to the files
Method Detail

create

public static Store create(Path path)
                    throws java.io.IOException,
                           java.sql.SQLException
Creates an independent store.

Throws:
java.io.IOException
java.sql.SQLException

setFlushDirtyBlocksOnCommit

public void setFlushDirtyBlocksOnCommit(boolean flushOnCommit)
If true, dirty blocks are written at commit time.


isFlushDirtyBlocksOnCommit

public boolean isFlushDirtyBlocksOnCommit()
If true, dirty blocks are written at commit time.


getName

public java.lang.String getName()
Returns the store's name.


getId

public int getId()
Returns the store's id.


getLock

public Lock getLock()
Returns the table's lock.


getBlockManager

public BlockManager getBlockManager()
Returns the block manager.


setCorrupted

public void setCorrupted(boolean isCorrupted)

isCorrupted

public boolean isCorrupted()

getFileSize

public long getFileSize()
Returns the file size.


getBlockCount

public long getBlockCount()
Returns the block count.


addressToBlockId

public final long addressToBlockId(long address)
Converts from the block index to the unique block id.


blockIdToAddress

public static long blockIdToAddress(long blockId)
Converts from the block index to the unique block id.


blockIdToAddress

public static long blockIdToAddress(long blockId,
                                    int offset)
Converts from the block index to the unique block id.


getTotalFragmentSize

public long getTotalFragmentSize()
Returns the current number of fragments used.


create

public void create()
            throws java.io.IOException,
                   java.sql.SQLException
Creates the store.

Throws:
java.io.IOException
java.sql.SQLException

init

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

remove

public void remove()
            throws java.sql.SQLException
Throws:
java.sql.SQLException

firstRow

public long firstRow(long blockId)
              throws java.io.IOException
Returns the first block id which contains a row.

Returns:
the block id of the first row block
Throws:
java.io.IOException

firstFragment

public long firstFragment(long blockId)
                   throws java.io.IOException
Returns the first block id which contains a fragment.

Returns:
the block id of the first row block
Throws:
java.io.IOException

firstBlock

public long firstBlock(long blockId,
                       int type)
                throws java.io.IOException
Returns the first block id which contains a row.

Returns:
the block id of the first row block
Throws:
java.io.IOException

readBlock

public final Block readBlock(long blockAddress)
                      throws java.io.IOException
Returns the matching block.

Throws:
java.io.IOException

allocateRow

public Block allocateRow()
                  throws java.io.IOException
Allocates a new block for a row.

Returns:
the block id of the allocated block.
Throws:
java.io.IOException

isRowBlock

public boolean isRowBlock(long blockAddress)
Return true if the block is a row block.


allocateBlock

public Block allocateBlock()
                    throws java.io.IOException
Allocates a new block for a non-row.

Returns:
the block id of the allocated block.
Throws:
java.io.IOException

allocateIndexBlock

public Block allocateIndexBlock()
                         throws java.io.IOException
Allocates a new block for an index

Returns:
the block id of the allocated block.
Throws:
java.io.IOException

isIndexBlock

public boolean isIndexBlock(long blockAddress)
Return true if the block is an index block.


validateBlockId

protected void validateBlockId(long blockId)
                        throws java.lang.IllegalArgumentException,
                               java.lang.IllegalStateException
Check that an allocated block is valid.

Throws:
java.lang.IllegalArgumentException
java.lang.IllegalStateException

assertStoreActive

protected void assertStoreActive()
                          throws java.lang.IllegalStateException
Check that an allocated block is valid.

Throws:
java.lang.IllegalStateException

freeBlock

protected void freeBlock(long blockId)
                  throws java.io.IOException
Frees a block.

Throws:
java.io.IOException

readFragment

public int readFragment(long fragmentAddress,
                        int fragmentOffset,
                        byte[] buffer,
                        int offset,
                        int length)
                 throws java.io.IOException
Reads a fragment.

Parameters:
fragmentAddress - the address of the fragment
fragmentOffset - the offset inside the fragment to start reading
buffer - the result buffer
offset - offset into the result buffer
length - the number of bytes to read
Returns:
the number of bytes read
Throws:
java.io.IOException

readFragment

public int readFragment(long fragmentAddress,
                        int fragmentOffset,
                        char[] buffer,
                        int offset,
                        int length)
                 throws java.io.IOException
Reads a fragment for a clob.

Parameters:
fragmentAddress - the address of the fragment
fragmentOffset - the offset inside the fragment to start reading
buffer - the result buffer
offset - offset into the result buffer
length - the length of the fragment in characters
Returns:
the number of characters read
Throws:
java.io.IOException

readFragmentLong

public long readFragmentLong(long fragmentAddress,
                             int fragmentOffset)
                      throws java.io.IOException
Reads a long value from a fragment.

Returns:
the long value
Throws:
java.io.IOException

readBlock

public int readBlock(long blockAddress,
                     int blockOffset,
                     byte[] buffer,
                     int offset,
                     int length)
              throws java.io.IOException
Reads a block.

Parameters:
blockAddress - the address of the block
blockOffset - the offset inside the block to start reading
buffer - the result buffer
offset - offset into the result buffer
length - the number of bytes to read
Returns:
the number of bytes read
Throws:
java.io.IOException

readBlock

public int readBlock(long blockAddress,
                     int blockOffset,
                     char[] buffer,
                     int offset,
                     int length)
              throws java.io.IOException
Reads a block for a clob.

Parameters:
blockAddress - the address of the block
blockOffset - the offset inside the block to start reading
buffer - the result buffer
offset - offset into the result buffer
length - the length of the block in characters
Returns:
the number of characters read
Throws:
java.io.IOException

readBlockLong

public long readBlockLong(long blockAddress,
                          int offset)
                   throws java.io.IOException
Reads a long value from a block.

Returns:
the long value
Throws:
java.io.IOException

allocateFragment

public long allocateFragment(StoreTransaction xa)
                      throws java.io.IOException
Allocates a new fragment.

Returns:
the fragment address
Throws:
java.io.IOException

deleteFragment

public void deleteFragment(StoreTransaction xa,
                           long fragmentAddress)
                    throws java.io.IOException
Deletes a fragment.

Throws:
java.io.IOException

writeFragment

public void writeFragment(StoreTransaction xa,
                          long fragmentAddress,
                          int fragmentOffset,
                          byte[] buffer,
                          int offset,
                          int length)
                   throws java.io.IOException
Writes a fragment.

Parameters:
xa - the owning transaction
fragmentAddress - the fragment to write
fragmentOffset - the offset into the fragment
buffer - the write buffer
offset - offset into the write buffer
length - the number of bytes to write
Throws:
java.io.IOException

writeFragment

public void writeFragment(StoreTransaction xa,
                          long fragmentAddress,
                          int fragmentOffset,
                          char[] buffer,
                          int offset,
                          int length)
                   throws java.io.IOException
Writes a character based

Parameters:
fragmentAddress - the fragment to write
fragmentOffset - the offset into the fragment
buffer - the write buffer
offset - offset into the write buffer
length - the number of bytes to write
Throws:
java.io.IOException

writeFragmentLong

public void writeFragmentLong(StoreTransaction xa,
                              long fragmentAddress,
                              int fragmentOffset,
                              long value)
                       throws java.io.IOException
Writes a long value to a fragment.

Throws:
java.io.IOException

writeBlock

public void writeBlock(StoreTransaction xa,
                       long blockAddress,
                       int blockOffset,
                       byte[] buffer,
                       int offset,
                       int length)
                throws java.io.IOException
Writes a blockfragment.

Parameters:
xa - the owning transaction
blockAddress - the block to write
blockOffset - the offset into the block
buffer - the write buffer
offset - offset into the write buffer
length - the number of bytes to write
Throws:
java.io.IOException

writeBlock

public void writeBlock(StoreTransaction xa,
                       long blockAddress,
                       int blockOffset,
                       char[] buffer,
                       int offset,
                       int length)
                throws java.io.IOException
Writes a character based block

Parameters:
blockAddress - the fragment to write
blockOffset - the offset into the fragment
buffer - the write buffer
offset - offset into the write buffer
length - the number of bytes to write
Throws:
java.io.IOException

writeBlockLong

public void writeBlockLong(StoreTransaction xa,
                           long blockAddress,
                           int offset,
                           long value)
                    throws java.io.IOException
Writes a long value to a block

Throws:
java.io.IOException

readMiniFragment

public int readMiniFragment(long fragmentAddress,
                            int fragmentOffset,
                            byte[] buffer,
                            int offset,
                            int length)
                     throws java.io.IOException
Reads a fragment.

Parameters:
fragmentAddress - the address of the fragment
fragmentOffset - the offset inside the fragment to start reading
buffer - the result buffer
offset - offset into the result buffer
length - the number of bytes to read
Returns:
the number of bytes read
Throws:
java.io.IOException

readMiniFragment

public int readMiniFragment(long fragmentAddress,
                            int fragmentOffset,
                            char[] buffer,
                            int offset,
                            int length)
                     throws java.io.IOException
Reads a miniFragment for a clob.

Parameters:
fragmentAddress - the address of the fragment
fragmentOffset - the offset inside the fragment to start reading
buffer - the result buffer
offset - offset into the result buffer
length - the length of the fragment in characters
Returns:
the number of characters read
Throws:
java.io.IOException

readMiniFragmentLong

public long readMiniFragmentLong(long fragmentAddress,
                                 int fragmentOffset)
                          throws java.io.IOException
Reads a long value from a miniFragment.

Returns:
the long value
Throws:
java.io.IOException

allocateMiniFragment

public long allocateMiniFragment(StoreTransaction xa)
                          throws java.io.IOException
Allocates a new miniFragment.

Returns:
the fragment address
Throws:
java.io.IOException

deleteMiniFragment

public void deleteMiniFragment(StoreTransaction xa,
                               long fragmentAddress)
                        throws java.io.IOException
Deletes a miniFragment.

Throws:
java.io.IOException

writeMiniFragment

public void writeMiniFragment(StoreTransaction xa,
                              long fragmentAddress,
                              int fragmentOffset,
                              byte[] buffer,
                              int offset,
                              int length)
                       throws java.io.IOException
Writes a miniFragment.

Parameters:
xa - the owning transaction
fragmentAddress - the fragment to write
fragmentOffset - the offset into the fragment
buffer - the write buffer
offset - offset into the write buffer
length - the number of bytes to write
Throws:
java.io.IOException

writeMiniFragment

public void writeMiniFragment(StoreTransaction xa,
                              long fragmentAddress,
                              int fragmentOffset,
                              char[] buffer,
                              int offset,
                              int length)
                       throws java.io.IOException
Writes a character based

Parameters:
miniFragmentAddress - the fragment to write
fragmentOffset - the offset into the fragment
buffer - the write buffer
offset - offset into the write buffer
length - the number of bytes to write
Throws:
java.io.IOException

writeMiniFragmentLong

public void writeMiniFragmentLong(StoreTransaction xa,
                                  long fragmentAddress,
                                  int fragmentOffset,
                                  long value)
                           throws java.io.IOException
Writes a long value to a miniFragment.

Throws:
java.io.IOException

readBlock

public void readBlock(long blockId,
                      byte[] buffer,
                      int offset,
                      int length)
               throws java.io.IOException
Reads a block into the buffer.

Throws:
java.io.IOException

writeBlock

public void writeBlock(long blockAddress,
                       byte[] buffer,
                       int offset,
                       int length)
                throws java.io.IOException
Saves the buffer to the database.

Throws:
java.io.IOException

flush

public void flush()
Flush the store.


isClosed

public boolean isClosed()
True if destroyed.


close

public void close()
Closes the store.


getAllocationTable

public byte[] getAllocationTable()
Returns a copy of the allocation table.


readLong

public static long readLong(byte[] buffer,
                            int offset)
Reads the long.


writeLong

public static void writeLong(byte[] buffer,
                             int offset,
                             long v)
Writes the long.


codeToName

public static java.lang.String codeToName(int code)
Debug names for the allocation.


toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object