casa
$Rev:20696$
|
00001 //# ConcatTable.h: Class to view a concatenation of tables as a single table 00002 //# Copyright (C) 2008 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: ConcatTable.h 21254 2012-07-18 06:20:53Z gervandiepen $ 00027 00028 #ifndef TABLES_CONCATTABLE_H 00029 #define TABLES_CONCATTABLE_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <tables/Tables/BaseTable.h> 00035 #include <tables/Tables/ConcatRows.h> 00036 #include <tables/Tables/TableRecord.h> 00037 #include <tables/Tables/Table.h> 00038 #include <casa/BasicSL/String.h> 00039 #include <casa/Arrays/Vector.h> 00040 #include <casa/Containers/SimOrdMap.h> 00041 00042 namespace casa { //# NAMESPACE CASA - BEGIN 00043 00044 //# Forward Declarations 00045 class TSMOption; 00046 class ConcatColumn; 00047 class AipsIO; 00048 00049 00050 // <summary> 00051 // Class to view a concatenation of tables as a single table. 00052 // </summary> 00053 00054 // <use visibility=local> 00055 00056 // <reviewed reviewer="UNKNOWN" date="" tests=""> 00057 // </reviewed> 00058 00059 // <prerequisite> 00060 //# Classes you should understand before using this one. 00061 // <li> BaseTable 00062 // <li> ConcatColumn 00063 // </prerequisite> 00064 00065 // <etymology> 00066 // ConcatTable represents the concatenation of one or more tables. 00067 // </etymology> 00068 00069 // <synopsis> 00070 // ConcatTable is used to virtually concatenate one or more tables. 00071 // Those tables must have the same description. 00072 // 00073 // It acts to the user as a normal table. All gets and puts are 00074 // handled by ConcatColumn which directs them to the referenced columns 00075 // while (if needed) converting the given row number to the row number 00076 // in the referenced tables. For that purpose ConcatTable keeps the 00077 // number of rows in the referenced tables. 00078 // <note>Currently it cannot handle changes in the number of rows in the 00079 // underlying tables. </note> 00080 // 00081 // It is possible to specify the keyword names of the subtables that have 00082 // to be concatenated as well. The other subtables are assumed to be 00083 // identical for all tables, so only the subtable of the first table is used. 00084 // 00085 // The ConcatTable maintains its own keyword set, which is initially a copy 00086 // of the keyword set of the first table. It replaces the keywords of the 00087 // subtables to be concatenated. 00088 // The keyword set is not persistent. One can add or change keywords, but 00089 // these changes are not kept when the ConcatTable object is made persistent. 00090 // </synopsis> 00091 00092 // <motivation> 00093 // Sometimes a very large MeasurementSet is split into multiple smaller ones 00094 // using the time axis. Using ConcatTable they can still b viewed as a 00095 // single MS. The SYSCAL subtable is split in time as well, thus it has 00096 // to be possible to concatenate that one as well. 00097 // <note>An MS split in subband could be concatenated as well provided that 00098 // at least the first part contains the full SPECTRAL_WINDOW subtable and 00099 // that unique SPWids are used. 00100 // </note> 00101 // </motivation> 00102 00103 // <todo asof="$DATE:$"> 00104 //# A List of bugs, limitations, extensions or planned refinements. 00105 // <li> Maybe not allocating the row number vector for a projection. 00106 // This saves space and time, but each rownr conversion will 00107 // take a bit more time because it has to test if there is a vector. 00108 // <li> Maybe maintain a Vector<String> telling on which columns 00109 // the table is ordered. This may speed up selection, but 00110 // it is hard to check if the order is changed by a put. 00111 // <li> Allow to remove a row or column from the ConcatTable 00112 // <li> Allow to rename a column in the ConcatTable 00113 // <li> Maybe implement doSort one time for a more efficient sort. 00114 // (now everything is handled by BaseTable). 00115 // </todo> 00116 00117 00118 class ConcatTable : public BaseTable 00119 { 00120 public: 00121 00122 // Create a virtual table as the concatenation of the given tables. 00123 // It checks if the table descriptions of the tables are the same. 00124 // Subtables with the given names will be concatenated as well. 00125 // It is assumed that the other subtables are the same for all tables, 00126 // so the ones of the first table are used. 00127 // <br>The option can be Table::Old or Table::Update. 00128 // <br>If a non-empty subdirectory name is given, the tables will 00129 // be moved to that subdirectory when the concatenated table is written 00130 // (by writeConcatTable). 00131 // <group> 00132 ConcatTable (const Block<BaseTable*>& tables, 00133 const Block<String>& subTables, 00134 const String& subDirName); 00135 ConcatTable (const Block<String>& tableNames, 00136 const Block<String>& subTables, 00137 const String& subDirName, 00138 int option, 00139 const TableLock& lockOptions, 00140 const TSMOption& tsmOption); 00141 // </group> 00142 00143 // Create a concat table out of a file (written by writeConcatTable). 00144 // The referenced tables will also be opened (if not stored in the cache). 00145 ConcatTable (AipsIO&, const String& name, uInt nrrow, int option, 00146 const TableLock& lockOptions, const TSMOption& tsmOption); 00147 00148 // The destructor flushes (i.e. writes) the table if it is opened 00149 // for output and not marked for delete. 00150 virtual ~ConcatTable(); 00151 00152 // Get the names of the tables this table consists of. 00153 virtual void getPartNames (Block<String>& names, Bool recursive) const; 00154 00155 // Return the layout of a table (i.e. description and #rows). 00156 // This function has the advantage that only the minimal amount of 00157 // information required is read from the table, thus it is much 00158 // faster than a normal table open. 00159 // <br> The number of rows is returned. The description of the table 00160 // is stored in desc (its contents will be overwritten). 00161 static void getLayout (TableDesc& desc, AipsIO& ios); 00162 00163 // Try to reopen the table (the underlying ones) for read/write access. 00164 // An exception is thrown if the table is not writable. 00165 // Nothing is done if the table is already open for read/write. 00166 virtual void reopenRW(); 00167 00168 // Is the table stored in big or little endian format? 00169 // It returns the endianness of the first underlying table. 00170 virtual Bool asBigEndian() const; 00171 00172 // Is the table in use (i.e. open) in another process? 00173 // It always returns False. 00174 virtual Bool isMultiUsed (Bool checkSubTable) const; 00175 00176 // Get the locking info. 00177 // All underlying tables have the same lock option. 00178 virtual const TableLock& lockOptions() const; 00179 00180 // Merge the given lock info with the existing one. 00181 virtual void mergeLock (const TableLock& lockOptions); 00182 00183 // Has this process the read or write lock, thus can the table 00184 // be read or written safely? 00185 virtual Bool hasLock (FileLocker::LockType) const; 00186 00187 // Try to lock the table for read or write access. 00188 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00189 00190 // Unlock the table. This will also synchronize the table data, 00191 // thus force the data to be written to disk. 00192 virtual void unlock(); 00193 00194 // Flush the table, i.e. write it to disk. 00195 // Nothing will be done if the table is not writable. 00196 // A flush can be executed at any time. 00197 // When a table is marked for delete, the destructor will remove 00198 // files written by intermediate flushes. 00199 // Note that if necessary the destructor will do an implicit flush, 00200 // unless it is executed due to an exception. 00201 virtual void flush (Bool fsync, Bool recursive); 00202 00203 // Resync the Table object with the table files. 00204 virtual void resync(); 00205 00206 // Get the modify counter. 00207 virtual uInt getModifyCounter() const; 00208 00209 // Test if all underlying tables are opened as writable. 00210 virtual Bool isWritable() const; 00211 00212 // Read a concat table from a file. 00213 // The underlying tables will be opened (if not stored in the cache). 00214 void getConcat (AipsIO&, int option, const TableLock& lockOptions, 00215 const TSMOption& tsmOption); 00216 00217 // This is doing a shallow copy. 00218 // It gives an error if the ConcatTable has not been stored yet. 00219 virtual void copy (const String& newName, int tableOption) const; 00220 00221 // Copy the table and all its subtables. 00222 // It copies the contents of each row to get a real copy. 00223 virtual void deepCopy (const String& newName, 00224 const Record& dataManagerInfo, 00225 int tableOption, Bool, int endianFormat, 00226 Bool noRows) const; 00227 00228 // It returns the type of the parent table. 00229 virtual int tableType() const; 00230 00231 // Get the actual table description. 00232 virtual TableDesc actualTableDesc() const; 00233 00234 // Get the data manager info (of the first underlying table). 00235 virtual Record dataManagerInfo() const; 00236 00237 // Get readonly access to the table keyword set. 00238 virtual TableRecord& keywordSet(); 00239 00240 // Get read/write access to the table keyword set. 00241 // This requires that the table is locked (or it gets locked 00242 // when using AutoLocking mode). 00243 virtual TableRecord& rwKeywordSet(); 00244 00245 // Get a column object using its index. 00246 virtual BaseColumn* getColumn (uInt columnIndex) const; 00247 00248 // Get a column object using its name. 00249 virtual BaseColumn* getColumn (const String& columnName) const; 00250 00251 // Test if it is possible to remove a row from this table (no). 00252 virtual Bool canRemoveRow() const; 00253 00254 // Remove the given row. 00255 virtual void removeRow (uInt rownr); 00256 00257 // Test if columns can be removed (no). 00258 virtual Bool canRemoveColumn (const Vector<String>& columnNames) const; 00259 00260 // Add one or more columns to the table. 00261 // The column is added to the parent tables if told so and if not existing. 00262 // <group> 00263 virtual void addColumn (const ColumnDesc& columnDesc, 00264 Bool addToParent); 00265 virtual void addColumn (const ColumnDesc& columnDesc, 00266 const String& dataManager, Bool byName, 00267 Bool addToParent); 00268 virtual void addColumn (const ColumnDesc& columnDesc, 00269 const DataManager& dataManager, 00270 Bool addToParent); 00271 virtual void addColumn (const TableDesc& tableDesc, 00272 const DataManager& dataManager, 00273 Bool addToParent); 00274 // </group> 00275 00276 // Remove a column. 00277 virtual void removeColumn (const Vector<String>& columnNames); 00278 00279 // Test if a column can be renamed (no). 00280 virtual Bool canRenameColumn (const String& columnName) const; 00281 00282 // Rename a column. 00283 virtual void renameColumn (const String& newName, const String& oldName); 00284 00285 // Rename a hypercolumn. 00286 virtual void renameHypercolumn (const String& newName, 00287 const String& oldName); 00288 00289 // Find the data manager with the given name or for the given column. 00290 virtual DataManager* findDataManager (const String& name, 00291 Bool byColumn) const; 00292 00293 // Get the rows object. 00294 const ConcatRows& rows() const 00295 { return rows_p; } 00296 00297 // Get the column objects in the referenced tables. 00298 Block<BaseColumn*> getRefColumns (const String& columnName); 00299 00300 // Create a (temporary) Table object from it. 00301 Table asTable() 00302 { return Table (this, False); } 00303 00304 private: 00305 // Copy constructor is forbidden, because copying a table requires 00306 // some more knowledge (like table name of result). 00307 // Declaring it private, makes it unusable. 00308 ConcatTable (const ConcatTable&); 00309 00310 // Assignment is forbidden, because copying a table requires 00311 // some more knowledge (like table name of result). 00312 // Declaring it private, makes it unusable. 00313 ConcatTable& operator= (const ConcatTable&); 00314 00315 // Show the extra table structure info (names of used tables). 00316 void showStructureExtra (std::ostream&) const; 00317 00318 // Open all tables in the required way. 00319 void openTables (const Block<String>& tableNames, int option, 00320 const TableLock& lockOptions, const TSMOption& tsmOption); 00321 00322 // Initialize. 00323 // It checks if the descriptions of all tables are equal. 00324 // It creates the keyword setfor which it concatenates subtables as needed. 00325 void initialize(); 00326 00327 // Setup the main parts of the object. 00328 // <br>First create the name map (mapping column name in ConcatTable to 00329 // the column in the original table). 00330 // If the BaseTable is a ConcatTable, 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 ConcatColumn 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 // Add lines containing the concatenated tables to the info. 00338 void addInfo(); 00339 00340 // Create the ConcatColumn objects for all columns in the description. 00341 void makeConcatCol(); 00342 00343 // Handle the subtales that have to be concatenated. 00344 void handleSubTables(); 00345 00346 // Write a reference table. 00347 void writeConcatTable (Bool fsync); 00348 00349 // Check if the column can be added, thus does not exist yet. 00350 void checkAddColumn (const String& name, Bool addToParent); 00351 00352 //# Data members 00353 Block<String> subTableNames_p; 00354 String subDirName_p; 00355 Block<BaseTable*> baseTabPtr_p; //# pointers to parent tables 00356 SimpleOrderedMap<String,ConcatColumn*> colMap_p; //# map name to column 00357 TableRecord keywordSet_p; 00358 Bool changed_p; //# True = changed since last write 00359 ConcatRows rows_p; 00360 }; 00361 00362 00363 } //# NAMESPACE CASA - END 00364 00365 #endif