casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ForwardColRow.h
Go to the documentation of this file.
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