Loading...
Searching...
No Matches
ISMBucket.h
Go to the documentation of this file.
//# ISMBucket.h: A bucket in the Incremental Storage Manager
//# Copyright (C) 1996,1999,2000,2001
//# Associated Universities, Inc. Washington DC, USA.
//#
//# This library is free software; you can redistribute it and/or modify it
//# under the terms of the GNU Library General Public License as published by
//# the Free Software Foundation; either version 2 of the License, or (at your
//# option) any later version.
//#
//# This library is distributed in the hope that it will be useful, but WITHOUT
//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
//# License for more details.
//#
//# You should have received a copy of the GNU Library General Public License
//# along with this library; if not, write to the Free Software Foundation,
//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
//#
//# Correspondence concerning AIPS++ should be addressed as follows:
//# Internet email: casa-feedback@nrao.edu.
//# Postal address: AIPS++ Project Office
//# National Radio Astronomy Observatory
//# 520 Edgemont Road
//# Charlottesville, VA 22903-2475 USA
#ifndef TABLES_ISMBUCKET_H
#define TABLES_ISMBUCKET_H
//# Includes
#include <casacore/casa/aips.h>
#include <casacore/casa/Containers/Block.h>
#include <casacore/casa/BasicSL/String.h>
#include <casacore/casa/iosfwd.h>
namespace casacore { //# NAMESPACE CASACORE - BEGIN
//# Forward declarations
class ISMBase;
// <summary>
// A bucket in the Incremental Storage Manager
// </summary>
// <use visibility=local>
// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
// </reviewed>
// <prerequisite>
//# Classes you should understand before using this one.
// <li> <linkto class=IncrementalStMan>IncrementalStMan</linkto>
// <li> <linkto class=BucketCache>BucketCache</linkto>
// </prerequisite>
// <etymology>
// ISMBucket represents a bucket in the Incremental Storage Manager.
// </etymology>
// <synopsis>
// The Incremental Storage Manager uses a <linkto class=BucketCache>
// BucketCache</linkto> object to read/write/cache the buckets
// containing the data. An <src>ISMBucket</src> object is the
// internal representation of the contents of a bucket. <src>ISMBucket</src>
// contains static callback functions which are called by
// <src>BucketCache</src> when reading/writing a bucket. These callback
// functions do the mapping of bucket data to <src>ISMBucket</src> object
// and vice-versa.
// <p>
// A bucket contains the values of several rows
// of all columns bound to this Incremental Storage Manager.
// A bucket is split into a data part and an index part.
// Each part has an arbitrary length but together they do not exceed
// the fixed bucket length.
// <p>
// The beginning of the data part contains the values of all columns
// bound. The remainder of the data part contains the values of
// the rows/columns with a changed value.
// <br>
// The index part contains an index per column. Each index contains the
// row number and an offset for a row with a stored value. The row numbers
// are relative to the beginning of the bucket, so the bucket has
// no knowledge about the absolute row numbers. In this way deletion of
// rows is much simpler.
// <p>
// The contents of a bucket looks like:
// <srcblock>
// -------------------------------------------------------------------
// | index offset | data part | index part | free |
// -------------------------------------------------------------------
// 0 4 4+length(data part)
// <--------------------------bucketsize----------------------------->
// </srcblock>
// The data part contains all data value belonging to the bucket.
// The index part contains for each column the following data:
// <srcblock>
// -----------------------------------------------------------------------
// | #values stored | row numbers of values | offset in data part of |
// | for column i | stored for column i | values stored for column i |
// -----------------------------------------------------------------------
// 0 4 4+4*nrval
// </srcblock>
// Note that the row numbers in the bucket start at 0, thus are relative
// to the beginning of the bucket. The main index kept in
// <linkto class=ISMIndex>ISMIndex</linkto> knows the starting row of
// each bucket. In this way bucket splitting and especially row removal
// is much easier.
// <p>
// The bucket can be stored in canonical or local (i.e. native) data format.
// When a bucket is read into memory, its data are read, converted, and
// stored in the ISMBucket object. When flushed, the contents are
// written. ISMBucket takes care that the values stored in its object
// do not exceed the size of the bucket. When full, the user can call
// a function to split it into a left and right bucket. When the new
// value has to be written at the end, the split merely consist of
// creating a new bucket. In any case, care is taken that a row is
// not split. Thus a row is always entirely contained in one bucket.
// <p>
// Class <linkto class=ISMColumn>ISMColumn</linkto> does the actual
// writing of data in a bucket and uses the relevant ISMBucket functions.
// <motivation>
// ISMBucket encapsulates the data of a bucket.
// </motivation>
//# <todo asof="$DATE:$">
//# A List of bugs, limitations, extensions or planned refinements.
//# </todo>
class ISMBucket
{
public:
// Create a bucket with the given parent.
// When <src>bucketStorage</src> is non-zero, reconstruct the
// object from it.
// It keeps the pointer to its parent (but does not own it).
ISMBucket (ISMBase* parent, const char* bucketStorage);
~ISMBucket();
// Forbid copy constructor.
ISMBucket (const ISMBucket&) = delete;
// Forbid assignment.
ISMBucket& operator= (const ISMBucket&) = delete;
// Get the row-interval for given column and row.
// It sets the start and end of the interval to which the row belongs
// and the offset of its current value.
// It returns the index where the row number can be put in the
// bucket index.
uInt getInterval (uInt colnr, rownr_t rownr, rownr_t bucketNrrow,
rownr_t& start, rownr_t& end, uInt& offset) const;
// Is the bucket large enough to add a value?
Bool canAddData (uInt leng) const;
// Add the data to the data part.
// It updates the bucket index at the given index.
// An exception is thrown if the bucket is too small.
void addData (uInt colnr, rownr_t rownr, uInt index,
const char* data, uInt leng);
// Is the bucket large enough to replace a value?
Bool canReplaceData (uInt newLeng, uInt oldLeng) const;
// Replace a data item.
// When its length is variable (indicated by fixedLength=0), the old
// value will be removed and the new one appended at the end.
// An exception is thrown if the bucket is too small.
void replaceData (uInt& offset, const char* data, uInt newLeng,
uInt fixedLength);
// Get a pointer to the data for the given offset.
const char* get (uInt offset) const;
// Get the length of the data value.
// It is <src>fixedLength</src> when non-zero,
// otherwise read it from the data value.
uInt getLength (uInt fixedLength, const char* data) const;
// Get access to the offset of the data for given column and row.
// It allows to change it (used for example by replaceData).
uInt& getOffset (uInt colnr, rownr_t rownr);
// Get access to the index information for the given column.
// This is used by ISMColumn when putting the data.
// <group>
// Return the row numbers with a stored value.
Block<rownr_t>& rowIndex (uInt colnr);
// Return the offsets of the values stored in the data part.
Block<uInt>& offIndex (uInt colnr);
// Return the number of values stored.
uInt& indexUsed (uInt colnr);
// </group>
// Split the bucket in the middle.
// It returns the row number where the bucket was split and the
// new left and right bucket. The caller is responsible for
// deleting the newly created buckets.
// When possible a simple split is done.
// <br>
// The starting values in the right bucket may be copies of the
// values in the left bucket. The duplicated Block contains a switch
// per column indicating if the value is copied.
rownr_t split (ISMBucket*& left, ISMBucket*& right, Block<Bool>& duplicated,
rownr_t bucketStartRow, rownr_t bucketNrrow,
uInt colnr, rownr_t rownr, uInt lengToAdd);
// Determine whether a simple split is possible. If so, do it.
// This is possible if the new row is at the end of the last bucket,
// which will often be the case.
// <br>A simple split means adding a new bucket for the new row.
// If the old bucket already contains values for that row, those
// values are moved to the new bucket.
// <br>This fuction is only called by split, which created the
// left and right bucket.
Bool simpleSplit (ISMBucket* left, ISMBucket* right,
Block<Bool>& duplicated,
rownr_t& splitRownr, rownr_t rownr);
// Return the index where the bucket should be split to get
// two parts with almost identical length.
uInt getSplit (uInt totLeng, const Block<uInt>& rowLeng,
const Block<uInt>& cumLeng);
// Remove <src>nr</src> items from data and index part by shifting
// to the left. The <src>rowIndex</src>, <src>offIndex</src>, and
// <src>nused</src> get updated. The caller is responsible for
// removing data when needed (e.g. <src>ISMIndColumn</src> removes
// the indirect arrays from its file).
void shiftLeft (uInt index, uInt nr, Block<rownr_t>& rowIndex,
Block<uInt>& offIndex, uInt& nused, uInt leng);
// Copy the contents of that bucket to this bucket.
// This is used after a split operation.
void copy (const ISMBucket& that);
// Callback function when BucketCache reads a bucket.
// It creates an ISMBucket object and converts the raw bucketStorage
// to that object.
// It returns the pointer to ISMBucket object which gets part of the cache.
// The object gets deleted by the deleteCallBack function.
static char* readCallBack (void* owner, const char* bucketStorage);
// Callback function when BucketCache writes a bucket.
// It converts the ISMBucket bucket object to the raw bucketStorage.
static void writeCallBack (void* owner, char* bucketStorage,
const char* bucket);
// Callback function when BucketCache adds a new bucket to the data file.
// This function creates an empty ISMBucket object.
// It returns the pointer to ISMBucket object which gets part of the cache.
// The object gets deleted by the deleteCallBack function.
static char* initCallBack (void* owner);
// Callback function when BucketCache removes a bucket from the cache.
// This function dletes the ISMBucket bucket object.
static void deleteCallBack (void*, char* bucket);
// Show the layout of the bucket.
void show (ostream& os) const;
// Check that there are no repeated rowIds in the bucket
Bool check (uInt& offendingCol, uInt& offendingIndex,
rownr_t& offendingRow, rownr_t& offendingPrevRow) const;
private:
// Remove a data item with the given length.
// If the length is zero, its variable length is read first.
void removeData (uInt offset, uInt leng);
// Insert a data value by appending it to the end.
// It returns the offset of the data value.
uInt insertData (const char* data, uInt leng);
// Copy a data item from this bucket to the other bucket.
uInt copyData (ISMBucket& other, uInt colnr, rownr_t toRownr,
uInt fromIndex, uInt toIndex) const;
// Read the data from the storage into this bucket.
void read (const char* bucketStorage);
// Write the bucket into the storage.
void write (char* bucketStorage) const;
//# Declare member variables.
// Pointer to the parent storage manager.
ISMBase* stmanPtr_p;
// The size (in bytes) of an uInt and rownr_t (used in index, etc.).
uInt uIntSize_p;
uInt rownrSize_p;
// The size (in bytes) of the data.
uInt dataLeng_p;
// The size (in bytes) of the index.
uInt indexLeng_p;
// The row index per column; each index contains the row number
// of each value stored in the bucket (for that column).
Block<Block<rownr_t>*> rowIndex_p;
// The offset index per column; each index contains the offset (in bytes)
// of each value stored in the bucket (for that column).
Block<Block<uInt>*> offIndex_p;
// Nr of used elements in each index; i.e. the number of stored values
// per column.
Block<uInt> indexUsed_p;
// The data space (in external (e.g. canonical) format).
char* data_p;
};
inline const char* ISMBucket::get (uInt offset) const
{
return data_p + offset;
}
inline Block<rownr_t>& ISMBucket::rowIndex (uInt colnr)
{
return *(rowIndex_p[colnr]);
}
inline Block<uInt>& ISMBucket::offIndex (uInt colnr)
{
return *(offIndex_p[colnr]);
}
inline uInt& ISMBucket::indexUsed (uInt colnr)
{
return indexUsed_p[colnr];
}
} //# NAMESPACE CASACORE - END
#endif
casacore::Block
Definition Block.h:140
casacore::ISMBase
Definition ISMBase.h:86
casacore::ISMBucket::~ISMBucket
~ISMBucket()
casacore::ISMBucket::read
void read(const char *bucketStorage)
Read the data from the storage into this bucket.
casacore::ISMBucket::initCallBack
static char * initCallBack(void *owner)
Callback function when BucketCache adds a new bucket to the data file.
casacore::ISMBucket::indexUsed
uInt & indexUsed(uInt colnr)
Return the number of values stored.
Definition ISMBucket.h:325
casacore::ISMBucket::stmanPtr_p
ISMBase * stmanPtr_p
Pointer to the parent storage manager.
Definition ISMBucket.h:291
casacore::ISMBucket::get
const char * get(uInt offset) const
Get a pointer to the data for the given offset.
Definition ISMBucket.h:313
casacore::ISMBucket::rownrSize_p
uInt rownrSize_p
Definition ISMBucket.h:294
casacore::ISMBucket::rowIndex
Block< rownr_t > & rowIndex(uInt colnr)
Get access to the index information for the given column.
Definition ISMBucket.h:317
casacore::ISMBucket::operator=
ISMBucket & operator=(const ISMBucket &)=delete
Forbid assignment.
casacore::ISMBucket::uIntSize_p
uInt uIntSize_p
The size (in bytes) of an uInt and rownr_t (used in index, etc.).
Definition ISMBucket.h:293
casacore::ISMBucket::getInterval
uInt getInterval(uInt colnr, rownr_t rownr, rownr_t bucketNrrow, rownr_t &start, rownr_t &end, uInt &offset) const
Get the row-interval for given column and row.
casacore::ISMBucket::removeData
void removeData(uInt offset, uInt leng)
Remove a data item with the given length.
casacore::ISMBucket::offIndex_p
Block< Block< uInt > * > offIndex_p
The offset index per column; each index contains the offset (in bytes) of each value stored in the bu...
Definition ISMBucket.h:304
casacore::ISMBucket::indexUsed_p
Block< uInt > indexUsed_p
Nr of used elements in each index; i.e.
Definition ISMBucket.h:307
casacore::ISMBucket::copyData
uInt copyData(ISMBucket &other, uInt colnr, rownr_t toRownr, uInt fromIndex, uInt toIndex) const
Copy a data item from this bucket to the other bucket.
casacore::ISMBucket::canReplaceData
Bool canReplaceData(uInt newLeng, uInt oldLeng) const
Is the bucket large enough to replace a value?
casacore::ISMBucket::check
Bool check(uInt &offendingCol, uInt &offendingIndex, rownr_t &offendingRow, rownr_t &offendingPrevRow) const
Check that there are no repeated rowIds in the bucket.
casacore::ISMBucket::offIndex
Block< uInt > & offIndex(uInt colnr)
Return the offsets of the values stored in the data part.
Definition ISMBucket.h:321
casacore::ISMBucket::copy
void copy(const ISMBucket &that)
Copy the contents of that bucket to this bucket.
casacore::ISMBucket::data_p
char * data_p
The data space (in external (e.g.
Definition ISMBucket.h:309
casacore::ISMBucket::rowIndex_p
Block< Block< rownr_t > * > rowIndex_p
The row index per column; each index contains the row number of each value stored in the bucket (for ...
Definition ISMBucket.h:301
casacore::ISMBucket::readCallBack
static char * readCallBack(void *owner, const char *bucketStorage)
Callback function when BucketCache reads a bucket.
casacore::ISMBucket::shiftLeft
void shiftLeft(uInt index, uInt nr, Block< rownr_t > &rowIndex, Block< uInt > &offIndex, uInt &nused, uInt leng)
Remove nr items from data and index part by shifting to the left.
casacore::ISMBucket::simpleSplit
Bool simpleSplit(ISMBucket *left, ISMBucket *right, Block< Bool > &duplicated, rownr_t &splitRownr, rownr_t rownr)
Determine whether a simple split is possible.
casacore::ISMBucket::getOffset
uInt & getOffset(uInt colnr, rownr_t rownr)
Get access to the offset of the data for given column and row.
casacore::ISMBucket::ISMBucket
ISMBucket(const ISMBucket &)=delete
Forbid copy constructor.
casacore::ISMBucket::dataLeng_p
uInt dataLeng_p
The size (in bytes) of the data.
Definition ISMBucket.h:296
casacore::ISMBucket::addData
void addData(uInt colnr, rownr_t rownr, uInt index, const char *data, uInt leng)
Add the data to the data part.
casacore::ISMBucket::write
void write(char *bucketStorage) const
Write the bucket into the storage.
casacore::ISMBucket::show
void show(ostream &os) const
Show the layout of the bucket.
casacore::ISMBucket::insertData
uInt insertData(const char *data, uInt leng)
Insert a data value by appending it to the end.
casacore::ISMBucket::deleteCallBack
static void deleteCallBack(void *, char *bucket)
Callback function when BucketCache removes a bucket from the cache.
casacore::ISMBucket::getLength
uInt getLength(uInt fixedLength, const char *data) const
Get the length of the data value.
casacore::ISMBucket::replaceData
void replaceData(uInt &offset, const char *data, uInt newLeng, uInt fixedLength)
Replace a data item.
casacore::ISMBucket::indexLeng_p
uInt indexLeng_p
The size (in bytes) of the index.
Definition ISMBucket.h:298
casacore::ISMBucket::writeCallBack
static void writeCallBack(void *owner, char *bucketStorage, const char *bucket)
Callback function when BucketCache writes a bucket.
casacore::ISMBucket::canAddData
Bool canAddData(uInt leng) const
Is the bucket large enough to add a value?
casacore::ISMBucket::split
rownr_t split(ISMBucket *&left, ISMBucket *&right, Block< Bool > &duplicated, rownr_t bucketStartRow, rownr_t bucketNrrow, uInt colnr, rownr_t rownr, uInt lengToAdd)
Split the bucket in the middle.
casacore::ISMBucket::getSplit
uInt getSplit(uInt totLeng, const Block< uInt > &rowLeng, const Block< uInt > &cumLeng)
Return the index where the bucket should be split to get two parts with almost identical length.
casacore::ISMBucket::ISMBucket
ISMBucket(ISMBase *parent, const char *bucketStorage)
Create a bucket with the given parent.
casacore
this file contains all the compiler specific defines
Definition mainpage.dox:28
casacore::offset
int offset(int, int) const
compute a linear offset from array indicies
casacore::uInt
unsigned int uInt
Definition aipstype.h:49
casacore::Bool
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
casacore::end
iterator end()
Definition Block.h:594
casacore::get
const T & get() const
Definition RecordField.h:143
casacore::rownr_t
uInt64 rownr_t
Define the type of a row number in a table.
Definition aipsxtype.h:44