The default behavior of
RDB object is to allocate space for data storage without pestering the user. When the object is used to read an
RDB table, it parses the file and creates RDBComments for each comment line and
RDBColumn of the appropriate datatype for each column.
When left to its own devices, an
RDB object will manage memory usage on its own with no need for intervention from the user. This management essentially consists of allocating
RDBComment objects and
RDBColumn objects on demand and deleting them via the destructor.
Likewise, the underlying RDBColumn objects used by the RDB object handle their own memory needs by default. So, upon creation an RDBColumn object allocates a single element for data storage. RDBColumns handle the deletion of this data storage element in the call to their destructor.
Copies of the values can be accessed via the RDB::getValue() methods or the RDBColumn::getData() methods.
Using the default data storage and the RDB::getValue() method.
while ( rdbtable.read( ) )
cout << "Column 0 value == " << rdbtable.getValue( 0 ) << endl;
Sometimes the user may want to handle memory for data storage on their own. It is possible to supply the
RDB object or
RDBColumn a pointer to memory the user has alloacted via the
RDBColumn::mapData() methods. By doing so the user can avoid calls to
RDBColumn::getData() or RDB::getValue() and simply access the value via the pointer to the storage they provided.
Any memory the user provides via RDBColumn::mapData() must be managed, i.e. deleted, by the user.
By providing their own memory for data storage, the user can also make use of RDB object's ablity to auto-index arrays used for storage.
With user supplied data storage there's no need to use the RDB::getValue() method.
double d;
rdbtable.getColumn( 0 )->mapData( d );
while ( rdbtable.read( ) )
cout << "Column 0 value == " << d << endl;
You can also store data from multiple rows.
double d_arr[10];
rdbtable.getColumn( 0 )->mapData( d, 10 );
int i = 0;
while ( rdbtable.read( ) ) {
cout << "Column 0 current value == " << d[i%10] << endl;
cout << "Column 0 previous value == " << d[(i-1)%10] << endl;
i++;
}
When the user supplies arrays of data storage via
RDBColumn::mapData() RDB objects and
RDBColumn will auto-index the arrays. As data is read or written, the default behavior is to increment the index into the user supplied array for data storage. It is possible then to store multiple rows of data.
RDB objects and RDBColumn increment the array index until the last element of the array provided by the user is reached. It then loops to the first element and begins over writing data.
It is possible to stop the auto-incrementing by calling the RDB::autoIdx() method. This temporarily turns off the auto-incrementing behavior until the next read or write.
In this example we want to store only the lines with negative data. So we use user supplied data storage and the
RDB::autoIdx() method.
double* d = new double( rdbtable.nRows( ) );
rdbtable.getColumn( 0 )->mapData( d, rdbtable.nRows( ) );
int i = 0;
while ( rdbtable.read( ) ) {
if ( 0 <= d[i] ) {
rdbtable.noAdvance( );
}
else
i++;
}
If the
RDB object is attached to a file stream, it is possible to rewind the file to the first line of data.
RDB::rewind() will move the file pointer back to the first data element. It also resets the array index for user supplied data storage. So, after a call to
RDB::rewind(), all user supplied data storage will be pointing to the first element in the array.
As noted above,
RDB::rewind only works when the
RDB object is attached to a stream that allows rewinding.
RDB::rewind() will fail if the
RDB is attached to STDIN or STDOUT.