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$ 00027 00028 #ifndef TABLES_CONCATTABLE_H 00029 #define TABLES_CONCATTABLE_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/tables/Tables/BaseTable.h> 00035 #include <casacore/tables/Tables/ConcatRows.h> 00036 #include <casacore/tables/Tables/TableRecord.h> 00037 #include <casacore/tables/Tables/Table.h> 00038 #include <casacore/casa/BasicSL/String.h> 00039 #include <casacore/casa/Arrays/Vector.h> 00040 #include <casacore/casa/Containers/SimOrdMap.h> 00041 00042 namespace casacore { //# NAMESPACE CASACORE - 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 // Get the storage option used for the table. 00173 // It returns the storage option of the first underlying table. 00174 virtual const StorageOption& storageOption() const; 00175 00176 // Is the table in use (i.e. open) in another process? 00177 // It always returns False. 00178 virtual Bool isMultiUsed (Bool checkSubTable) const; 00179 00180 // Get the locking info. 00181 // All underlying tables have the same lock option. 00182 virtual const TableLock& lockOptions() const; 00183 00184 // Merge the given lock info with the existing one. 00185 virtual void mergeLock (const TableLock& lockOptions); 00186 00187 // Has this process the read or write lock, thus can the table 00188 // be read or written safely? 00189 virtual Bool hasLock (FileLocker::LockType) const; 00190 00191 // Try to lock the table for read or write access. 00192 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00193 00194 // Unlock the table. This will also synchronize the table data, 00195 // thus force the data to be written to disk. 00196 virtual void unlock(); 00197 00198 // Flush the table, i.e. write it to disk. 00199 // Nothing will be done if the table is not writable. 00200 // A flush can be executed at any time. 00201 // When a table is marked for delete, the destructor will remove 00202 // files written by intermediate flushes. 00203 // Note that if necessary the destructor will do an implicit flush, 00204 // unless it is executed due to an exception. 00205 virtual void flush (Bool fsync, Bool recursive); 00206 00207 // Resync the Table object with the table files. 00208 virtual void resync(); 00209 00210 // Get the modify counter. 00211 virtual uInt getModifyCounter() const; 00212 00213 // Test if all underlying tables are opened as writable. 00214 virtual Bool isWritable() const; 00215 00216 // Read a concat table from a file. 00217 // The underlying tables will be opened (if not stored in the cache). 00218 void getConcat (AipsIO&, int option, const TableLock& lockOptions, 00219 const TSMOption& tsmOption); 00220 00221 // This is doing a shallow copy. 00222 // It gives an error if the ConcatTable has not been stored yet. 00223 virtual void copy (const String& newName, int tableOption) const; 00224 00225 // Copy the table and all its subtables. 00226 // It copies the contents of each row to get a real copy. 00227 virtual void deepCopy (const String& newName, 00228 const Record& dataManagerInfo, 00229 const StorageOption&, 00230 int tableOption, Bool, int endianFormat, 00231 Bool noRows) const; 00232 00233 // It returns the type of the parent table. 00234 virtual int tableType() const; 00235 00236 // Get the actual table description. 00237 virtual TableDesc actualTableDesc() const; 00238 00239 // Get the data manager info (of the first underlying table). 00240 virtual Record dataManagerInfo() const; 00241 00242 // Get readonly access to the table keyword set. 00243 virtual TableRecord& keywordSet(); 00244 00245 // Get read/write access to the table keyword set. 00246 // This requires that the table is locked (or it gets locked 00247 // when using AutoLocking mode). 00248 virtual TableRecord& rwKeywordSet(); 00249 00250 // Get a column object using its index. 00251 virtual BaseColumn* getColumn (uInt columnIndex) const; 00252 00253 // Get a column object using its name. 00254 virtual BaseColumn* getColumn (const String& columnName) const; 00255 00256 // Test if it is possible to remove a row from this table (no). 00257 virtual Bool canRemoveRow() const; 00258 00259 // Remove the given row. 00260 virtual void removeRow (uInt rownr); 00261 00262 // Test if columns can be removed (no). 00263 virtual Bool canRemoveColumn (const Vector<String>& columnNames) const; 00264 00265 // Add one or more columns to the table. 00266 // The column is added to the parent tables if told so and if not existing. 00267 // <group> 00268 virtual void addColumn (const ColumnDesc& columnDesc, 00269 Bool addToParent); 00270 virtual void addColumn (const ColumnDesc& columnDesc, 00271 const String& dataManager, Bool byName, 00272 Bool addToParent); 00273 virtual void addColumn (const ColumnDesc& columnDesc, 00274 const DataManager& dataManager, 00275 Bool addToParent); 00276 virtual void addColumn (const TableDesc& tableDesc, 00277 const DataManager& dataManager, 00278 Bool addToParent); 00279 // </group> 00280 00281 // Remove a column. 00282 virtual void removeColumn (const Vector<String>& columnNames); 00283 00284 // Test if a column can be renamed (no). 00285 virtual Bool canRenameColumn (const String& columnName) const; 00286 00287 // Rename a column. 00288 virtual void renameColumn (const String& newName, const String& oldName); 00289 00290 // Rename a hypercolumn. 00291 virtual void renameHypercolumn (const String& newName, 00292 const String& oldName); 00293 00294 // Find the data manager with the given name or for the given column. 00295 virtual DataManager* findDataManager (const String& name, 00296 Bool byColumn) const; 00297 00298 // Get the rows object. 00299 const ConcatRows& rows() const 00300 { return rows_p; } 00301 00302 // Get the column objects in the referenced tables. 00303 Block<BaseColumn*> getRefColumns (const String& columnName); 00304 00305 // Create a (temporary) Table object from it. 00306 Table asTable() 00307 { return Table (this, False); } 00308 00309 private: 00310 // Copy constructor 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 (const ConcatTable&); 00314 00315 // Assignment is forbidden, because copying a table requires 00316 // some more knowledge (like table name of result). 00317 // Declaring it private, makes it unusable. 00318 ConcatTable& operator= (const ConcatTable&); 00319 00320 // Show the extra table structure info (names of used tables). 00321 void showStructureExtra (std::ostream&) const; 00322 00323 // Open all tables in the required way. 00324 void openTables (const Block<String>& tableNames, int option, 00325 const TableLock& lockOptions, const TSMOption& tsmOption); 00326 00327 // Initialize. 00328 // It checks if the descriptions of all tables are equal. 00329 // It creates the keyword setfor which it concatenates subtables as needed. 00330 void initialize(); 00331 00332 // Setup the main parts of the object. 00333 // <br>First create the name map (mapping column name in ConcatTable to 00334 // the column in the original table). 00335 // If the BaseTable is a ConcatTable, use its name map. 00336 // Otherwise create the initial name map from the table description. 00337 // A rename might change the map. 00338 // <br>Create the ConcatColumn objects. 00339 // <br>Create the initial TableInfo as a copy of the original BaseTable. 00340 void setup (BaseTable* btp, const Vector<String>& columnNames); 00341 00342 // Add lines containing the concatenated tables to the info. 00343 void addInfo(); 00344 00345 // Create the ConcatColumn objects for all columns in the description. 00346 void makeConcatCol(); 00347 00348 // Handle the subtales that have to be concatenated. 00349 void handleSubTables(); 00350 00351 // Write a reference table. 00352 void writeConcatTable (Bool fsync); 00353 00354 // Check if the column can be added, thus does not exist yet. 00355 void checkAddColumn (const String& name, Bool addToParent); 00356 00357 //# Data members 00358 Block<String> subTableNames_p; 00359 String subDirName_p; 00360 Block<BaseTable*> baseTabPtr_p; //# pointers to parent tables 00361 SimpleOrderedMap<String,ConcatColumn*> colMap_p; //# map name to column 00362 TableRecord keywordSet_p; 00363 Bool changed_p; //# True = changed since last write 00364 ConcatRows rows_p; 00365 }; 00366 00367 00368 } //# NAMESPACE CASACORE - END 00369 00370 #endif