ch.javasoft.jbase
Class VariableWidthTable<E>

java.lang.Object
  extended by ch.javasoft.jbase.VariableWidthTable<E>
All Implemented Interfaces:
Stateful, Table<E>

public class VariableWidthTable<E>
extends Object
implements Table<E>, Stateful

The VariableWidthTablePaired stores entities of unknown, variable size. A pair of tables is used to store the rows. If necessary, a pointer in the first table points to the entry in another table of sufficient row width.

Multiple files are used to store the data, each file controlled by a FixedWidthTable. The primary table contains raw data plus two additional indices pointing to an entry of the secondary table (one index for the table, one for the row in the table). Multiple secondary tables of different sizes exist, each storing raw data plus an index back to the row of the primary table (needed for deletions). The widths of the secondary tables are powers of two. The smallest possible secondary table is used and created if not yet existing.

Note that variable width tables are not thread safe. However, a thread safe table for concurrent use is possible by using this table together with ConcurrentTable.


Constructor Summary
protected VariableWidthTable(File folder, String fileName, EntityMarshaller<E> entityMarshaller, int cacheTableSize, int cacheEntrySize)
          Constructor, only for subclassing, use the static create and open methods to create instances.
 
Method Summary
 int add(E entity)
          Adds a new entity to the table.
 void close(boolean erase)
          Closes this table.
static
<En> VariableWidthTable<En>
create(File folder, String fileName, int firstTableByteWidth, EntityMarshaller<En> entityMarshaller, int cacheTableSize, int cacheEntrySize)
          Creates new variable table files, erasing existing files if existent.
 VariableWidthTable<E> createReadCopy(ReadWriteLock lock)
          Returns a read copy of this stateful object.
protected  void finalize()
          Calls close(boolean) with false argument, i.e.
 void flush()
          Flush ensures that all write operations are persisted.
 E get(int index)
          Returns the entity at the given position.
protected static String getFileNamePostfix(String fileName)
           
protected static String getFileNamePrefix(String fileName)
           
protected static int getTableByteWidth(int tableIndex, int rawByteWidth)
           
protected  File getTableFile(int tableIndex, int byteWidth)
           
protected static int getTableIndexCount(int tableIndex)
           
protected static int getTotalByteWidth(int tableIndex, int byteWidth)
           
static
<En> VariableWidthTable<En>
open(File folder, String fileName, EntityMarshaller<En> entityMarshaller, int cacheTableSize, int cacheEntrySize)
          Opens existing variable table files.
protected  FixedWidthTable<ch.javasoft.jbase.FixedTableRow> openTableFile(int tableIndex, int byteWidth, boolean createIfNeeded)
           
 void remove(int index)
          Removes the entity at the given position from the table.
 void removeAll()
          Closes this table.
 void set(int index, E entity)
          Replaces the entity at the given position by the specified entity.
 int size()
          Returns the size of the table, i.e.
 void swap(int indexA, int indexB)
          Swaps the two entities specified by their index.
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

VariableWidthTable

protected VariableWidthTable(File folder,
                             String fileName,
                             EntityMarshaller<E> entityMarshaller,
                             int cacheTableSize,
                             int cacheEntrySize)
Constructor, only for subclassing, use the static create and open methods to create instances.

Parameters:
folder - The folder containing the table files
fileName - The file name of the tables. Indexing is inserted in front of the file ending if needed.
entityMarshaller - The marshaller transforming entities (rows) into bytes
cacheTableSize - Table size for BufferedRandomAccessPersister, or 0 if no cache should be used
cacheEntrySize - Table entry size for BufferedRandomAccessPersister, or 0 if no cache should be used
Method Detail

open

public static <En> VariableWidthTable<En> open(File folder,
                                               String fileName,
                                               EntityMarshaller<En> entityMarshaller,
                                               int cacheTableSize,
                                               int cacheEntrySize)
                                   throws IOException
Opens existing variable table files.

Parameters:
folder - The folder containing the table files
fileName - The file name of the tables. Indexing is inserted in front of the file ending if needed.
entityMarshaller - The marshaller transforming entities (rows) into bytes
cacheTableSize - Table size for BufferedRandomAccessPersister, or 0 if no cache should be used
cacheEntrySize - Table entry size for BufferedRandomAccessPersister, or 0 if no cache should be used
Throws:
IOException

create

public static <En> VariableWidthTable<En> create(File folder,
                                                 String fileName,
                                                 int firstTableByteWidth,
                                                 EntityMarshaller<En> entityMarshaller,
                                                 int cacheTableSize,
                                                 int cacheEntrySize)
                                     throws IOException
Creates new variable table files, erasing existing files if existent.

The width of the primary table controls the frequency of single/double table accesses versus gaps in the primary table. If the primary table is wide, the majority of accesses only concern the primary table, but many rows might only use a small portion of the fixed row width. If the primary table is small, less disk space is needed, but secondary table accesses are more likely.

Parameters:
folder - The folder containing the table files
fileName - The file name of the tables. Indexing is inserted in front of the file ending if needed.
firstTableByteWidth - The byte width of the primary table, without index widths for indices to secondary tables
entityMarshaller - The marshaller transforming entities (rows) into bytes
cacheTableSize - Table size for BufferedRandomAccessPersister, or 0 if no cache should be used
cacheEntrySize - Table entry size for BufferedRandomAccessPersister, or 0 if no cache should be used
Throws:
IOException

openTableFile

protected FixedWidthTable<ch.javasoft.jbase.FixedTableRow> openTableFile(int tableIndex,
                                                                         int byteWidth,
                                                                         boolean createIfNeeded)
                                                                  throws IOException
Throws:
IOException

getFileNamePrefix

protected static String getFileNamePrefix(String fileName)

getFileNamePostfix

protected static String getFileNamePostfix(String fileName)

getTableFile

protected File getTableFile(int tableIndex,
                            int byteWidth)

getTotalByteWidth

protected static int getTotalByteWidth(int tableIndex,
                                       int byteWidth)

getTableIndexCount

protected static int getTableIndexCount(int tableIndex)

getTableByteWidth

protected static int getTableByteWidth(int tableIndex,
                                       int rawByteWidth)
                                throws IOException
Throws:
IOException

add

public int add(E entity)
        throws IOException
Description copied from interface: Table
Adds a new entity to the table. The index of the added entity is at end of table, i.e. size-1 after adding the new entity.

Specified by:
add in interface Table<E>
Returns:
the position of the added entity, i.e. size-1
Throws:
IOException

close

public void close(boolean erase)
           throws IOException
Description copied from interface: Table
Closes this table. Pending write operations are flushed, and underlying files are closed. Subsequent access to the table is not allowed and causes exceptions. Multiple calls to this close method do not cause any exceptions.

Specified by:
close in interface Table<E>
Throws:
IOException

flush

public void flush()
           throws IOException
Description copied from interface: Table
Flush ensures that all write operations are persisted. Writing to files ore databases might involve caches (operating system caches or application caches). Calling this method enforces that all cached data is written to the underlying layer(s).

Specified by:
flush in interface Table<E>
Throws:
IOException

finalize

protected void finalize()
                 throws Throwable
Calls close(boolean) with false argument, i.e. without erasing

Overrides:
finalize in class Object
Throws:
Throwable

createReadCopy

public VariableWidthTable<E> createReadCopy(ReadWriteLock lock)
                                     throws IOException
Description copied from interface: Stateful
Returns a read copy of this stateful object. The returned read copy contains its own state compared to another read copy instance, i.e. read copies can be used by different threads without causing conflicts considering the state of the stateful object.

The submitted read/write lock can be used later on e.g. for lazy opening of additional files. When this method is invoked, the write lock of the submitted read/write lock is held.

Specified by:
createReadCopy in interface Stateful
Parameters:
lock - A read/write lock, the write lock is held. The lock, however, might also be used for other functionality of the returned read copy, for instance, if the read copy has to be put in sync with the main object.
Returns:
a new read copy instance, with copied state compared to other read copy instances
Throws:
IOException

get

public E get(int index)
      throws IOException
Description copied from interface: Table
Returns the entity at the given position. Note that (row) indices might change if entities are added or removed.

Specified by:
get in interface Table<E>
Throws:
IOException

remove

public void remove(int index)
            throws IOException
Description copied from interface: Table
Removes the entity at the given position from the table. If this was the last entity, it is just removed. If it is another (not the last) row, the entity at the last row is moved to the specified position of the entity to remove.

Specified by:
remove in interface Table<E>
Throws:
IOException

removeAll

public void removeAll()
               throws IOException
Description copied from interface: Table
Closes this table. Pending write operations are flushed, and underlying files are closed. Subsequent access to the table is not allowed and causes exceptions. Multiple calls to this close method do not cause any exceptions.

Specified by:
removeAll in interface Table<E>
Throws:
IOException

set

public void set(int index,
                E entity)
         throws IOException
Description copied from interface: Table
Replaces the entity at the given position by the specified entity.

Specified by:
set in interface Table<E>
Throws:
IOException

swap

public void swap(int indexA,
                 int indexB)
          throws IOException
Description copied from interface: Table
Swaps the two entities specified by their index.

Specified by:
swap in interface Table<E>
Throws:
IOException

size

public int size()
         throws IOException
Description copied from interface: Table
Returns the size of the table, i.e. the number of rows or entities.

Specified by:
size in interface Table<E>
Throws:
IOException