1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
|
//# ISMColumn.h: A Column in the Incremental Storage Manager
//# Copyright (C) 1996,1997,1998,1999,2002
//# 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_ISMCOLUMN_H
#define TABLES_ISMCOLUMN_H
//# Includes
#include <casacore/casa/aips.h>
#include <casacore/tables/DataMan/StManColumnBase.h>
#include <casacore/tables/DataMan/ISMBase.h>
#include <casacore/casa/Arrays/IPosition.h>
#include <casacore/casa/Containers/Block.h>
#include <casacore/casa/Utilities/Compare.h>
#include <casacore/casa/OS/Conversion.h>
namespace casacore { //# NAMESPACE CASACORE - BEGIN
//# Forward declarations
class ISMBucket;
// <summary>
// A Column 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=ISMBase>ISMBase</linkto>
// </prerequisite>
// <etymology>
// ISMColumn represents a Column in the Incremental Storage Manager.
// </etymology>
// <synopsis>
// ISMColumn handles the access to a column containing scalars or direct
// arrays of the various data types. It uses class <linkto class=ISMBucket>
// ISMBucket</linkto> to get and put the data into the correct bucket.
// When the value does not fit in the bucket, the bucket is split
// and the new bucket is added to the storage manager.
// <p>
// The object maintains a variable indicating the last row ever put.
// This is used to decide if a put of a value is valid until the
// end of the table or for that one row only. In this way it does not
// make any difference if rows are added before or after a value is put
// <br>
// A value put before or at the last row ever put will only affect that
// one row. The rows before and after it keep their original value. If
// needed that value is copied.
// <p>
// To optimize (especially sequential) access to the column, ISMColumn
// maintains the last value gotten and the rows for which it is valid.
// In this way a get does not need to access the data in the bucket.
// <p>
// ISMColumn use the static conversion functions in the
// <linkto class=Conversion>Conversion</linkto> framework to
// get/put the data in external format (be it canonical or local).
// Most data types are fixed length, but some are variable length
// (e.g. String). In external format variable length data is preceeded
// by its total length (which includes the length itself). This makes
// it possible to get the length of a data value without having to
// interpret it, which is easy when (re)moving a value. For this reason
// ISMColumn contains its own conversion functions for Strings.
// <p>
// ISMColumn also acts as the base class for more specialized ISM
// column classes (i.e. <linkto class=ISMIndColumn>ISMIndColumn</linkto>
// for indirect columns).
// In this way <linkto class=ISMBase>ISMBase</linkto> can hold a
// block of <src>ISMColumn*</src> for any column. Furthermore
// <src>ISMColumn</src> contains the hooks to allow a derived class
// to use other ISMColumn functions (e.g. there are "action" functions
// for a derived class to react on the duplication or removal of
// a data value (e.g. due to a bucket split).
// </synopsis>
// <motivation>
// ISMColumn encapsulates all operations on an ISM Column.
// </motivation>
//# <todo asof="$DATE:$">
//# A List of bugs, limitations, extensions or planned refinements.
//# </todo>
class ISMColumn : public StManColumnBase
{
public:
// Create a ISMColumn object with the given parent.
// It initializes the various variables.
// It keeps the pointer to its parent (but does not own it).
ISMColumn (ISMBase* parent, int dataType, uInt colnr);
~ISMColumn();
// Forbid copy constructor.
ISMColumn (const ISMColumn&) = delete;
// Forbid assignment.
ISMColumn& operator= (const ISMColumn&) = delete;
// Set the shape of an array in the column.
virtual void setShapeColumn (const IPosition& shape);
// Get the dimensionality of the item in the given row.
// This is the same for all rows.
virtual uInt ndim (rownr_t rownr);
// Get the shape of the array in the given row.
// This is the same for all rows.
virtual IPosition shape (rownr_t rownr);
// Let the column object initialize itself for a newly created table.
// This is meant for a derived class.
virtual void doCreate (ISMBucket*);
// Let the column object initialize itself for an existing table.
virtual void getFile (rownr_t nrrow);
// Flush and optionally fsync the data.
// This is meant for a derived class.
virtual Bool flush (rownr_t nrrow, Bool fsync);
// Resync the storage manager with the new file contents.
// It resets the last rownr put.
void resync (rownr_t nrrow);
// Let the column reopen its data files for read/write access.
virtual void reopenRW();
// Get a scalar value in the given row.
// <group>
virtual void getBool (rownr_t rownr, Bool* dataPtr);
virtual void getuChar (rownr_t rownr, uChar* dataPtr);
virtual void getShort (rownr_t rownr, Short* dataPtr);
virtual void getuShort (rownr_t rownr, uShort* dataPtr);
virtual void getInt (rownr_t rownr, Int* dataPtr);
virtual void getuInt (rownr_t rownr, uInt* dataPtr);
virtual void getInt64 (rownr_t rownr, Int64* dataPtr);
virtual void getfloat (rownr_t rownr, float* dataPtr);
virtual void getdouble (rownr_t rownr, double* dataPtr);
virtual void getComplex (rownr_t rownr, Complex* dataPtr);
virtual void getDComplex (rownr_t rownr, DComplex* dataPtr);
virtual void getString (rownr_t rownr, String* dataPtr);
// </group>
// Put a scalar value in the given row.
// <group>
virtual void putBool (rownr_t rownr, const Bool* dataPtr);
virtual void putuChar (rownr_t rownr, const uChar* dataPtr);
virtual void putShort (rownr_t rownr, const Short* dataPtr);
virtual void putuShort (rownr_t rownr, const uShort* dataPtr);
virtual void putInt (rownr_t rownr, const Int* dataPtr);
virtual void putuInt (rownr_t rownr, const uInt* dataPtr);
virtual void putInt64 (rownr_t rownr, const Int64* dataPtr);
virtual void putfloat (rownr_t rownr, const float* dataPtr);
virtual void putdouble (rownr_t rownr, const double* dataPtr);
virtual void putComplex (rownr_t rownr, const Complex* dataPtr);
virtual void putDComplex (rownr_t rownr, const DComplex* dataPtr);
virtual void putString (rownr_t rownr, const String* dataPtr);
// </group>
// Get the scalar values in the entire column.
// The buffer pointed to by dataPtr has to have the correct length.
// (which is guaranteed by the ScalarColumn getColumn function).
virtual void getScalarColumnV (ArrayBase& dataPtr);
// Put the scalar values into the entire column.
// The buffer pointed to by dataPtr has to have the correct length.
// (which is guaranteed by the ScalarColumn putColumn function).
virtual void putScalarColumnV (const ArrayBase& dataPtr);
// Get the scalar values in some cells of the column.
// The buffer pointed to by dataPtr has to have the correct length.
// (which is guaranteed by the ScalarColumn getColumnCells function).
virtual void getScalarColumnCellsV (const RefRows& rownrs,
ArrayBase& dataPtr);
// Get an array value in the given row.
virtual void getArrayV (rownr_t rownr, ArrayBase& dataPtr);
// Put an array value in the given row.
virtual void putArrayV (rownr_t rownr, const ArrayBase& dataPtr);
// Add (newNrrow-oldNrrow) rows to the column and initialize
// the new rows when needed.
virtual void addRow (rownr_t newNrrow, rownr_t oldNrrow);
// Remove the given row in the bucket from the column.
void remove (rownr_t bucketRownr, ISMBucket* bucket, rownr_t bucketNrrow,
rownr_t newNrrow);
// Get the function needed to read/write a uInt and rownr from/to
// external format. This is used by other classes to read the length
// of a variable data value.
// <group>
static Conversion::ValueFunction* getReaduInt (Bool asCanonical);
static Conversion::ValueFunction* getReadRownr (Bool asCanonical);
static Conversion::ValueFunction* getWriteuInt (Bool asCanonical);
static Conversion::ValueFunction* getWriteRownr (Bool asCanonical);
// </group>
// Give a derived class the opportunity to react on the duplication
// of a value. It is used by ISMIndColumn.
virtual void handleCopy (rownr_t rownr, const char* value);
// Give a derived class the opportunity to react on the removal
// of a value. It is used by ISMIndColumn.
virtual void handleRemove (rownr_t rownr, const char* value);
// Get the fixed length of the data value in a cell of this column
// (0 = variable length).
uInt getFixedLength() const;
// Get the nr of elements in this data value.
uInt nelements() const;
protected:
// Test if the last value is invalid for this row.
Bool isLastValueInvalid (rownr_t rownr);
// Get the value for this row.
// Set the cache if the flag is set.
void getValue (rownr_t rownr, void* value, Bool setCache);
// Put the value for this row.
void putValue (rownr_t rownr, const void* value);
//# Declare member variables.
// Pointer to the parent storage manager.
ISMBase* stmanPtr_p;
// Length of column cell value in storage format (0 = variable length).
// If 0, the value is always preceeded by a uInt giving the length.
uInt fixedLength_p;
// Column sequence number of this column.
uInt colnr_p;
// The shape of the column.
IPosition shape_p;
// Number of elements in a value for this column.
uInt nrelem_p;
// Number of values to be copied.
// Normally this is nrelem_p, but for complex types it is 2*nrelem_p.
// When local format is used, it is the number of bytes.
uInt nrcopy_p;
// Cache for interval for which last value read is valid.
// The last value is valid for startRow_p till endRow_p (inclusive).
rownr_t startRow_p;
rownr_t endRow_p;
void* lastValue_p;
// The last row for which a value has been put.
rownr_t lastRowPut_p;
// The size of the data type in local format.
uInt typeSize_p;
// Pointer to a convert function for writing.
Conversion::ValueFunction* writeFunc_p;
// Pointer to a convert function for reading.
Conversion::ValueFunction* readFunc_p;
// Pointer to a compare function.
ObjCompareFunc* compareFunc_p;
private:
// Initialize part of the object.
// It is used by doCreate and getFile.
void init();
// Clear the object (used by destructor and init).
void clear();
// Put the value in all buckets from the given row on.
void putFromRow (rownr_t rownr, const char* data, uInt lenData);
// Put a data value into the bucket.
// When it is at the first row of the bucket, it replaces the value.
// Otherwise it is added.
void putData (ISMBucket* bucket, rownr_t bucketStartRow,
rownr_t bucketNrrow, rownr_t bucketRownr,
const char* data, uInt lenData,
Bool afterLastRow, Bool canSplit);
// Replace a value at the given offset in the bucket.
// If the bucket is too small, it will be split (if allowed).
void replaceData (ISMBucket* bucket, rownr_t bucketStartRow,
rownr_t bucketNrrow, rownr_t bucketRownr, uInt& offset,
const char* data, uInt lenData, Bool canSplit = True);
// Add a value at the given index in the bucket.
// If the bucket is too small, it will be split (if allowed).
Bool addData (ISMBucket* bucket, rownr_t bucketStartRow,
rownr_t bucketNrrow, rownr_t bucketRownr, uInt inx,
const char* data, uInt lenData,
Bool afterLastRow = False, Bool canSplit = True);
// Handle the duplicated values after a bucket split.
void handleSplit (ISMBucket& bucket, const Block<Bool>& duplicated);
// Compare the values.
virtual Bool compareValue (const void* val1, const void* val2) const;
// Handle a String in copying to/from external format.
// <group>
static size_t fromString (void* out, const void* in, size_t n,
Conversion::ValueFunction* writeLeng);
static size_t toString (void* out, const void* in, size_t n,
Conversion::ValueFunction* readLeng);
static size_t writeStringBE (void* out, const void* in, size_t n);
static size_t readStringBE (void* out, const void* in, size_t n);
static size_t writeStringLE (void* out, const void* in, size_t n);
static size_t readStringLE (void* out, const void* in, size_t n);
// </group>
void getScaCol (Vector<Bool>&);
void getScaCol (Vector<uChar>&);
void getScaCol (Vector<Short>&);
void getScaCol (Vector<uShort>&);
void getScaCol (Vector<Int>&);
void getScaCol (Vector<uInt>&);
void getScaCol (Vector<Int64>&);
void getScaCol (Vector<float>&);
void getScaCol (Vector<double>&);
void getScaCol (Vector<Complex>&);
void getScaCol (Vector<DComplex>&);
void getScaCol (Vector<String>&);
void getScaColCells (const RefRows&, Vector<Bool>&);
void getScaColCells (const RefRows&, Vector<uChar>&);
void getScaColCells (const RefRows&, Vector<Short>&);
void getScaColCells (const RefRows&, Vector<uShort>&);
void getScaColCells (const RefRows&, Vector<Int>&);
void getScaColCells (const RefRows&, Vector<uInt>&);
void getScaColCells (const RefRows&, Vector<Int64>&);
void getScaColCells (const RefRows&, Vector<float>&);
void getScaColCells (const RefRows&, Vector<double>&);
void getScaColCells (const RefRows&, Vector<Complex>&);
void getScaColCells (const RefRows&, Vector<DComplex>&);
void getScaColCells (const RefRows&, Vector<String>&);
void putScaCol (const Vector<Bool>&);
void putScaCol (const Vector<uChar>&);
void putScaCol (const Vector<Short>&);
void putScaCol (const Vector<uShort>&);
void putScaCol (const Vector<Int>&);
void putScaCol (const Vector<uInt>&);
void putScaCol (const Vector<Int64>&);
void putScaCol (const Vector<float>&);
void putScaCol (const Vector<double>&);
void putScaCol (const Vector<Complex>&);
void putScaCol (const Vector<DComplex>&);
void putScaCol (const Vector<String>&);
};
inline Bool ISMColumn::isLastValueInvalid (rownr_t rownr)
{
return rownr < startRow_p || rownr > endRow_p;
}
inline uInt ISMColumn::getFixedLength() const
{
return fixedLength_p;
}
inline uInt ISMColumn::nelements() const
{
return nrelem_p;
}
} //# NAMESPACE CASACORE - END
#endif
|