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 <casacore/casa/aips.h> 00034 #include <casacore/tables/Tables/BaseTable.h> 00035 #include <casacore/casa/BasicSL/String.h> 00036 #include <casacore/casa/Arrays/Vector.h> 00037 #include <casacore/casa/Containers/SimOrdMap.h> 00038 00039 namespace casacore { //# NAMESPACE CASACORE - 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 // Get the storage option used for the table. 00163 virtual const StorageOption& storageOption() const; 00164 00165 // Is the table in use (i.e. open) in another process? 00166 // It always returns False. 00167 virtual Bool isMultiUsed (Bool checkSubTable) const; 00168 00169 // Get the locking info. 00170 virtual const TableLock& lockOptions() const; 00171 00172 // Merge the given lock info with the existing one. 00173 virtual void mergeLock (const TableLock& lockOptions); 00174 00175 // Has this process the read or write lock, thus can the table 00176 // be read or written safely? 00177 virtual Bool hasLock (FileLocker::LockType) const; 00178 00179 // Try to lock the table for read or write access. 00180 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00181 00182 // Unlock the table. This will also synchronize the table data, 00183 // thus force the data to be written to disk. 00184 virtual void unlock(); 00185 00186 // Flush the table, i.e. write it to disk. 00187 // Nothing will be done if the table is not writable. 00188 // A flush can be executed at any time. 00189 // When a table is marked for delete, the destructor will remove 00190 // files written by intermediate flushes. 00191 // Note that if necessary the destructor will do an implicit flush, 00192 // unless it is executed due to an exception. 00193 virtual void flush (Bool fsync, Bool recursive); 00194 00195 // Resync the Table object with the table file. 00196 virtual void resync(); 00197 00198 // Get the modify counter. 00199 virtual uInt getModifyCounter() const; 00200 00201 // Test if the parent table is opened as writable. 00202 virtual Bool isWritable() const; 00203 00204 // Read a reference table from a file. 00205 // The referenced table will also be created (if not stored in the cache). 00206 void getRef (AipsIO&, int option, const TableLock& lockOptions, 00207 const TSMOption& tsmOption); 00208 00209 // This is doing a shallow copy. 00210 // It gives an error if the RefTable has not been stored yet. 00211 virtual void copy (const String& newName, int tableOption) const; 00212 00213 // Copy the table and all its subtables. 00214 // It copies the contents of each row to get a real copy. 00215 virtual void deepCopy (const String& newName, 00216 const Record& dataManagerInfo, 00217 const StorageOption&, 00218 int tableOption, Bool, int endianFormat, 00219 Bool noRows) const; 00220 00221 // It returns the type of the parent table. 00222 virtual int tableType() const; 00223 00224 // Get the actual table description. 00225 virtual TableDesc actualTableDesc() const; 00226 00227 // Get the data manager info. 00228 virtual Record dataManagerInfo() const; 00229 00230 // Get readonly access to the table keyword set. 00231 virtual TableRecord& keywordSet(); 00232 00233 // Get read/write access to the table keyword set. 00234 // This requires that the table is locked (or it gets locked 00235 // when using AutoLocking mode). 00236 virtual TableRecord& rwKeywordSet(); 00237 00238 // Get a column object using its index. 00239 virtual BaseColumn* getColumn (uInt columnIndex) const; 00240 00241 // Get a column object using its name. 00242 virtual BaseColumn* getColumn (const String& columnName) const; 00243 00244 // Test if it is possible to remove a row from this table. 00245 virtual Bool canRemoveRow() const; 00246 00247 // Remove the given row. 00248 virtual void removeRow (uInt rownr); 00249 00250 // Add one or more columns to the table. 00251 // The column is added to the parent table if told so and if not existing. 00252 // <group> 00253 virtual void addColumn (const ColumnDesc& columnDesc, 00254 Bool addToParent); 00255 virtual void addColumn (const ColumnDesc& columnDesc, 00256 const String& dataManager, Bool byName, 00257 Bool addToParent); 00258 virtual void addColumn (const ColumnDesc& columnDesc, 00259 const DataManager& dataManager, 00260 Bool addToParent); 00261 virtual void addColumn (const TableDesc& tableDesc, 00262 const DataManager& dataManager, 00263 Bool addToParent); 00264 // </group> 00265 00266 // Test if columns can be removed (yes). 00267 virtual Bool canRemoveColumn (const Vector<String>& columnNames) const; 00268 00269 // Remove columns. 00270 virtual void removeColumn (const Vector<String>& columnNames); 00271 00272 // Test if a column can be renamed (yes). 00273 virtual Bool canRenameColumn (const String& columnName) const; 00274 00275 // Rename a column. 00276 virtual void renameColumn (const String& newName, const String& oldName); 00277 00278 // Rename a hypercolumn. 00279 virtual void renameHypercolumn (const String& newName, 00280 const String& oldName); 00281 00282 // Find the data manager with the given name or for the given column. 00283 virtual DataManager* findDataManager (const String& name, 00284 Bool byColumn) const; 00285 00286 // Get a vector of row numbers. 00287 virtual Vector<uInt> rowNumbers() const; 00288 00289 // Get parent of this table. 00290 virtual BaseTable* root(); 00291 00292 // Get rownr in root table. 00293 // This converts the given row number to the row number in the root table. 00294 uInt rootRownr (uInt rownr) const; 00295 00296 // Get vector of rownrs in root table. 00297 // This converts the given row numbers to row numbers in the root table. 00298 Vector<uInt> rootRownr (const Vector<uInt>& rownrs) const; 00299 00300 // Tell if the table is in row order. 00301 virtual Bool rowOrder() const; 00302 00303 // Get row number vector. 00304 // This is used by the BaseTable logic and sort routines. 00305 virtual Vector<uInt>* rowStorage(); 00306 00307 // Add a rownr to reference table. 00308 void addRownr (uInt rownr); 00309 00310 // Set the exact number of rows in the table. 00311 // An exception is thrown if more than current nrrow. 00312 void setNrrow (uInt nrrow); 00313 00314 // Adjust the row numbers to be the actual row numbers in the 00315 // root table. This is, for instance, used when a RefTable is sorted. 00316 // Optionally it also determines if the resulting rows are in row order. 00317 virtual Bool adjustRownrs (uInt nrrow, Vector<uInt>& rownrs, 00318 Bool determineOrder) const; 00319 00320 // And, or, subtract or xor the row numbers of 2 tables. 00321 void refAnd (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00322 void refOr (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00323 void refSub (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00324 void refXor (uInt nr1, const uInt* rows1, uInt nr2, const uInt* rows2); 00325 void refNot (uInt nr1, const uInt* rows1, uInt nrmain); 00326 00327 // Get the internal pointer in a rowStorage vector. 00328 // It checks whether no copy is made of the data. 00329 static uInt* getStorage (Vector<uInt>& rownrs); 00330 00331 private: 00332 BaseTable* baseTabPtr_p; //# pointer to parent table 00333 Bool rowOrd_p; //# True = table is in row order 00334 Vector<uInt> rowStorage_p; //# row numbers in parent table 00335 uInt* rows_p; //# Pointer to rowStorage_p 00336 SimpleOrderedMap<String,String> nameMap_p; //# map to column name in parent 00337 SimpleOrderedMap<String,RefColumn*> colMap_p; //# map name to column 00338 Bool changed_p; //# True = changed since last write 00339 00340 // Copy constructor is forbidden, because copying a table requires 00341 // some more knowledge (like table name of result). 00342 // Declaring it private, makes it unusable. 00343 RefTable (const RefTable&); 00344 00345 // Assignment is forbidden, because copying a table requires 00346 // some more knowledge (like table name of result). 00347 // Declaring it private, makes it unusable. 00348 RefTable& operator= (const RefTable&); 00349 00350 // Get the names of the tables this table consists of. 00351 virtual void getPartNames (Block<String>& names, Bool recursive) const; 00352 00353 // Show the extra table structure info (name of root table). 00354 void showStructureExtra (std::ostream&) const; 00355 00356 // Make a table description for the given columns. 00357 static void makeDesc (TableDesc& desc, const TableDesc& rootDesc, 00358 SimpleOrderedMap<String,String>& nameMap, 00359 Vector<String>& names); 00360 00361 // Setup the main parts of the object. 00362 // <br>First create the name map (mapping column name in RefTable to 00363 // the column in the original table). 00364 // If the BaseTable is a RefTable, use its name map. 00365 // Otherwise create the initial name map from the table description. 00366 // A rename might change the map. 00367 // <br>Create the RefColumn objects. 00368 // <br>Create the initial TableInfo as a copy of the original BaseTable. 00369 void setup (BaseTable* btp, const Vector<String>& columnNames); 00370 00371 // Create the RefColumn objects for all columns in the description. 00372 void makeRefCol(); 00373 00374 // Write a reference table. 00375 void writeRefTable (Bool fsync); 00376 00377 // Copy a RefTable that is not persistent. It requires some special logic. 00378 void copyRefTable (const String& newName, int tableOption); 00379 00380 // Check if a column can be added. Return True if it can and must be 00381 // added to the parent table first. 00382 Bool checkAddColumn (const String& name, Bool addToParent); 00383 00384 // Add a column. 00385 void addRefCol (const ColumnDesc& cd); 00386 // Add multiple columns. 00387 void addRefCol (const TableDesc& tdesc); 00388 }; 00389 00390 00391 00392 inline uInt RefTable::rootRownr (uInt rnr) const 00393 { return rows_p[rnr]; } 00394 00395 00396 00397 00398 } //# NAMESPACE CASACORE - END 00399 00400 #endif