casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ISMBase.h
Go to the documentation of this file.
00001 //# ISMBase.h: Base class of the Incremental Storage Manager
00002 //# Copyright (C) 1996,1997,1999,2000,2001,2002
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: ISMBase.h 21014 2011-01-06 08:57:49Z gervandiepen $
00027 
00028 #ifndef TABLES_ISMBASE_H
00029 #define TABLES_ISMBASE_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <tables/Tables/DataManager.h>
00035 #include <casa/Containers/Block.h>
00036 #include <casa/iosfwd.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 //# Forward declarations
00041 class BucketCache;
00042 class BucketFile;
00043 class ISMBucket;
00044 class ISMIndex;
00045 class ISMColumn;
00046 class StManArrayFile;
00047 
00048 // <summary>
00049 // Base class of the Incremental Storage Manager
00050 // </summary>
00051 
00052 // <use visibility=local>
00053 
00054 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tIncrementalStMan.cc">
00055 // </reviewed>
00056 
00057 // <prerequisite>
00058 //# Classes you should understand before using this one.
00059 //   <li> <linkto class=IncrementalStMan>IncrementalStMan</linkto>
00060 //   <li> <linkto class=ISMColumn>ISMColumn</linkto>
00061 // </prerequisite>
00062 
00063 // <etymology>
00064 // ISMBase is the base class of the Incremental Storage Manager.
00065 // </etymology>
00066 
00067 // <synopsis>
00068 // The behaviour of this class is described in
00069 // <linkto class="IncrementalStMan:description">IncrementalStMan</linkto>.
00070 
00071 // <motivation>
00072 // The public interface of ISMBase is quite large, because the other
00073 // internal ISM classes need these functions. To have a class with a
00074 // minimal interface for the normal user, class <src>IncrementalStMan</src>
00075 // is derived from it.
00076 // <br>IncrementalStMan needs an isA- instead of hasA-relation to be
00077 // able to bind columns to it in class <linkto class=SetupNewTable>
00078 // SetupNewTable</linkto>.
00079 // </motivation>
00080 
00081 // <todo asof="$DATE:$">
00082 //# A List of bugs, limitations, extensions or planned refinements.
00083 //   <li> Removed AipsIO argument from open and close.
00084 // </todo>
00085 
00086 
00087 class ISMBase: public DataManager
00088 {
00089 public:
00090     // Create an incremental storage manager without a name.
00091     // The bucket size has to be given in bytes and the cache size in buckets.
00092     // The bucket size is checked or calculated as described in
00093     // IncrementalStMan.h.
00094     explicit ISMBase (uInt bucketSize = 0, Bool checkBucketSize = True,
00095                       uInt cacheSize = 1);
00096 
00097     // Create an incremental storage manager with the given name.
00098     // The bucket size has to be given in bytes and the cache size in buckets.
00099     // The bucket size is checked or calculated as described in
00100     // IncrementalStMan.h.
00101     ISMBase (const String& dataManagerName,
00102              uInt bucketSize, Bool checkBucketSize, uInt cacheSize);
00103 
00104     // Create an incremental storage manager with the given name.
00105     // The specifications are in the record (as created by dataManagerSpec).
00106     ISMBase (const String& aDataManName,
00107              const Record& spec);
00108 
00109     ~ISMBase();
00110 
00111     // Clone this object.
00112     // It does not clone ISMColumn objects possibly used.
00113     // The caller has to delete the newly created object.
00114     virtual DataManager* clone() const;
00115 
00116     // Get the type name of the data manager (i.e. IncrementalStMan).
00117     virtual String dataManagerType() const;
00118 
00119     // Get the name given to the storage manager (in the constructor).
00120     virtual String dataManagerName() const;
00121 
00122     // Record a record containing data manager specifications.
00123     virtual Record dataManagerSpec() const;
00124 
00125     // Get data manager properties that can be modified.
00126     // It is only ActualCacheSize (the actual cache size in buckets).
00127     // It is a subset of the data manager specification.
00128     virtual Record getProperties() const;
00129 
00130     // Modify data manager properties.
00131     // Only ActualCacheSize can be used. It is similar to function setCacheSize
00132     // with <src>canExceedNrBuckets=False</src>.
00133     virtual void setProperties (const Record& spec);
00134 
00135     // Get the version of the class.
00136     uInt version() const;
00137 
00138     // Set the cache size (in buckets).
00139     // If <src>canExceedNrBuckets=True</src>, the given cache size can be
00140     // larger than the nr of buckets in the file. In this way the cache can
00141     // be made large enough for a future file extnsion.
00142     // Otherwise, it is limited to the actual number of buckets. This is useful
00143     // if one wants the entire file to be cached.
00144    void setCacheSize (uInt cacheSize, Bool canExceedNrBuckets);
00145 
00146     // Get the current cache size (in buckets).
00147     uInt cacheSize() const;
00148 
00149     // Clear the cache used by this storage manager.
00150     // It will flush the cache as needed and remove all buckets from it.
00151     void clearCache();
00152 
00153     // Show the statistics of all caches used.
00154     void showCacheStatistics (ostream& os) const;
00155 
00156     // Get the bucket size (in bytes).
00157     uInt bucketSize() const;
00158 
00159     // Get the size of a uInt in external format (can be canonical or local).
00160     uInt uIntSize() const;
00161 
00162     // Get the bucket containing the given row.
00163     // Also return the first and last row of that bucket.
00164     // The bucket object is created and deleted by the caching mechanism.
00165     ISMBucket* getBucket (uInt rownr, uInt& bucketStartRow,
00166                           uInt& bucketNrrow);
00167 
00168     // Get the next bucket.
00169     // cursor=0 indicates the start of the iteration.
00170     // The first bucket returned is the bucket containing the rownr
00171     // given in bucketStartRow.
00172     // After each iteration BucketStartRow and bucketNrrow are set.
00173     // A 0 is returned when no more buckets.
00174     // The bucket object is created and deleted by the caching mechanism.
00175     ISMBucket* nextBucket (uInt& cursor, uInt& bucketStartRow,
00176                            uInt& bucketNrrow);
00177 
00178     // Get access to the temporary buffer.
00179     char* tempBuffer() const;
00180 
00181     // Get a unique column number for the column
00182     // (it is only unique for this storage manager).
00183     // This is used by ISMColumnIndArr to create a unique file name.
00184     uInt uniqueNr();
00185 
00186     // Get the number of rows in this storage manager.
00187     uInt nrow() const;
00188 
00189     // Can the storage manager add rows? (yes)
00190     virtual Bool canAddRow() const;
00191 
00192     // Can the storage manager delete rows? (yes)
00193     virtual Bool canRemoveRow() const;
00194 
00195     // Can the storage manager add columns? (not yet)
00196     virtual Bool canAddColumn() const;
00197 
00198     // Can the storage manager delete columns? (not yet)
00199     virtual Bool canRemoveColumn() const;
00200 
00201     // Make the object from the type name string.
00202     // This function gets registered in the DataManager "constructor" map.
00203     // The caller has to delete the object.
00204     static DataManager* makeObject (const String& dataManagerType,
00205                                     const Record& spec);
00206 
00207     // Get access to the given column.
00208     ISMColumn& getColumn (uInt colnr);
00209 
00210     // Add a bucket to the storage manager (i.e. to the cache).
00211     // The pointer is taken over.
00212     void addBucket (uInt rownr, ISMBucket* bucket);
00213 
00214     // Make the current bucket in the cache dirty (i.e. something has been
00215     // changed in it and it needs to be written when removed from the cache).
00216     // (used by ISMColumn::putValue).
00217     void setBucketDirty();
00218 
00219     // Open (if needed) the file for indirect arrays with the given mode.
00220     // Return a pointer to the object.
00221     StManArrayFile* openArrayFile (ByteIO::OpenOption opt);
00222 
00223 
00224 private:
00225     // Copy constructor (only meant for clone function).
00226     ISMBase (const ISMBase& that);
00227 
00228     // Assignment cannot be used.
00229     ISMBase& operator= (const ISMBase& that);
00230 
00231     // (Re)create the index, file, and cache object.
00232     void recreate();
00233 
00234     // Flush and optionally fsync the data.
00235     // It returns a True status if it had to flush (i.e. if data have changed).
00236     virtual Bool flush (AipsIO&, Bool fsync);
00237 
00238     // Let the storage manager create files as needed for a new table.
00239     // This allows a column with an indirect array to create its file.
00240     virtual void create (uInt nrrow);
00241 
00242     // Open the storage manager file for an existing table, read in
00243     // the data, and let the ISMColumn objects read their data.
00244     virtual void open (uInt nrrow, AipsIO&);
00245 
00246     // Resync the storage manager with the new file contents.
00247     // This is done by clearing the cache.
00248     virtual void resync (uInt nrrow);
00249 
00250     // Reopen the storage manager files for read/write.
00251     virtual void reopenRW();
00252 
00253     // The data manager will be deleted (because all its columns are
00254     // requested to be deleted).
00255     // So clean up the things needed (e.g. delete files).
00256     virtual void deleteManager();
00257 
00258     // Let the storage manager initialize itself.
00259     // It is used by create and open.
00260     void init();
00261 
00262     // Add rows to the storage manager.
00263     // Per column it extends the interval for which the last value written
00264     // is valid.
00265     virtual void addRow (uInt nrrow);
00266 
00267     // Delete a row from all columns.
00268     virtual void removeRow (uInt rownr);
00269 
00270     // Do the final addition of a column.
00271     // The <src>DataManagerColumn</src> object has already been created
00272     // (by the <src>makeXXColumn</src> function) and added to
00273     // <src>colSet_p</src>. However, it still has to be added to the
00274     // data files, which is done by this function. It uses the
00275     // pointer to find the correct column in the <src>colSet_p</src>.
00276     virtual void addColumn (DataManagerColumn*);
00277 
00278     // Remove a column from the data file and the <src>colSet_p</src>.
00279     // The <src>DataManagerColumn</src> object gets deleted..
00280     virtual void removeColumn (DataManagerColumn*);
00281 
00282     // Create a column in the storage manager on behalf of a table column.
00283     // The caller has to delete the newly created object.
00284     // <group>
00285     // Create a scalar column.
00286     virtual DataManagerColumn* makeScalarColumn (const String& name,
00287                                                  int dataType,
00288                                                  const String& dataTypeID);
00289     // Create a direct array column.
00290     virtual DataManagerColumn* makeDirArrColumn (const String& name,
00291                                                  int dataType,
00292                                                  const String& dataTypeID);
00293     // Create an indirect array column.
00294     virtual DataManagerColumn* makeIndArrColumn (const String& name,
00295                                                  int dataType,
00296                                                  const String& dataTypeID);
00297     // </group>
00298 
00299     // Get the cache object.
00300     // This will construct the cache object if not present yet.
00301     // The cache object will be deleted by the destructor.
00302     BucketCache& getCache();
00303 
00304     // Get the index object.
00305     // This will construct the index object if not present yet.
00306     // The index object will be deleted by the destructor.
00307     ISMIndex& getIndex();
00308 
00309     // Construct the cache object (if not constructed yet).
00310     void makeCache();
00311 
00312     // Construct the index object (if not constructed yet) and read it.
00313     void makeIndex();
00314 
00315     // Read the index (at the end of the file).
00316     void readIndex();
00317 
00318     // Write the index (at the end of the file).
00319     void writeIndex();
00320 
00321 
00322     //# Declare member variables.
00323     // Name of data manager.
00324     String       dataManName_p;
00325     // The version of the class.
00326     uInt         version_p;
00327     // The file containing the indirect arrays.
00328     StManArrayFile* iosfile_p;
00329     // Unique nr for column in this storage manager.
00330     uInt         uniqnr_p;
00331     // The number of rows in the columns.
00332     uInt         nrrow_p;
00333     // The assembly of all columns.
00334     PtrBlock<ISMColumn*>  colSet_p;
00335     // The cache with the ISM buckets.
00336     BucketCache* cache_p;
00337     // The file containing all data.
00338     BucketFile*  file_p;
00339     // The ISM bucket index.
00340     ISMIndex*    index_p;
00341     // The persistent cache size.
00342     uInt persCacheSize_p;
00343     // The actual cache size.
00344     uInt cacheSize_p;
00345     // The initial number of buckets in the cache.
00346     uInt nbucketInit_p;
00347     // The nr of free buckets.
00348     uInt nFreeBucket_p;
00349     // The first free bucket.
00350     Int firstFree_p;
00351     // The bucket size.
00352     uInt bucketSize_p;
00353     // Check a positive bucketsize?
00354     Bool checkBucketSize_p;
00355     // Has the data changed since the last flush?
00356     Bool dataChanged_p;
00357     // The size of a uInt in external format (local or canonical).
00358     uInt uIntSize_p;
00359     // A temporary read/write buffer (also for other classes).
00360     char* tempBuffer_p;
00361 };
00362 
00363 
00364 inline uInt ISMBase::version() const
00365 {
00366     return version_p;
00367 }
00368 
00369 inline uInt ISMBase::cacheSize() const
00370 {
00371     return cacheSize_p;
00372 }
00373 
00374 inline uInt ISMBase::uniqueNr()
00375 {
00376     return uniqnr_p++;
00377 }
00378 
00379 inline uInt ISMBase::nrow() const
00380 {
00381     return nrrow_p;
00382 }
00383 
00384 inline uInt ISMBase::bucketSize() const
00385 {
00386     return bucketSize_p;
00387 }
00388 
00389 inline uInt ISMBase::uIntSize() const
00390 {
00391     return uIntSize_p;
00392 }
00393 
00394 inline char* ISMBase::tempBuffer() const
00395 {
00396     return tempBuffer_p;
00397 }
00398 
00399 inline BucketCache& ISMBase::getCache()
00400 {
00401     if (cache_p == 0) {
00402         makeCache();
00403     }
00404     return *cache_p;
00405 }
00406 
00407 inline ISMIndex& ISMBase::getIndex()
00408 {
00409     if (index_p == 0) {
00410         makeIndex();
00411     }
00412     return *index_p;
00413 }
00414 
00415 inline ISMColumn& ISMBase::getColumn (uInt colnr)
00416 {
00417     return *(colSet_p[colnr]);
00418 }
00419 
00420 
00421 
00422 } //# NAMESPACE CASA - END
00423 
00424 #endif