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$ 00027 00028 #ifndef TABLES_ISMBASE_H 00029 #define TABLES_ISMBASE_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/tables/DataMan/DataManager.h> 00035 #include <casacore/casa/Containers/Block.h> 00036 #include <casacore/casa/iosfwd.h> 00037 00038 namespace casacore { //# NAMESPACE CASACORE - 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 virtual void showCacheStatistics (ostream& os) const; 00155 00156 // Show the index statistics. 00157 void showIndexStatistics (ostream& os); 00158 00159 // Show the layout of the buckets 00160 void showBucketLayout (ostream& os); 00161 00162 // Get the bucket size (in bytes). 00163 uInt bucketSize() const; 00164 00165 // Get the size of a uInt in external format (can be canonical or local). 00166 uInt uIntSize() const; 00167 00168 // Get the bucket containing the given row. 00169 // Also return the first and last row of that bucket. 00170 // The bucket object is created and deleted by the caching mechanism. 00171 ISMBucket* getBucket (uInt rownr, uInt& bucketStartRow, 00172 uInt& bucketNrrow); 00173 00174 // Get the next bucket. 00175 // cursor=0 indicates the start of the iteration. 00176 // The first bucket returned is the bucket containing the rownr 00177 // given in bucketStartRow. 00178 // After each iteration BucketStartRow and bucketNrrow are set. 00179 // A 0 is returned when no more buckets. 00180 // The bucket object is created and deleted by the caching mechanism. 00181 ISMBucket* nextBucket (uInt& cursor, uInt& bucketStartRow, 00182 uInt& bucketNrrow); 00183 00184 // Get access to the temporary buffer. 00185 char* tempBuffer() const; 00186 00187 // Get a unique column number for the column 00188 // (it is only unique for this storage manager). 00189 // This is used by ISMColumnIndArr to create a unique file name. 00190 uInt uniqueNr(); 00191 00192 // Get the number of rows in this storage manager. 00193 uInt nrow() const; 00194 00195 // Can the storage manager add rows? (yes) 00196 virtual Bool canAddRow() const; 00197 00198 // Can the storage manager delete rows? (yes) 00199 virtual Bool canRemoveRow() const; 00200 00201 // Can the storage manager add columns? (not yet) 00202 virtual Bool canAddColumn() const; 00203 00204 // Can the storage manager delete columns? (not yet) 00205 virtual Bool canRemoveColumn() const; 00206 00207 // Make the object from the type name string. 00208 // This function gets registered in the DataManager "constructor" map. 00209 // The caller has to delete the object. 00210 static DataManager* makeObject (const String& dataManagerType, 00211 const Record& spec); 00212 00213 // Get access to the given column. 00214 ISMColumn& getColumn (uInt colnr); 00215 00216 // Add a bucket to the storage manager (i.e. to the cache). 00217 // The pointer is taken over. 00218 void addBucket (uInt rownr, ISMBucket* bucket); 00219 00220 // Make the current bucket in the cache dirty (i.e. something has been 00221 // changed in it and it needs to be written when removed from the cache). 00222 // (used by ISMColumn::putValue). 00223 void setBucketDirty(); 00224 00225 // Open (if needed) the file for indirect arrays with the given mode. 00226 // Return a pointer to the object. 00227 StManArrayFile* openArrayFile (ByteIO::OpenOption opt); 00228 00229 // Check that there are no repeated rowIds in the buckets comprising this ISM. 00230 Bool checkBucketLayout (uInt &offendingCursor, 00231 uInt &offendingBucketStartRow, 00232 uInt &offendingBucketNrow, 00233 uInt &offendingBucketNr, 00234 uInt &offendingCol, 00235 uInt &offendingIndex, 00236 uInt &offendingRow, 00237 uInt &offendingPrevRow); 00238 00239 private: 00240 // Copy constructor (only meant for clone function). 00241 ISMBase (const ISMBase& that); 00242 00243 // Assignment cannot be used. 00244 ISMBase& operator= (const ISMBase& that); 00245 00246 // (Re)create the index, file, and cache object. 00247 void recreate(); 00248 00249 // The data manager supports use of MultiFile. 00250 virtual Bool hasMultiFileSupport() const; 00251 00252 // Flush and optionally fsync the data. 00253 // It returns a True status if it had to flush (i.e. if data have changed). 00254 virtual Bool flush (AipsIO&, Bool fsync); 00255 00256 // Let the storage manager create files as needed for a new table. 00257 // This allows a column with an indirect array to create its file. 00258 virtual void create (uInt nrrow); 00259 00260 // Open the storage manager file for an existing table, read in 00261 // the data, and let the ISMColumn objects read their data. 00262 virtual void open (uInt nrrow, AipsIO&); 00263 00264 // Resync the storage manager with the new file contents. 00265 // This is done by clearing the cache. 00266 virtual void resync (uInt nrrow); 00267 00268 // Reopen the storage manager files for read/write. 00269 virtual void reopenRW(); 00270 00271 // The data manager will be deleted (because all its columns are 00272 // requested to be deleted). 00273 // So clean up the things needed (e.g. delete files). 00274 virtual void deleteManager(); 00275 00276 // Let the storage manager initialize itself. 00277 // It is used by create and open. 00278 void init(); 00279 00280 // Add rows to the storage manager. 00281 // Per column it extends the interval for which the last value written 00282 // is valid. 00283 virtual void addRow (uInt nrrow); 00284 00285 // Delete a row from all columns. 00286 virtual void removeRow (uInt rownr); 00287 00288 // Do the final addition of a column. 00289 // The <src>DataManagerColumn</src> object has already been created 00290 // (by the <src>makeXXColumn</src> function) and added to 00291 // <src>colSet_p</src>. However, it still has to be added to the 00292 // data files, which is done by this function. It uses the 00293 // pointer to find the correct column in the <src>colSet_p</src>. 00294 virtual void addColumn (DataManagerColumn*); 00295 00296 // Remove a column from the data file and the <src>colSet_p</src>. 00297 // The <src>DataManagerColumn</src> object gets deleted.. 00298 virtual void removeColumn (DataManagerColumn*); 00299 00300 // Create a column in the storage manager on behalf of a table column. 00301 // The caller has to delete the newly created object. 00302 // <group> 00303 // Create a scalar column. 00304 virtual DataManagerColumn* makeScalarColumn (const String& name, 00305 int dataType, 00306 const String& dataTypeID); 00307 // Create a direct array column. 00308 virtual DataManagerColumn* makeDirArrColumn (const String& name, 00309 int dataType, 00310 const String& dataTypeID); 00311 // Create an indirect array column. 00312 virtual DataManagerColumn* makeIndArrColumn (const String& name, 00313 int dataType, 00314 const String& dataTypeID); 00315 // </group> 00316 00317 // Get the cache object. 00318 // This will construct the cache object if not present yet. 00319 // The cache object will be deleted by the destructor. 00320 BucketCache& getCache(); 00321 00322 // Get the index object. 00323 // This will construct the index object if not present yet. 00324 // The index object will be deleted by the destructor. 00325 ISMIndex& getIndex(); 00326 00327 // Construct the cache object (if not constructed yet). 00328 void makeCache(); 00329 00330 // Construct the index object (if not constructed yet) and read it. 00331 void makeIndex(); 00332 00333 // Read the index (at the end of the file). 00334 void readIndex(); 00335 00336 // Write the index (at the end of the file). 00337 void writeIndex(); 00338 00339 00340 //# Declare member variables. 00341 // Name of data manager. 00342 String dataManName_p; 00343 // The version of the class. 00344 uInt version_p; 00345 // The file containing the indirect arrays. 00346 StManArrayFile* iosfile_p; 00347 // Unique nr for column in this storage manager. 00348 uInt uniqnr_p; 00349 // The number of rows in the columns. 00350 uInt nrrow_p; 00351 // The assembly of all columns. 00352 PtrBlock<ISMColumn*> colSet_p; 00353 // The cache with the ISM buckets. 00354 BucketCache* cache_p; 00355 // The file containing all data. 00356 BucketFile* file_p; 00357 // The ISM bucket index. 00358 ISMIndex* index_p; 00359 // The persistent cache size. 00360 uInt persCacheSize_p; 00361 // The actual cache size. 00362 uInt cacheSize_p; 00363 // The initial number of buckets in the cache. 00364 uInt nbucketInit_p; 00365 // The nr of free buckets. 00366 uInt nFreeBucket_p; 00367 // The first free bucket. 00368 Int firstFree_p; 00369 // The bucket size. 00370 uInt bucketSize_p; 00371 // Check a positive bucketsize? 00372 Bool checkBucketSize_p; 00373 // Has the data changed since the last flush? 00374 Bool dataChanged_p; 00375 // The size of a uInt in external format (local or canonical). 00376 uInt uIntSize_p; 00377 // A temporary read/write buffer (also for other classes). 00378 char* tempBuffer_p; 00379 }; 00380 00381 00382 inline uInt ISMBase::version() const 00383 { 00384 return version_p; 00385 } 00386 00387 inline uInt ISMBase::cacheSize() const 00388 { 00389 return cacheSize_p; 00390 } 00391 00392 inline uInt ISMBase::uniqueNr() 00393 { 00394 return uniqnr_p++; 00395 } 00396 00397 inline uInt ISMBase::nrow() const 00398 { 00399 return nrrow_p; 00400 } 00401 00402 inline uInt ISMBase::bucketSize() const 00403 { 00404 return bucketSize_p; 00405 } 00406 00407 inline uInt ISMBase::uIntSize() const 00408 { 00409 return uIntSize_p; 00410 } 00411 00412 inline char* ISMBase::tempBuffer() const 00413 { 00414 return tempBuffer_p; 00415 } 00416 00417 inline BucketCache& ISMBase::getCache() 00418 { 00419 if (cache_p == 0) { 00420 makeCache(); 00421 } 00422 return *cache_p; 00423 } 00424 00425 inline ISMIndex& ISMBase::getIndex() 00426 { 00427 if (index_p == 0) { 00428 makeIndex(); 00429 } 00430 return *index_p; 00431 } 00432 00433 inline ISMColumn& ISMBase::getColumn (uInt colnr) 00434 { 00435 return *(colSet_p[colnr]); 00436 } 00437 00438 00439 00440 } //# NAMESPACE CASACORE - END 00441 00442 #endif