00001 //# RefTable.h: Class for a table as a view of another table 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_REFTABLE_H 00029 #define TABLES_REFTABLE_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <tables/Tables/BaseTable.h> 00035 #include <casa/BasicSL/String.h> 00036 #include <casa/Arrays/Vector.h> 00037 #include <casa/Containers/SimOrdMap.h> 00038 00039 namespace casa { //# NAMESPACE CASA - BEGIN 00040 00041 //# Forward Declarations 00042 class RefColumn; 00043 class AipsIO; 00044 00045 00046 // <summary> 00047 // Class for a table as a view of another table 00048 // </summary> 00049 00050 // <use visibility=local> 00051 00052 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00053 // </reviewed> 00054 00055 // <prerequisite> 00056 //# Classes you should understand before using this one. 00057 // <li> BaseTable 00058 // <li> RefColumn 00059 // </prerequisite> 00060 00061 // <etymology> 00062 // RefTable represents a table which is a view on another table, 00063 // thus which references another table. 00064 // </etymology> 00065 00066 // <synopsis> 00067 // RefTable is used to make a view on another table. 00068 // Usually it is a view on a subset of the table, either in vertical 00069 // or horizontal direction. Thus a subset of rows and/or columns. 00070 // It will be the result of a select, sort, project or iterate function. 00071 // 00072 // It acts to the user as a normal table. All gets and puts are 00073 // handled by RefColumn which directs them to the referenced column 00074 // while (if needed) converting the given row number to the row number 00075 // in the referenced table. For that purpose RefTable maintains a 00076 // Vector of the row numbers in the referenced table. 00077 // 00078 // The RefTable constructor acts in a way that it will always reference 00079 // the original table. This means that if a select is done on a RefTable, 00080 // the resulting RefTable will also reference the original PlainTable. 00081 // This is done to avoid long chains of RefTables. 00082 // However, if ever some other kind of table views are introduced 00083 // (like a join or a concatenation of similar tables), this cannot be 00084 // used anymore. Most software already anticipates on that. The only 00085 // exception is the code anding, oring tables (refAnd, etc.). 00086 // </synopsis> 00087 00088 // <todo asof="$DATE:$"> 00089 //# A List of bugs, limitations, extensions or planned refinements. 00090 // <li> Maybe not allocating the row number vector for a projection. 00091 // This saves space and time, but each rownr conversion will 00092 // take a bit more time because it has to test if there is a vector. 00093 // <li> Maybe maintain a Vector<String> telling on which columns 00094 // the table is ordered. This may speed up selection, but 00095 // it is hard to check if the order is changed by a put. 00096 // <li> Allow to remove a row or column from the RefTable 00097 // <li> Allow to rename a column in the RefTable 00098 // <li> Maybe implement doSort one time for a more efficient sort. 00099 // (now everything is handled by BaseTable). 00100 // </todo> 00101 00102 00103 class RefTable : public BaseTable 00104 { 00105 public: 00106 00107 // Create a reference table object referencing the 00108 // given BaseTable object. 00109 // If the BaseTable is actually another RefTable, it will reference 00110 // its referenced table (thus the original table) and it will 00111 // take its vector of row numbers and projected column names 00112 // into account. Thus if a select is done on a projected table, 00113 // the resulting RefTable will have the same projection. 00114 // <group> 00115 // Construct a RefTable with an empty row number vector. 00116 // rowOrder=True indicates that the order of the rows will not 00117 // be disturbed (as will be the case for a sort). 00118 // A row number vector of the given size is initially allocated. 00119 // Later this RefTable will be filled in by the select, etc.. 00120 RefTable (BaseTable*, Bool rowOrder, uInt initialNrrow); 00121 00122 // A RefTable with the given row numbers is constructed. 00123 RefTable (BaseTable*, const Vector<uInt>& rowNumbers); 00124 00125 // Create a reference table object out of a mask. 00126 // The row number vector will consist of the rows for which the 00127 // mask has a True value. 00128 // The length of the mask must be the number of rows in the BaseTable. 00129 RefTable (BaseTable*, const Vector<Bool>& rowMask); 00130 00131 // Create a reference table object via projection (i.e. column selection). 00132 // The row number vector is a copy of the given table. 00133 RefTable (BaseTable*, const Vector<String>& columnNames); 00134 // </group> 00135 00136 // Create a reference table out of a file (written by writeRefTable). 00137 // The referenced table will also be created (if not stored in the cache). 00138 RefTable (AipsIO&, const String& name, uInt nrrow, int option, 00139 const TableLock& lockOptions); 00140 00141 // The destructor flushes (i.e. writes) the table if it is opened 00142 // for output and not marked for delete. 00143 virtual ~RefTable(); 00144 00145 // Return the layout of a table (i.e. description and #rows). 00146 // This function has the advantage that only the minimal amount of 00147 // information required is read from the table, thus it is much 00148 // faster than a normal table open. 00149 // <br> The number of rows is returned. The description of the table 00150 // is stored in desc (its contents will be overwritten). 00151 static void getLayout (TableDesc& desc, AipsIO& ios); 00152 00153 // Try to reopen the table (the underlying one) for read/write access. 00154 // An exception is thrown if the table is not writable. 00155 // Nothing is done if the table is already open for read/write. 00156 virtual void reopenRW(); 00157 00158 // Is the table stored in big or little endian format? 00159 virtual Bool asBigEndian() const; 00160 00161 // Is the table in use (i.e. open) in another process? 00162 // It always returns False. 00163 virtual Bool isMultiUsed (Bool checkSubTable) const; 00164 00165 // Get the locking info. 00166 virtual const TableLock& lockOptions() const; 00167 00168 // Merge the given lock info with the existing one. 00169 virtual void mergeLock (const TableLock& lockOptions); 00170 00171 // Has this process the read or write lock, thus can the table 00172 // be read or written safely? 00173 virtual Bool hasLock (FileLocker::LockType) const; 00174 00175 // Try to lock the table for read or write access. 00176 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00177 00178 // Unlock the table. This will also synchronize the table data, 00179 // thus force the data to be written to disk. 00180 virtual void unlock(); 00181 00182 // Flush the table, i.e. write it to disk. 00183 // Nothing will be done if the table is not writable. 00184 // A flush can be executed at any time. 00185 // When a table is marked for delete, the destructor will remove 00186 // files written by intermediate flushes. 00187 // Note that if necessary the destructor will do an implicit flush, 00188 // unless it is executed due to an exception. 00189 virtual void flush (Bool fsync, Bool recursive); 00190 00191 // Resync the Table object with the table file. 00192 virtual void resync(); 00193 00194 // Get the modify counter. 00195 virtual uInt getModifyCounter() const; 00196 00197 // Test if the parent table is opened as writable. 00198 virtual Bool isWritable() const; 00199 00200 // Read a reference table from a file. 00201 // The referenced table will also be created (if not stored in the cache). 00202 void getRef (AipsIO&, int option, const TableLock& lockOptions); 00203 00204 // This is doing a shallow copy. 00205 // It gives an error if the RefTable has not been stored yet. 00206 virtual void copy (const String& newName, int tableOption) const; 00207 00208 // Copy the table and all its subtables. 00209 // It copies the contents of each row to get a real copy. 00210 virtual void deepCopy (const String& newName, 00211 const Record& dataManagerInfo, 00212 int tableOption, Bool, int endianFormat, 00213 Bool noRows) const; 00214 00215 // It returns the type of the parent table. 00216 virtual int tableType() const; 00217 00218 // Get the actual table description. 00219 virtual TableDesc actualTableDesc() const; 00220 00221 // Get the data manager info. 00222 virtual Record dataManagerInfo() const; 00223 00224 // Get readonly access to the table keyword set. 00225 virtual TableRecord& keywordSet(); 00226 00227 // Get read/write access to the table keyword set. 00228 // This requires that the table is locked (or it gets locked 00229 // when using AutoLocking mode). 00230 virtual TableRecord& rwKeywordSet(); 00231 00232 // Get a column object using its index. 00233 virtual BaseColumn* getColumn (uInt columnIndex) const; 00234 00235 // Get a column object using its name. 00236 virtual BaseColumn* getColumn (const String& columnName) const; 00237 00238 // Test if it is possible to remove a row from this table. 00239 virtual Bool canRemoveRow() const; 00240 00241 // Remove the given row. 00242 virtual void removeRow (uInt rownr); 00243 00244 // Test if columns can be removed (yes). 00245 virtual Bool canRemoveColumn (const Vector<String>& columnNames) const; 00246 00247 // Remove columns. 00248 virtual void removeColumn (const Vector<String>& columnNames); 00249 00250 // Test if a column can be renamed (yes). 00251 virtual Bool canRenameColumn (const String& columnName) const; 00252 00253 // Rename a column. 00254 virtual void renameColumn (const String& newName, const String& oldName); 00255 00256 // Find the data manager with the given name. 00257 virtual DataManager* findDataManager (const String& dataManagerName) const; 00258 00259 // Get a vector of row numbers. 00260 virtual Vector<uInt> rowNumbers() const; 00261 00262 // Get parent of this table. 00263 virtual BaseTable* root(); 00264 00265 // Get rownr in root table. 00266 // This converts the given row number to the row number in the root table. 00267 uInt rootRownr (uInt rownr) const; 00268 00269 // Get vector of rownrs in root table. 00270 // This converts the given row numbers to row numbers in the root table. 00271 Vector<uInt> rootRownr (const Vector<uInt>& rownrs) const; 00272 00273 // Tell if the table is in row order. 00274 virtual Bool rowOrder() const; 00275 00276 // Get row number vector. 00277 // This is used by the BaseTable logic and sort routines. 00278 virtual Vector<uInt>* rowStorage(); 00279 00280 // Add a rownr to reference table. 00281 void addRownr (uInt rownr); 00282 00283 // Set the exact number of rows in the table. 00284 // An exception is thrown if more than current nrrow. 00285 void setNrrow (uInt nrrow); 00286 00287 // Adjust the row numbers to be the actual row numbers in the 00288 // root table. This is, for instance, used when a RefTable is sorted. 00289 // Optionally it also determines if the resulting rows are in row order. 00290 virtual Bool adjustRownrs (uInt nrrow, Vector<uInt>& rownrs, 00291 Bool determineOrder) const; 00292 00293 // And, or, subtract or xor the row numbers of 2 tables. 00294 void refAnd (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00295 void refOr (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00296 void refSub (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00297 void refXor (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00298 void refNot (uInt nr1, const uInt* rows1, uInt nrmain); 00299 00300 // Get the internal pointer in a rowStorage vector. 00301 // It checks whether no copy is made of the data. 00302 static uInt* getStorage (Vector<uInt>& rownrs); 00303 00304 private: 00305 BaseTable* baseTabPtr_p; //# pointer to parent table 00306 Bool rowOrd_p; //# True = table is in row order 00307 Vector<uInt> rowStorage_p; //# row numbers in parent table 00308 uInt* rows_p; //# Pointer to rowStorage_p 00309 SimpleOrderedMap<String,String> nameMap_p; //# map to column name in parent 00310 SimpleOrderedMap<String,RefColumn*> colMap_p; //# map name to column 00311 Bool changed_p; //# True = changed since last write 00312 00313 // Copy constructor is forbidden, because copying a table requires 00314 // some more knowledge (like table name of result). 00315 // Declaring it private, makes it unusable. 00316 RefTable (const RefTable&); 00317 00318 // Assignment is forbidden, because copying a table requires 00319 // some more knowledge (like table name of result). 00320 // Declaring it private, makes it unusable. 00321 RefTable& operator= (const RefTable&); 00322 00323 static void makeDesc (TableDesc& desc, const TableDesc& rootDesc, 00324 SimpleOrderedMap<String,String>& nameMap, 00325 Vector<String>& names); 00326 00327 // Setup the main parts of the object. 00328 // <br>First create the name map (mapping column name in RefTable to 00329 // the column in the original table). 00330 // If the BaseTable is a RefTable, use its name map. 00331 // Otherwise create the initial name map from the table description. 00332 // A rename might change the map. 00333 // <br>Create the RefColumn objects. 00334 // <br>Create the initial TableInfo as a copy of the original BaseTable. 00335 void setup (BaseTable* btp, const Vector<String>& columnNames); 00336 00337 // Create the RefColumn objects for all columns in the description. 00338 void makeRefCol(); 00339 00340 // Write a reference table. 00341 void writeRefTable (Bool fsync); 00342 }; 00343 00344 00345 00346 inline uInt RefTable::rootRownr (uInt rnr) const 00347 { return rows_p[rnr]; } 00348 00349 00350 00351 00352 } //# NAMESPACE CASA - END 00353 00354 #endif
1.5.1