casa
$Rev:20696$
|
00001 //# ColumnSet.h: Class to manage a set of table columns 00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2003 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: ColumnSet.h 21014 2011-01-06 08:57:49Z gervandiepen $ 00027 00028 #ifndef TABLES_COLUMNSET_H 00029 #define TABLES_COLUMNSET_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <tables/Tables/TableLockData.h> 00035 #include <tables/Tables/BaseTable.h> 00036 #include <casa/Containers/SimOrdMap.h> 00037 #include <casa/BasicSL/String.h> 00038 00039 namespace casa { //# NAMESPACE CASA - BEGIN 00040 00041 //# Forward Declarations 00042 class SetupNewTable; 00043 class Table; 00044 class TableDesc; 00045 class TSMOption; 00046 class BaseTable; 00047 class TableAttr; 00048 class ColumnDesc; 00049 class PlainColumn; 00050 class DataManager; 00051 class Record; 00052 class IPosition; 00053 class AipsIO; 00054 template<class T> class Vector; 00055 00056 00057 // <summary> 00058 // Class to manage a set of table columns 00059 // </summary> 00060 00061 // <use visibility=local> 00062 00063 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00064 // </reviewed> 00065 00066 // <prerequisite> 00067 //# Classes you should understand before using this one. 00068 // <li> PlainTable 00069 // <li> DataManager 00070 // </prerequisite> 00071 00072 // <etymology> 00073 // ColumnSet represent the set of columns in a table. 00074 // </etymology> 00075 00076 // <synopsis> 00077 // ColumnSet contains all columns in a plain table (thus not in a RefTable). 00078 // Furthermore it contains the set of data managers used by the columns 00079 // in the table. 00080 // 00081 // The main purpose of the class is to deal with constructing, writing 00082 // and reading the column objects. It is used by classes SetupNewTable 00083 // and Table. 00084 // </synopsis> 00085 00086 // <todo asof="$DATE:$"> 00087 //# A List of bugs, limitations, extensions or planned refinements. 00088 // </todo> 00089 00090 00091 class ColumnSet 00092 { 00093 public: 00094 00095 // Construct from the table description. 00096 // This creates all underlying filled and virtual column objects. 00097 ColumnSet (TableDesc*); 00098 00099 ~ColumnSet(); 00100 00101 // Reopen the data managers for read/write. 00102 void reopenRW(); 00103 00104 // Rename the necessary subtables in the column keywords. 00105 void renameTables (const String& newName, const String& oldName); 00106 00107 // Are subtables used in other processes. 00108 Bool areTablesMultiUsed() const; 00109 00110 // Get a column by name. 00111 PlainColumn* getColumn (const String& columnName) const; 00112 00113 // Get a column by index. 00114 PlainColumn* getColumn (uInt columnIndex) const; 00115 00116 // Add a data manager. 00117 // It increments seqCount_p and returns that as a unique sequence number. 00118 // This can, for instance, be used to create a unique file name. 00119 void addDataManager (DataManager*); 00120 00121 // Initialize the data managers for a new table. 00122 // It creates the data manager column objects for each column 00123 // and it allows the data managers to link themselves to the 00124 // Table object and to initialize themselves. 00125 void initDataManagers (uInt nrrow, Bool bigEndian, 00126 const TSMOption& tsmOption, 00127 Table& tab); 00128 00129 // Link the ColumnSet object to the BaseTable object. 00130 void linkToTable (BaseTable* baseTableObject); 00131 00132 // Link the ColumnSet object to the TableLockData object. 00133 void linkToLockObject (TableLockData* lockObject); 00134 00135 // Check if the table is locked for read or write. 00136 // If manual or permanent locking is in effect, it checks if the 00137 // table is properly locked. 00138 // If autolocking is in effect, it locks the table when needed. 00139 // <group> 00140 void checkReadLock (Bool wait); 00141 void checkWriteLock (Bool wait); 00142 // </group> 00143 00144 // Inspect the auto lock when the inspection interval has expired and 00145 // release it when another process needs the lock. 00146 void autoReleaseLock(); 00147 00148 // If needed, get a temporary user lock. 00149 // It returns False if the lock was already there. 00150 Bool userLock (FileLocker::LockType, Bool wait); 00151 00152 // Release a temporary user lock if the given release flag is True. 00153 void userUnlock (Bool releaseFlag); 00154 00155 // Do all data managers and engines allow to add rows? 00156 Bool canAddRow() const; 00157 00158 // Do all data managers and engines allow to remove rows? 00159 Bool canRemoveRow() const; 00160 00161 // Can the given columns be removed from the data manager? 00162 Bool canRemoveColumn (const Vector<String>& columnNames) const; 00163 00164 // Can a column be renamed in the data manager? 00165 Bool canRenameColumn (const String& columnName) const; 00166 00167 // Add rows to all data managers. 00168 void addRow (uInt nrrow); 00169 00170 // Remove a row from all data managers. 00171 // It will throw an exception if not possible. 00172 void removeRow (uInt rownr); 00173 00174 // Remove the columns from the map and the data manager. 00175 void removeColumn (const Vector<String>& columnNames); 00176 00177 // Rename the column in the map. 00178 void renameColumn (const String& newName, const String& oldName); 00179 00180 // Add a column to the table. 00181 // The default implementation throws an "invalid operation" exception. 00182 // <group> 00183 void addColumn (const ColumnDesc& columnDesc, 00184 Bool bigEndian, const TSMOption& tsmOption, Table& tab); 00185 void addColumn (const ColumnDesc& columnDesc, 00186 const String& dataManager, Bool byName, 00187 Bool bigEndian, const TSMOption& tsmOption, Table& tab); 00188 void addColumn (const ColumnDesc& columnDesc, 00189 const DataManager& dataManager, 00190 Bool bigEndian, const TSMOption& tsmOption, Table& tab); 00191 void addColumn (const TableDesc& tableDesc, 00192 const DataManager& dataManager, 00193 Bool bigEndian, const TSMOption& tsmOption, Table& tab); 00194 // </group> 00195 00196 // Get nr of rows. 00197 uInt nrow() const; 00198 00199 // Get the actual table description. 00200 TableDesc actualTableDesc() const; 00201 00202 // Get the data manager info. 00203 // Optionally only the virtual engines are retrieved. 00204 Record dataManagerInfo (Bool virtualOnly=False) const; 00205 00206 // Initialize rows startRownr till endRownr (inclusive). 00207 void initialize (uInt startRownr, uInt endRownr); 00208 00209 // Write all the data and let the data managers flush their data. 00210 // This function is called when a table gets written (i.e. flushed). 00211 // It returns True if any data manager wrote something. 00212 Bool putFile (Bool writeTable, AipsIO&, const TableAttr&, Bool fsync); 00213 00214 // Read the data, reconstruct the data managers, and link those to 00215 // the table object. 00216 // This function gets called when an existing table is read back. 00217 // It returns the number of rows in case a data manager thinks there are 00218 // more. That is in particular used by LofarStMan. 00219 uInt getFile (AipsIO&, Table& tab, uInt nrrow, Bool bigEndian, 00220 const TSMOption& tsmOption); 00221 00222 // Set the table to being changed. 00223 void setTableChanged(); 00224 00225 // Get the data manager change flags (used by PlainTable). 00226 Block<Bool>& dataManChanged(); 00227 00228 // Synchronize the data managers when data in them have changed. 00229 // It returns the number of rows it think it has, which is needed for 00230 // storage managers like LofarStMan. 00231 // <src>forceSync=True</src> means that the data managers are forced 00232 // to do a sync. Otherwise the contents of the lock file tell if a data 00233 // manager has to sync. 00234 uInt resync (uInt nrrow, Bool forceSync); 00235 00236 // Invalidate the column caches for all columns. 00237 void invalidateColumnCaches(); 00238 00239 // Get the correct data manager. 00240 // This is used by the column objects to link themselves to the 00241 // correct datamanagers when they are read back. 00242 DataManager* getDataManager (uInt seqnr) const; 00243 00244 // Check if no double data manager names have been given. 00245 void checkDataManagerNames (const String& tableName) const; 00246 00247 // Find the data manager with the given name or for the given column. 00248 // If the data manager or column is unknown, an exception is thrown. 00249 // A blank name means the data manager is unknown. 00250 DataManager* findDataManager (const String& name, 00251 Bool byColumn=False) const; 00252 00253 // Make a unique data manager name by appending a suffix _n if needed 00254 // where n is a number that makes the name unique. 00255 String uniqueDataManagerName (const String& name) const; 00256 00257 // Synchronize the columns after it appeared that data in the 00258 // main table file have changed. 00259 // It cannot deal with changes in number of columns, so it throws an 00260 // exception when they have changed. 00261 // Keywords in all columns are updated. 00262 // The other ColumnSet gives the new data. 00263 void syncColumns (const ColumnSet& other, const TableAttr& defaultAttr); 00264 00265 private: 00266 // Remove the last data manager (used by addColumn after an exception). 00267 // It does the opposite of addDataManager. 00268 void removeLastDataManager(); 00269 00270 // Let the data managers (from the given index on) initialize themselves. 00271 void initSomeDataManagers (uInt from, Table& tab); 00272 00273 // Let the data managers (from the given index on) prepare themselves. 00274 void prepareSomeDataManagers (uInt from); 00275 00276 // Check if a data manager name has not already been used. 00277 // Start checking at the given index in the array. 00278 // It returns False if the name has already been used. 00279 // By default an exception is thrown if the name has already been used. 00280 Bool checkDataManagerName (const String& name, uInt from, 00281 const String& tableName, 00282 Bool doTthrow=True) const; 00283 00284 // Do the actual addition of a column. 00285 void doAddColumn (const ColumnDesc& columnDesc, DataManager* dataManPtr); 00286 00287 // Check if columns to be removed can be removed. 00288 // It returns a map of DataManager* telling how many columns for 00289 // a data manager have to be removed. A count of -1 means that all 00290 // columns have to be removed. For such columns the flag in the 00291 // returned Block is False, otherwise True. 00292 SimpleOrderedMap<void*,Int> checkRemoveColumn 00293 (const Vector<String>& columnNames); 00294 00295 // Check if the table is locked for read or write. 00296 // If manual or permanent locking is in effect, it checks if the 00297 // table is properly locked. 00298 // If autolocking is in effect, it locks the table when needed. 00299 void doLock (FileLocker::LockType, Bool wait); 00300 00301 00302 //# Declare the variables. 00303 TableDesc* tdescPtr_p; 00304 uInt nrrow_p; //# #rows 00305 BaseTable* baseTablePtr_p; 00306 TableLockData* lockPtr_p; //# lock object 00307 SimpleOrderedMap<String,void*> colMap_p; //# list of PlainColumns 00308 uInt seqCount_p; //# sequence number count 00309 //# (used for unique seqnr) 00310 Block<void*> blockDataMan_p; //# list of data managers 00311 Block<Bool> dataManChanged_p; //# data has changed 00312 }; 00313 00314 00315 00316 inline uInt ColumnSet::nrow() const 00317 { 00318 return nrrow_p; 00319 } 00320 inline void ColumnSet::linkToTable (BaseTable* baseTableObject) 00321 { 00322 baseTablePtr_p = baseTableObject; 00323 } 00324 inline void ColumnSet::setTableChanged() 00325 { 00326 baseTablePtr_p->setTableChanged(); 00327 } 00328 inline void ColumnSet::linkToLockObject (TableLockData* lockObject) 00329 { 00330 lockPtr_p = lockObject; 00331 } 00332 inline void ColumnSet::checkReadLock (Bool wait) 00333 { 00334 if (lockPtr_p->readLocking() 00335 && ! lockPtr_p->hasLock (FileLocker::Read)) { 00336 doLock (FileLocker::Read, wait); 00337 } 00338 } 00339 inline void ColumnSet::checkWriteLock (Bool wait) 00340 { 00341 if (! lockPtr_p->hasLock (FileLocker::Write)) { 00342 doLock (FileLocker::Write, wait); 00343 } 00344 } 00345 inline void ColumnSet::userUnlock (Bool releaseFlag) 00346 { 00347 if (releaseFlag) { 00348 lockPtr_p->release(); 00349 } 00350 } 00351 inline void ColumnSet::autoReleaseLock() 00352 { 00353 lockPtr_p->autoRelease(); 00354 } 00355 inline Block<Bool>& ColumnSet::dataManChanged() 00356 { 00357 return dataManChanged_p; 00358 } 00359 00360 00361 00362 00363 } //# NAMESPACE CASA - END 00364 00365 #endif