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