casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
StManAipsIO.h
Go to the documentation of this file.
00001 //# StManAipsIO.h: Storage manager for tables using AipsIO
00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: StManAipsIO.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef TABLES_STMANAIPSIO_H
00029 #define TABLES_STMANAIPSIO_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <tables/Tables/DataManager.h>
00035 #include <tables/Tables/StManColumn.h>
00036 #include <casa/Containers/Block.h>
00037 #include <casa/BasicSL/Complex.h>
00038 #include <casa/Arrays/IPosition.h>
00039 #include <casa/BasicSL/String.h>
00040 #include <casa/IO/ByteIO.h>
00041 
00042 namespace casa { //# NAMESPACE CASA - BEGIN
00043 
00044 //# Forward clarations
00045 class AipsIO;
00046 class StManAipsIO;
00047 class StManArrayFile;
00048 
00049 
00050 // <summary>
00051 // AipsIO table column storage manager class
00052 // </summary>
00053 
00054 // <use visibility=local>
00055 
00056 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00057 // </reviewed>
00058 
00059 // <prerequisite>
00060 //# Classes you should understand before using this one.
00061 //   <li> StManColumn
00062 // </prerequisite>
00063 
00064 // <etymology>
00065 // StManColumnAipsIO handles a column for an AipsIO storage manager.
00066 // </etymology>
00067 
00068 // <synopsis> 
00069 // StManColumnAipsIO is used by StManAipsIO to handle the access to
00070 // the data in a table column.
00071 // It is an storage manager based on AipsIO. The entire column is
00072 // kept in memory and only written when the storage manager closes.
00073 // When the storage manager gets opened, the entire column gets
00074 // read back.
00075 // It fully supports addition and removal of rows.
00076 //
00077 // StManColumnAipsIO serves 2 purposes:
00078 // <ol>
00079 // <li> It handles a column containing scalar values.
00080 // <li> It serves as a base class for StManArrayColumnAipsIO and
00081 //        StManIndArrayColumnAipsIO. These classes handle arrays and
00082 //        use StManColumnAipsIO to hold a pointer to the array in each row.
00083 // </ol>
00084 //
00085 // StManColumnAipsIO does not hold a column as a consecutive array,
00086 // because extending the column (i.e. adding rows) proofed be too
00087 // expensive due to the repeated copying involved when creating a table
00088 // (this method was used by the old table system).
00089 // Instead it has a number of data blocks (extensions) indexed to by a
00090 // super block. Accessing a row means finding the appropriate extension
00091 // via a binary search. Because there is only 1 extension when a table is
00092 // read back, the overhead in finding a row is small.
00093 // </synopsis> 
00094 
00095 // <motivation>
00096 // StManColumnAipsIO handles the standard data types. The class
00097 // is not templated, but a switch statement is used instead.
00098 // Templates would cause too many instantiations.
00099 // </motivation>
00100 
00101 // <todo asof="$DATE:$">
00102 //# A List of bugs, limitations, extensions or planned refinements.
00103 // </todo>
00104 
00105 
00106 class StManColumnAipsIO : public StManColumn
00107 {
00108 public:
00109 
00110     // Create a column of the given type.
00111     // It will maintain a pointer to its parent storage manager.
00112     StManColumnAipsIO (StManAipsIO* stMan, int dataType, Bool byPtr);
00113 
00114     // Frees up the storage.
00115     virtual ~StManColumnAipsIO();
00116 
00117     // Get a scalar value in the given row.
00118     // The buffer pointed to by dataPtr has to have the correct length
00119     // (which is guaranteed by the Scalar/ArrayColumn get function).
00120     // <group>
00121     void getBoolV     (uInt rownr, Bool* dataPtr);
00122     void getuCharV    (uInt rownr, uChar* dataPtr);
00123     void getShortV    (uInt rownr, Short* dataPtr);
00124     void getuShortV   (uInt rownr, uShort* dataPtr);
00125     void getIntV      (uInt rownr, Int* dataPtr);
00126     void getuIntV     (uInt rownr, uInt* dataPtr);
00127     void getfloatV    (uInt rownr, float* dataPtr);
00128     void getdoubleV   (uInt rownr, double* dataPtr);
00129     void getComplexV  (uInt rownr, Complex* dataPtr);
00130     void getDComplexV (uInt rownr, DComplex* dataPtr);
00131     void getStringV   (uInt rownr, String* dataPtr);
00132     // </group>
00133 
00134     // Put a scalar value into the given row.
00135     // The buffer pointed to by dataPtr has to have the correct length
00136     // (which is guaranteed by the Scalar/ArrayColumn put function).
00137     // <group>
00138     void putBoolV     (uInt rownr, const Bool* dataPtr);
00139     void putuCharV    (uInt rownr, const uChar* dataPtr);
00140     void putShortV    (uInt rownr, const Short* dataPtr);
00141     void putuShortV   (uInt rownr, const uShort* dataPtr);
00142     void putIntV      (uInt rownr, const Int* dataPtr);
00143     void putuIntV     (uInt rownr, const uInt* dataPtr);
00144     void putfloatV    (uInt rownr, const float* dataPtr);
00145     void putdoubleV   (uInt rownr, const double* dataPtr);
00146     void putComplexV  (uInt rownr, const Complex* dataPtr);
00147     void putDComplexV (uInt rownr, const DComplex* dataPtr);
00148     void putStringV   (uInt rownr, const String* dataPtr);
00149     // </group>
00150 
00151     // Get scalars from the given row on with a maximum of nrmax values.
00152     // This can be used to get an entire column of scalars or to get
00153     // a part of a column (for a cache for example).
00154     // The buffer pointed to by dataPtr has to have the correct length
00155     // (which is guaranteed by the ScalarColumn get function).
00156     // <group>
00157     uInt getBlockBoolV     (uInt rownr, uInt nrmax, Bool* dataPtr);
00158     uInt getBlockuCharV    (uInt rownr, uInt nrmax, uChar* dataPtr);
00159     uInt getBlockShortV    (uInt rownr, uInt nrmax, Short* dataPtr);
00160     uInt getBlockuShortV   (uInt rownr, uInt nrmax, uShort* dataPtr);
00161     uInt getBlockIntV      (uInt rownr, uInt nrmax, Int* dataPtr);
00162     uInt getBlockuIntV     (uInt rownr, uInt nrmax, uInt* dataPtr);
00163     uInt getBlockfloatV    (uInt rownr, uInt nrmax, float* dataPtr);
00164     uInt getBlockdoubleV   (uInt rownr, uInt nrmax, double* dataPtr);
00165     uInt getBlockComplexV  (uInt rownr, uInt nrmax, Complex* dataPtr);
00166     uInt getBlockDComplexV (uInt rownr, uInt nrmax, DComplex* dataPtr);
00167     uInt getBlockStringV   (uInt rownr, uInt nrmax, String* dataPtr);
00168     // </group>
00169 
00170     // Put nrmax scalars from the given row on.
00171     // This can be used to put an entire column of scalars or to put
00172     // a part of a column (for a cache for example).
00173     // The buffer pointed to by dataPtr has to have the correct length
00174     // (which is guaranteed by the ScalarColumn put function).
00175     // <group>
00176     void putBlockBoolV     (uInt rownr, uInt nrmax, const Bool* dataPtr);
00177     void putBlockuCharV    (uInt rownr, uInt nrmax, const uChar* dataPtr);
00178     void putBlockShortV    (uInt rownr, uInt nrmax, const Short* dataPtr);
00179     void putBlockuShortV   (uInt rownr, uInt nrmax, const uShort* dataPtr);
00180     void putBlockIntV      (uInt rownr, uInt nrmax, const Int* dataPtr);
00181     void putBlockuIntV     (uInt rownr, uInt nrmax, const uInt* dataPtr);
00182     void putBlockfloatV    (uInt rownr, uInt nrmax, const float* dataPtr);
00183     void putBlockdoubleV   (uInt rownr, uInt nrmax, const double* dataPtr);
00184     void putBlockComplexV  (uInt rownr, uInt nrmax, const Complex* dataPtr);
00185     void putBlockDComplexV (uInt rownr, uInt nrmax, const DComplex* dataPtr);
00186     void putBlockStringV   (uInt rownr, uInt nrmax, const String* dataPtr);
00187     // </group>
00188 
00189     // Get the scalar values in some cells of the column.
00190     // The buffer pointed to by dataPtr has to have the correct length.
00191     // (which is guaranteed by the ScalarColumn getColumnCells function).
00192     // The default implementation loops through all rows.
00193     // <group>
00194     virtual void getScalarColumnCellsBoolV     (const RefRows& rownrs,
00195                                                 Vector<Bool>* dataPtr);
00196     virtual void getScalarColumnCellsuCharV    (const RefRows& rownrs,
00197                                                 Vector<uChar>* dataPtr);
00198     virtual void getScalarColumnCellsShortV    (const RefRows& rownrs,
00199                                                 Vector<Short>* dataPtr);
00200     virtual void getScalarColumnCellsuShortV   (const RefRows& rownrs,
00201                                                 Vector<uShort>* dataPtr);
00202     virtual void getScalarColumnCellsIntV      (const RefRows& rownrs,
00203                                                 Vector<Int>* dataPtr);
00204     virtual void getScalarColumnCellsuIntV     (const RefRows& rownrs,
00205                                                 Vector<uInt>* dataPtr);
00206     virtual void getScalarColumnCellsfloatV    (const RefRows& rownrs,
00207                                                 Vector<float>* dataPtr);
00208     virtual void getScalarColumnCellsdoubleV   (const RefRows& rownrs,
00209                                                 Vector<double>* dataPtr);
00210     virtual void getScalarColumnCellsComplexV  (const RefRows& rownrs,
00211                                                 Vector<Complex>* dataPtr);
00212     virtual void getScalarColumnCellsDComplexV (const RefRows& rownrs,
00213                                                 Vector<DComplex>* dataPtr);
00214     virtual void getScalarColumnCellsStringV   (const RefRows& rownrs,
00215                                                 Vector<String>* dataPtr);
00216     // </group>
00217 
00218     // Add (newNrrow-oldNrrow) rows to the column.
00219     virtual void addRow (uInt newNrrow, uInt oldNrrow);
00220 
00221     // Resize the data blocks.
00222     // This adds an extension when needed.
00223     void resize (uInt nrval);
00224 
00225     // Remove the given row.
00226     // If no rows remain in the extension, the extension is also removed.
00227     virtual void remove (uInt rownr);
00228 
00229     // Create the number of rows in a new table.
00230     // This is used when a table gets created.
00231     virtual void doCreate (uInt nrrow);
00232 
00233     // Write the column data into AipsIO.
00234     // It will successively write all extensions using putData.
00235     virtual void putFile (uInt nrval, AipsIO&);
00236 
00237     // Read the column data from AipsIO.
00238     // One extension gets allocated to hold all rows in the column.
00239     virtual void getFile (uInt nrval, AipsIO&);
00240 
00241     // Reopen the storage manager files for read/write.
00242     virtual void reopenRW();
00243 
00244     // Check if the class invariants still hold.
00245     virtual Bool ok() const;
00246 
00247 protected:
00248     // The storage manager.
00249     StManAipsIO* stmanPtr_p;
00250     // The data type (for caching purposes).
00251     int dtype_p;
00252     // The data is indirectly accessed via a pointer (for the derived classes).
00253     Bool  byPtr_p;
00254     // The number of allocated rows in the column.
00255     uInt  nralloc_p;
00256     // The nr of extensions in use.
00257     uInt  nrext_p;
00258     // The assembly of all extensions (actually Block<T*>).
00259     Block<void*> data_p;
00260     // The cumulative nr of rows in all extensions.
00261     Block<uInt>  ncum_p;
00262 
00263     // Find the extension in which the row number is.
00264     // If the flag is true, it also sets the columnCache object.
00265     uInt findExt (uInt rownr, Bool setCache);
00266 
00267     // Get the next extension.
00268     // For the first iteration extnr should be zero.
00269     // It returns the number of values in it until the maximum is reached.
00270     // Zero means no more extensions.
00271     uInt nextExt (void*& ext, uInt& extnr, uInt nrmax) const;
00272 
00273     // Allocate an extension with the data type of the column.
00274     void* allocData (uInt nrval, Bool byPtr);
00275 
00276     // Delete all extensions.
00277     // Possible underlying data (as used by StManArrayColumnAipsIO)
00278     // will not be deleted and should have been deleted beforehand.
00279     void deleteAll();
00280 
00281     // Delete an extension.
00282     void deleteData (void* datap, Bool byPtr);
00283 
00284     // Remove an entry (i.e. a row) from an extension at the given index.
00285     // It will do this by shifting the rest (nrvalAfter elements)
00286     // one position to the left.
00287     void removeData (void* datap, uInt inx, uInt nrvalAfter);
00288 
00289     // Put the data (nrval elements) in an extension (starting at datap)
00290     // into AipsIO.
00291     virtual void putData (void* datap, uInt nrval, AipsIO&);
00292 
00293     // Get data (nrval elements) into an extension (starting at datap
00294     // plus the given index).
00295     virtual void getData (void* datap, uInt index, uInt nrval, AipsIO&,
00296                           uInt version);
00297 
00298     // Get the pointer for the given row.
00299     // This is for the derived classes like StManArrayColumnAipsIO.
00300     void* getArrayPtr (uInt rownr);
00301 
00302     // Put the pointer for the given row.
00303     // This is for the derived classes like StManArrayColumnAipsIO.
00304     void putArrayPtr (uInt rownr, void* dataPtr);
00305 
00306 private:
00307     // Forbid copy constructor.
00308     StManColumnAipsIO (const StManColumnAipsIO&);
00309 
00310     // Forbid assignment.
00311     StManColumnAipsIO& operator= (const StManColumnAipsIO&);
00312 };
00313 
00314 
00315 
00316 
00317 // <summary>
00318 // AipsIO table storage manager class
00319 // </summary>
00320 
00321 // <use visibility=export>
00322 
00323 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00324 // </reviewed>
00325 
00326 // <prerequisite>
00327 //# Classes you should understand before using this one.
00328 //   <li> DataManager
00329 //   <li> StManColumnAipsIO
00330 // </prerequisite>
00331 
00332 // <etymology>
00333 // StManAipsIO is the storage manager using AipsIO.
00334 // </etymology>
00335 
00336 // <synopsis> 
00337 // StManAipsIO is a table storage manager based on AipsIO.
00338 // It holds the data in the columns in memory and writes them to
00339 // a file when the table gets closed. Only the data of indirect arrays
00340 // are directly read/written from/to a file.
00341 // It contains pointers to the underlying StManColumnAipsIO objects,
00342 // which do the actual data handling.
00343 //
00344 // The AipsIO storage manager does fully support addition and removal
00345 // of rows and columns.
00346 //
00347 // All data, except indirect columns, for this storage manager are kept
00348 // in one file. The file name is the table name appended with
00349 // .N_AipsIO, where N is the (unique) storage manager sequence number.
00350 // Each column containing indirect arrays is stored in a separate file
00351 // using class StManIndArrayColumnAipsIO. The name of such a file is
00352 // the storage manager file name appended with _cM, where M is a unique
00353 // column sequence number acquired using function uniqueNr().
00354 // </synopsis> 
00355 
00356 // <todo asof="$DATE:$">
00357 //# A List of bugs, limitations, extensions or planned refinements.
00358 // </todo>
00359 
00360 
00361 class StManAipsIO : public DataManager
00362 {
00363 public:
00364 
00365     // Create an AipsIO storage manager.
00366     // Its name will be blank.
00367     StManAipsIO();
00368 
00369     // Create an AipsIO storage manager with the given name.
00370     // Its name can be used later in e.g. Table::addColumn to
00371     // add a column to this storage manager.
00372     // <br> Note that the 2nd constructor is needed for table creation
00373     // from a record specification.
00374     // <group>
00375     StManAipsIO (const String& storageManagerName);
00376     StManAipsIO (const String& storageManagerName, const Record&);
00377     // </group>
00378 
00379     ~StManAipsIO();
00380 
00381     // Clone this object.
00382     // It does not clone StManAipsIOColumn objects possibly used.
00383     DataManager* clone() const;
00384 
00385     // Get the type name of the data manager (i.e. StManAipsIO).
00386     String dataManagerType() const;
00387 
00388     // Get the name given to this storage manager.
00389     String dataManagerName() const;
00390 
00391     // Get a unique column number for the column
00392     // (it is only unique for this storage manager).
00393     // This is used by StManIndArrayColumnAipsIO to create a unique file name.
00394     uInt uniqueNr()
00395         { return uniqnr_p++; }
00396 
00397     // Get the nr of rows in this storage manager.
00398     uInt nrow() const
00399         { return nrrow_p; }
00400 
00401     // Set the hasPut_p flag. In this way the StManAipsIOColumn objects
00402     // can indicate that data have been put.
00403     void setHasPut()
00404         { hasPut_p = True; }
00405 
00406     // Does the storage manager allow to add rows? (yes)
00407     Bool canAddRow() const;
00408 
00409     // Does the storage manager allow to delete rows? (yes)
00410     Bool canRemoveRow() const;
00411 
00412     // Does the storage manager allow to add columns? (yes)
00413     Bool canAddColumn() const;
00414 
00415     // Does the storage manager allow to delete columns? (yes)
00416     Bool canRemoveColumn() const;
00417 
00418     // Make the object from the string.
00419     // This function gets registered in the DataManager "constructor" map.
00420     static DataManager* makeObject (const String& dataManagerType,
00421                                     const Record& spec);
00422 
00423     // Open (if needed) the file for indirect arrays with the given mode.
00424     // Return a pointer to the object.
00425     StManArrayFile* openArrayFile (ByteIO::OpenOption opt);
00426 
00427 
00428 private:
00429     // Forbid copy constructor.
00430     StManAipsIO (const StManAipsIO&);
00431 
00432     // Forbid assignment.
00433     StManAipsIO& operator= (const StManAipsIO&);
00434 
00435     // Flush and optionally fsync the data.
00436     // It returns a True status if it had to flush (i.e. if data have changed).
00437     virtual Bool flush (AipsIO&, Bool fsync);
00438 
00439     // Let the storage manager create files as needed for a new table.
00440     // This allows a column with an indirect array to create its file.
00441     virtual void create (uInt nrrow);
00442 
00443     // Open the storage manager file for an existing table and read in
00444     // the data and let the StManColumnAipsIO objects read their data.
00445     virtual void open (uInt nrrow, AipsIO&);
00446 
00447     // Resync the storage manager with the new file contents.
00448     // This is done by clearing the cache.
00449     virtual void resync (uInt nrrow);
00450 
00451     // Reopen the storage manager files for read/write.
00452     virtual void reopenRW();
00453 
00454     // The data manager will be deleted (because all its columns are
00455     // requested to be deleted).
00456     // So clean up the things needed (e.g. delete files).
00457     virtual void deleteManager();
00458 
00459     // Add rows to all columns.
00460     void addRow (uInt nrrow);
00461 
00462     // Delete a row from all columns.
00463     void removeRow (uInt rownr);
00464 
00465     // Create a column in the storage manager on behalf of a table column.
00466     // <group>
00467     // Create a scalar column.
00468     DataManagerColumn* makeScalarColumn (const String& name, int dataType,
00469                                          const String& dataTypeID);
00470     // Create a direct array column.
00471     DataManagerColumn* makeDirArrColumn (const String& name, int dataType,
00472                                          const String& dataTypeID);
00473     // Create an indirect array column.
00474     DataManagerColumn* makeIndArrColumn (const String& name, int dataType,
00475                                          const String& dataTypeID);
00476     // </group>
00477 
00478     // Add a column.
00479     void addColumn (DataManagerColumn*);
00480 
00481     // Delete a column.
00482     void removeColumn (DataManagerColumn*);
00483 
00484 
00485     // Name given by user to this storage manager.
00486     String stmanName_p;
00487     // Unique nr for column in this storage manager.
00488     uInt   uniqnr_p;
00489     // The number of rows in the columns.
00490     uInt   nrrow_p;
00491     // The assembly of all columns.
00492     PtrBlock<StManColumnAipsIO*>  colSet_p;
00493     // Has anything been put since the last flush?
00494     Bool   hasPut_p;
00495     // The file containing the indirect arrays.
00496     StManArrayFile* iosfile_p;
00497 };
00498 
00499 
00500 
00501 
00502 } //# NAMESPACE CASA - END
00503 
00504 #endif