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