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