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

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1