ColumnSet.h

Go to the documentation of this file.
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

Generated on Mon Sep 1 22:36:15 2008 for NRAOCASA by  doxygen 1.5.1