Sometimes STIL needs to store the data from a table for later use.
This is necessary for instance when it creates a StarTable
object by reading a VOTable document: it parses the XML by reading
through from start to finish, but must be able to supply the
cell data through the StarTable
's data access methods
without doing another parse later.
Another example is when converting a sequential-only access table to
a random-access one (see the example below, and Section 2.3.4) -
the data must be stored somewhere they can be accessed in a
non-sequential way at a later date.
The obvious thing to do is to store such data in object arrays
or lists in memory. However, if the tables get very large this is no longer
appropriate because memory will fill up, and the application
will fail with an OutOfMemoryError
(Java's garbage collection based memory management means it
is not much good at using virtual memory).
So sometimes it would be better to store the data in a temporary disk file.
There may be other decisions to make as well, for instance the location
or format (perhaps row- or column-oriented) to use for
a temporary disk file.
Since on the whole you don't want to worry about these choices
when writing an application, STIL provides a way of dealing with them
which is highly configurable, but behaves in a 'sensible' way if
you don't take any special steps. This is based around the
StoragePolicy
class.
A StoragePolicy
is a factory for
RowStore
objects,
and a RowStore
is an object to which you can write
the metadata and data of a table once, and perform random access
reads on it at a later date.
Any of the STIL classes which need to do this sort of table data caching
use a StoragePolicy
object; they have policy get/set methods
and usually constructors which take a StoragePolicy
too.
Application code which needs to stash table data away should follow
the same procedure.
By way of example: the
randomTable
method takes a (possibly non-random-access) table and returns a random-access
one containing the same data. Here is roughly how it does it:
static StarTable randomTable( StarTable seqTable, StoragePolicy policy ) throws IOException { // Get a new row store object from the policy. RowStore rowStore = policy.makeRowStore(); // Inform the row store about the table metadata - we do this by // passing the table itself, but this could be a data-less StarTable // object if the data were not available yet. rowStore.acceptMetadata( seqTable ); // Loop over the rows in the input table, passing each one in turn // to the row store. RowSequence rowSeq = seqTable.getRowSequence(); while ( rowSeq.next() ) { rowStore.acceptRow( rowSeq.getRow() ); } // Inform the row store that there are no more rows to come. rowStore.endRows(); // Extract and return a table from the row store. This consists of // the metadata and data we've written in there, but is guaranteed // random access. return rowStore.getStarTable(); }Most times you won't have to write this kind of code since the STIL classes will be doing it behind the scenes for you.