casa
$Rev:20696$
|
00001 //# ForwardColRow.h: Virtual Column Engine to forward to other rows/columns 00002 //# Copyright (C) 1995,1996,1997,2001 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: ForwardColRow.h 21051 2011-04-20 11:46:29Z gervandiepen $ 00027 00028 #ifndef TABLES_FORWARDCOLROW_H 00029 #define TABLES_FORWARDCOLROW_H 00030 00031 //# Includes 00032 #include <tables/Tables/ForwardCol.h> 00033 #include <tables/Tables/ScalarColumn.h> 00034 00035 namespace casa { //# NAMESPACE CASA - BEGIN 00036 00037 //# Forward Declarations 00038 class ForwardColumnIndexedRowEngine; 00039 00040 00041 // <summary> 00042 // Virtual column forwarding to another row/column 00043 // </summary> 00044 00045 // <reviewed reviewer="Paul Shannon" date="1995/05/22" tests="tForwardColRow.cc"> 00046 // </reviewed> 00047 00048 // <use visibility=local> 00049 00050 // <prerequisite> 00051 //# Classes you should understand before using this one. 00052 // <li> ForwardColumnIndexedRowEngine 00053 // <li> ForwardColumn 00054 // </prerequisite> 00055 00056 // <etymology> 00057 // ForwardColumnIndexedRow handles the forwarding of the gets and puts 00058 // for an individual row/column on behalf of the virtual column engine 00059 // ForwardColumnIndexedRowEngine. It forwards them to a row/column in 00060 // another table. The row forwarding is done using a special column 00061 // containing row numbers indexing the referenced table. 00062 // </etymology> 00063 00064 // <synopsis> 00065 // ForwardColumnIndexedRow represents a virtual column which forwards the 00066 // gets and puts to a column with the same name in another table. 00067 // It is, in fact, a reference to the other column. 00068 // The row numbers in the column are mapped to row numbers in the referenced 00069 // column using a special column containing the mapping. 00070 // The name of the other table is stored as a keyword in the 00071 // forwarding column. When the referenced column is in its turn a 00072 // ForwardColumn (note: not a ForwardColumnIndexedRow), the table 00073 // mentioned in there will be used. In this way, the length of the 00074 // forwarding chain is kept to a minimum. 00075 // 00076 // An object of this class is created (and deleted) by the virtual column 00077 // engine 00078 // <linkto class="ForwardColumnIndexedRowEngine:description"> 00079 // ForwardColumnIndexedRowEngine</linkto> 00080 // which creates a ForwardColumnIndexedRow object for each column being 00081 // forwarded. 00082 // </synopsis> 00083 00084 00085 class ForwardColumnIndexedRow : public ForwardColumn 00086 { 00087 public: 00088 00089 // Construct it for the given column. 00090 ForwardColumnIndexedRow (ForwardColumnIndexedRowEngine* enginePtr, 00091 const String& columnName, 00092 int dataType, 00093 const String& dataTypeId, 00094 const Table& referencedTable); 00095 00096 // Destructor is mandatory. 00097 ~ForwardColumnIndexedRow(); 00098 00099 // Initialize the object. 00100 // This means binding the column to the column with the same name 00101 // in the original table. 00102 // It checks if the description of both columns is the same. 00103 void prepare (const Table& thisTable); 00104 00105 private: 00106 // Copy constructor is not needed and therefore forbidden 00107 // (so make it private). 00108 ForwardColumnIndexedRow (const ForwardColumnIndexedRow&); 00109 00110 // Assignment is not needed and therefore forbidden (so make it private). 00111 ForwardColumnIndexedRow& operator= (const ForwardColumnIndexedRow&); 00112 00113 // This data manager cannot handle changing array shapes. 00114 Bool canChangeShape() const; 00115 00116 // This data manager cannot do get/putColumn. 00117 Bool canAccessScalarColumn (Bool& reask) const; 00118 00119 // This data manager cannot do get/putColumn. 00120 Bool canAccessArrayColumn (Bool& reask) const; 00121 00122 // This data manager cannot do get/putColumn. 00123 Bool canAccessColumnSlice (Bool& reask) const; 00124 00125 // Set the shape of an (indirect) array in the given row. 00126 // This throws an exception, because putting is not supported. 00127 void setShape (uInt rownr, const IPosition& shape); 00128 00129 // Is the value shape defined in the given row? 00130 Bool isShapeDefined (uInt rownr); 00131 00132 // Get the dimensionality of the item in the given row. 00133 uInt ndim (uInt rownr); 00134 00135 // Get the shape of the item in the given row. 00136 IPosition shape (uInt rownr); 00137 00138 // Get the scalar value with a standard data type in the given row. 00139 // <group> 00140 void getBoolV (uInt rownr, Bool* dataPtr); 00141 void getuCharV (uInt rownr, uChar* dataPtr); 00142 void getShortV (uInt rownr, Short* dataPtr); 00143 void getuShortV (uInt rownr, uShort* dataPtr); 00144 void getIntV (uInt rownr, Int* dataPtr); 00145 void getuIntV (uInt rownr, uInt* dataPtr); 00146 void getfloatV (uInt rownr, float* dataPtr); 00147 void getdoubleV (uInt rownr, double* dataPtr); 00148 void getComplexV (uInt rownr, Complex* dataPtr); 00149 void getDComplexV (uInt rownr, DComplex* dataPtr); 00150 void getStringV (uInt rownr, String* dataPtr); 00151 // </group> 00152 00153 // Get the scalar value with a non-standard data type in the given row. 00154 void getOtherV (uInt rownr, void* dataPtr); 00155 00156 // Put the scalar value with a standard data type into the given row. 00157 // This throws an exception, because putting is not supported. 00158 // <group> 00159 void putBoolV (uInt rownr, const Bool* dataPtr); 00160 void putuCharV (uInt rownr, const uChar* dataPtr); 00161 void putShortV (uInt rownr, const Short* dataPtr); 00162 void putuShortV (uInt rownr, const uShort* dataPtr); 00163 void putIntV (uInt rownr, const Int* dataPtr); 00164 void putuIntV (uInt rownr, const uInt* dataPtr); 00165 void putfloatV (uInt rownr, const float* dataPtr); 00166 void putdoubleV (uInt rownr, const double* dataPtr); 00167 void putComplexV (uInt rownr, const Complex* dataPtr); 00168 void putDComplexV (uInt rownr, const DComplex* dataPtr); 00169 void putStringV (uInt rownr, const String* dataPtr); 00170 // </group> 00171 00172 // Put the scalar value with a non-standard data type into the given row. 00173 // This throws an exception, because putting is not supported. 00174 void putOtherV (uInt rownr, const void* dataPtr); 00175 00176 // Get the array value in the given row. 00177 // The argument dataPtr is in fact a Array<T>*, but a void* 00178 // is needed to be generic. 00179 // The array pointed to by dataPtr has to have the correct shape 00180 // (which is guaranteed by the ArrayColumn get function). 00181 void getArrayV (uInt rownr, void* dataPtr); 00182 00183 // Put the array value into the given row. 00184 // This throws an exception, because putting is not supported. 00185 void putArrayV (uInt rownr, const void* dataPtr); 00186 00187 // Get a section of the array in the given row. 00188 // The argument dataPtr is in fact a Array<T>*, but a void* 00189 // is needed to be generic. 00190 // The array pointed to by dataPtr has to have the correct shape 00191 // (which is guaranteed by the ArrayColumn getSlice function). 00192 void getSliceV (uInt rownr, const Slicer& slicer, void* dataPtr); 00193 00194 // Put into a section of the array in the given row. 00195 // This throws an exception, because putting is not supported. 00196 void putSliceV (uInt rownr, const Slicer& slicer, const void* dataPtr); 00197 00198 // Convert the rownr to the rownr in the underlying table. 00199 uInt convertRownr (uInt rownr); 00200 00201 //# Now define the data members. 00202 ForwardColumnIndexedRowEngine* enginePtr_p; //# pointer to parent engine 00203 }; 00204 00205 00206 00207 00208 // <summary> 00209 // Virtual column engine forwarding to other columns/rows. 00210 // </summary> 00211 00212 // <reviewed reviewer="" date="" tests=""> 00213 // </reviewed> 00214 00215 // <use visibility=export> 00216 00217 // <prerequisite> 00218 //# Classes you should understand before using this one. 00219 // <li> VirtualColumnEngine 00220 // </prerequisite> 00221 00222 // <etymology> 00223 // ForwardColumnIndexedRowEngine is a virtual column engine which 00224 // forwards the gets and puts of columns to corresponding columns 00225 // in another table. Furthermore it maps the row number by indexing 00226 // the row number in the referenced table. 00227 // </etymology> 00228 00229 // <synopsis> 00230 // ForwardColumnIndexedRowEngine is a data manager which forwards 00231 // the gets and puts of columns to columns with the same names in 00232 // another table. In that sense it is the same as the virtual column engine 00233 // <linkto class="ForwardColumnEngine:description"> 00234 // ForwardColumnEngine</linkto>. 00235 // However, it also forwards the row number. That is, it uses a column 00236 // containing row numbers to index the correct row in the referenced table. 00237 // The name of this column and the name of the referenced table have to 00238 // be given when constructing the engine. 00239 // 00240 // For example:<br> 00241 // Table TABA contains columns A, B and C and consists of N rows. 00242 // Table TABF uses ForwardColumnIndexedRowEngine to forward its columns 00243 // A, B and C to the corresponding columns in TABA. Furthermore it 00244 // contains a column ROW containing row numbers in TABA. This column is 00245 // the mapping of row numbers in TABF to rows in TABA. E.g. if ROW has 00246 // the value 25 in row 10, row 10 of TABF is forwarded to row 25 in TABA. 00247 // 00248 // Actually, puts are not possible. When multiple rows map to the same row 00249 // in the referenced table, putting a value in one row would also change 00250 // the value in another row referencing the same underlying row. This 00251 // could result in unexpected behaviour. 00252 // 00253 // The engine consists of a set of 00254 // <linkto class="ForwardColumnIndexedRow:description"> 00255 // ForwardColumnIndexedRow</linkto> 00256 // objects, which handle the actual gets. 00257 // </synopsis> 00258 00259 // <motivation> 00260 // In some ways it overlaps the functionality of the storage manager 00261 // StManMirAIO. They both allow to have the same value used by multiple 00262 // rows. However, StManMirAIO only allows that for consecutive rows, 00263 // while this engine allows it for any row. On the other side, 00264 // StManMirAIO is faster. 00265 // </motivation> 00266 00267 // <example> 00268 // <srcblock> 00269 // // The original table. 00270 // Table tab("someTable"); 00271 // // Create another table with the same description. 00272 // SetupNewTable newtab("tForwardColRow.data", tab.tableDesc(), Table::New); 00273 // // Create an engine which forwards to the original table and uses 00274 // // column rowColumn to get the row number in the referenced table. 00275 // // Bind all columns in the new table to the forwarding engine. 00276 // ForwardColumnIndexedRowEngine fce(tab, "rowColumn"); 00277 // newtab.bindAll (fce); 00278 // // Create the new table. 00279 // // Every get and put on this table is forwarded to the original table. 00280 // // NB. Puts cannot be done here, because the original table was 00281 // // opened as readonly. 00282 // // Of course, some columns could have been bound to another 00283 // // data manager (storage manager, calibration engine, ...). 00284 // Table forwTab(newtab); 00285 // </srcblock> 00286 // </example> 00287 00288 class ForwardColumnIndexedRowEngine : public ForwardColumnEngine 00289 { 00290 public: 00291 00292 // The default constructor is required for reconstruction of the 00293 // engine when a table is read back. 00294 ForwardColumnIndexedRowEngine (const String& dataManagerName, 00295 const Record& spec); 00296 00297 // Create the engine. 00298 // The columns using this engine will reference the given table. 00299 // The column with the given name contains the row number mapping, 00300 // i.e. a row number in a get or put is converted to a row number 00301 // in the referenced table using the value in this column. 00302 // The data manager gets the given name. 00303 ForwardColumnIndexedRowEngine (const Table& referencedTable, 00304 const String& rowColumnName, 00305 const String& dataManagerName); 00306 00307 // Create the engine. 00308 // The columns using this engine will reference the given table. 00309 // The column with the given name contains the row number mapping, 00310 // i.e. a row number in a get or put is converted to a row number 00311 // in the referenced table using the value in this column. 00312 // The data manager has no name. 00313 ForwardColumnIndexedRowEngine (const Table& referencedTable, 00314 const String& rowColumnName); 00315 00316 // Destructor is mandatory. 00317 ~ForwardColumnIndexedRowEngine(); 00318 00319 // Clone the engine object. 00320 DataManager* clone() const; 00321 00322 // Return the type name of the engine 00323 // (i.e. its class name ForwardColumnIndexedRowEngine). 00324 String dataManagerType() const; 00325 00326 // Record a record containing data manager specifications. 00327 virtual Record dataManagerSpec() const; 00328 00329 // Return the name of the class. 00330 static String className(); 00331 00332 // Register the class name and the static makeObject "constructor". 00333 // This will make the engine known to the table system. 00334 static void registerClass(); 00335 00336 private: 00337 // The copy constructor is forbidden (so it is private). 00338 ForwardColumnIndexedRowEngine (const ForwardColumnIndexedRowEngine&); 00339 00340 // Assignment is forbidden (so it is private). 00341 ForwardColumnIndexedRowEngine& operator= 00342 (const ForwardColumnIndexedRowEngine&); 00343 00344 // Create the column object for the scalar column in this engine. 00345 DataManagerColumn* makeScalarColumn (const String& columnName, 00346 int dataType, 00347 const String& dataTypeId); 00348 00349 // Create the column object for the indirect array column in this engine. 00350 DataManagerColumn* makeIndArrColumn (const String& columnName, 00351 int dataType, 00352 const String& dataTypeId); 00353 00354 // Initialize the object for a new table. 00355 // It defines the column keywords containing the name of the 00356 // original table, which can be the parent of the referenced table. 00357 // It also defines a keyword containing the row column name. 00358 void create (uInt initialNrrow); 00359 00360 // Initialize the engine. 00361 // It gets the name of the original table(s) from the column keywords, 00362 // opens those tables and attaches the ForwardColumnIndexedRow objects 00363 // to the columns in those tables. 00364 void prepare(); 00365 00366 // Reopen the engine for read/write access. 00367 // This cannot be done, so all columns remain readonly. 00368 // The function is needed to override the behaviour of its base class. 00369 void reopenRW(); 00370 00371 00372 // Define the column with the row numbers (must have data type uInt). 00373 String rowColumnName_p; 00374 ROScalarColumn<uInt> rowColumn_p; 00375 // Define the various engine column objects. 00376 PtrBlock<ForwardColumnIndexedRow*> refColumns_p; 00377 // Cache of last row used to get row number. 00378 Int lastRow_p; 00379 uInt rowNumber_p; 00380 00381 00382 public: 00383 // Define the "constructor" to construct this engine when a 00384 // table is read back. 00385 // This "constructor" has to be registered by the user of the engine. 00386 // If the engine is commonly used, its registration can be added 00387 // into the registerAllCtor function in DataManReg.cc. 00388 // This function gets automatically invoked by the table system. 00389 static DataManager* makeObject (const String& dataManagerName, 00390 const Record& spec); 00391 00392 // Convert the rownr to the rownr in the underlying table. 00393 uInt convertRownr (uInt rownr); 00394 }; 00395 00396 00397 inline uInt ForwardColumnIndexedRowEngine::convertRownr (uInt rownr) 00398 { 00399 if (Int(rownr) != lastRow_p) { 00400 rowNumber_p = rowColumn_p(rownr); 00401 lastRow_p = rownr; 00402 } 00403 return rowNumber_p; 00404 } 00405 00406 inline uInt ForwardColumnIndexedRow::convertRownr (uInt rownr) 00407 { return enginePtr_p->convertRownr (rownr); } 00408 00409 00410 00411 } //# NAMESPACE CASA - END 00412 00413 #endif