casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TiledStManAccessor.h
Go to the documentation of this file.
00001 //# TiledStManAccessor.h: Gives access to some TiledStMan functions
00002 //# Copyright (C) 1994,1995,1996,1997,1999,2000,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: TiledStManAccessor.h 21295 2012-11-30 16:00:01Z gervandiepen $
00027 
00028 #ifndef TABLES_TILEDSTMANACCESSOR_H
00029 #define TABLES_TILEDSTMANACCESSOR_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <tables/Tables/DataManAccessor.h>
00034 #include <casa/iosfwd.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 //# Forward Declarations
00039 class TiledStMan;
00040 class DataManager;
00041 class Table;
00042 class IPosition;
00043 class String;
00044 class Record;
00045 
00046 // <summary>
00047 // Give access to some TiledStMan functions
00048 // </summary>
00049 
00050 // <use visibility=local>
00051 
00052 // <reviewed reviewer="Gareth Hunt" date="94Nov17" tests="">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //# Classes you should understand before using this one.
00057 // <li> <linkto class=TiledStMan>TiledStMan</linkto>
00058 // </prerequisite>
00059 
00060 // <synopsis>
00061 // The Table system has one or more storage managers underneath.
00062 // These storage managers are invisible and there is no way to
00063 // get access to them.
00064 // However, the <linkto class=TiledStMan>TiledStMan</linkto>-type
00065 // storage managers are quite specific.
00066 // This class ROTiledStManAccessor gives the user the means to
00067 // access a TiledStMan-type object and to control it in some way.
00068 // <p>
00069 // The actions that can be performed deal with the caches used in
00070 // a tiled storage manager. Per hypercube a cache is used to keep as many
00071 // tiles in memory as needed for efficient access to the data.
00072 // The cache size needed is calculated automatically. However,
00073 // it may be possible that a cache uses too much memory. Therefore
00074 // a maximum cache size can be specified, which can be done in 2 ways:
00075 // <ol>
00076 //  <li> To the constructor of a tiled storage manager. This is
00077 //       persistent and acts as the default maximum cache size.
00078 //  <li> Using the function setMaximumCacheSize in this accessor class.
00079 //       This is not persistent and acts as a temporary overwrite
00080 //       of the default maximum cache size.
00081 // </ol>
00082 // It is recommended to set the maximum cache size only when the
00083 // tiled storage manager may use too much memory. Setting a
00084 // maximum could have the effect that the optimal number of tiles
00085 // does not fit in memory leading to excessive read/write activity.
00086 // <br>For example:<br>
00087 // A hypercube has shape [12,20,30,42] and tile shape [4,5,6,7].
00088 // The hypercube contains doubles, so the tilesize is 6720 bytes.
00089 // The number of tiles per dimension is [3,4,5,6] resulting in 360 tiles.
00090 // Iterating through that hypercube requires that some tiles are kept in
00091 // memory to avoid too many read operations. When iterating like
00092 // <srcblock>
00093 // for (uInt i3=0; i3<42; i3++)
00094 //   for (uInt i2=0; i2<30; i2++)
00095 //     for (uInt i1=0; i1<20; i1++)
00096 //       for (uInt i0=0; i0<12; i0++)
00097 //         do something with data[i0,i1,i2,i3]
00098 // </srcblock>
00099 // it is clear that it is best to have a cache which can contain at least
00100 // 3*4*5 tiles. In that way each tile is read only once resulting in
00101 // 360 reads.
00102 // <br>When the cache can hold 3*4 tiles, the first tiles of the 3rd
00103 // dimension have been flushed out when the second step in the 4th dimension
00104 // gets executed. So the tiles have to be reread for each step in the 4th
00105 // dimension, resulting in 3*4*5*42 = 2520 reads.
00106 // <br>When the cache can hold only one tile, the situation is dramatic.
00107 // A tile has to be read for every 4 pixels, resulting in 75600 reads.
00108 // <p>
00109 // Apart from setting the maximum cache size, one can also clear the
00110 // caches. This can be useful to free memory when an iteration through the
00111 // data in the tiled storage manager has been done completely. Clearing
00112 // the caches also clears their statistics (see below).
00113 // <p>
00114 // Showing the statistics of the caches used by a tiled storage
00115 // manager is possible. Per cache it shows the number of tiles accessed and
00116 // the number of tiles actually read, written, or initialized. The hit ratio
00117 // gives a good idea of the cache behaviour.
00118 // <p>
00119 // Note that the maximum cache size is not an absolute maximum.
00120 // When the optimal number of tiles do not fit, it is tried if they fit
00121 // when using an overdrawn of maximum 10%. If so, it uses that overdrawn.
00122 // If not, it uses the maximum cache size.
00123 // <p>
00124 // A few functions exist to get information about a hypercube.
00125 // The 'get' functions get the information for the given hypercube,
00126 // while similar functions without the 'get' prefix do the same for the
00127 // given row.
00128 // </synopsis> 
00129 
00130 // <motivation>
00131 // In principle a pointer to TiledStMan could be used.
00132 // However, that would give access to all public functions.
00133 // Furthermore it could not distinguish between read/write and readonly
00134 // tables. 
00135 // </motivation>
00136 
00137 // <example>
00138 // This example shows how to set the maximum cache size for
00139 // the tiled storage manager with the name "TSMExample". The cache
00140 // size is not persistent, i.e. when the same table is reopened
00141 // at a later time, this cache size is not remembered.
00142 // <srcblock>
00143 //  // Open a table.
00144 //  Table table("someName.data");
00145 //  // Set the maximum cache size of its tiled hypercube storage
00146 //  // manager TSMExample to 0.5 Mb.
00147 //  ROTiledStManAccessor accessor(table, "TSMExample");
00148 //  accessor.setMaximumCacheSize (512*1024);
00149 // </srcblock>
00150 // </example>
00151 
00152 //# <todo asof="$DATE:$">
00153 //# </todo>
00154 
00155 
00156 class ROTiledStManAccessor : public RODataManAccessor
00157 {
00158 public:
00159     // Default constructor should be used with care.
00160     // The resulting object cannot be used for any other operation
00161     // until a 'true' ROTiledStManAccessor object is assigned to it.
00162     ROTiledStManAccessor ();
00163 
00164     // Construct the object for a data manager in the table given the name
00165     // of the data manager or the column.
00166     // An exception is thrown if the data manager type is not any tiled
00167     // storage manager.
00168     ROTiledStManAccessor (const Table& table, const String& name,
00169                           Bool byColumn=False);
00170 
00171     virtual ~ROTiledStManAccessor();
00172 
00173     // Copy constructor (reference semantics).
00174     ROTiledStManAccessor (const ROTiledStManAccessor& that);
00175 
00176     // Assignment (reference semantics).
00177     ROTiledStManAccessor& operator= (const ROTiledStManAccessor& that);
00178 
00179     // Set the maximum cache size (in bytes) to be used by a hypercube
00180     // in the storage manager. Note that each hypercube has its own cache.
00181     // 0 means unlimited.
00182     // The initial maximum cache size is unlimited.
00183     // The maximum cache size given in this way is not persistent.
00184     // Only the maximum cache size given to the constructors of the tiled
00185     // storage managers, is persistent.
00186     void setMaximumCacheSize (uInt nbytes);
00187 
00188     // Get the maximum cache size (in bytes).
00189     uInt maximumCacheSize() const;
00190 
00191     // Get the current cache size (in buckets) for the hypercube in
00192     // the given row.
00193     uInt cacheSize (uInt rownr) const;
00194 
00195     // Get the hypercube shape of the data in the given row.
00196     const IPosition& hypercubeShape (uInt rownr) const;
00197 
00198     // Get the tile shape of the data in the given row.
00199     const IPosition& tileShape (uInt rownr) const;
00200 
00201     // Get the bucket size (in bytes) of the hypercube in the given row.
00202     uInt bucketSize (uInt rownr) const;
00203 
00204     // Get coordinate and id values of the hypercube in the given row.
00205     const Record& valueRecord (uInt rownr) const;
00206 
00207     // Return the number of hypercubes.
00208     uInt nhypercubes() const;
00209 
00210     // Get the current cache size (in buckets) for the given hypercube.
00211     uInt getCacheSize (uInt hypercube) const;
00212 
00213     // Get the shape of the given hypercube.
00214     const IPosition& getHypercubeShape (uInt hypercube) const;
00215 
00216     // Get the tile shape of the given hypercube.
00217     const IPosition& getTileShape (uInt hypercube) const;
00218 
00219      // Get the bucket size (in bytes) of the given hypercube.
00220     uInt getBucketSize (uInt hypercube) const;
00221 
00222     // Get coordinate and id values of the given hypercube.
00223     const Record& getValueRecord (uInt hypercube) const;
00224 
00225     // Calculate the cache size (in buckets) for accessing the hypercube
00226     // containing the given row. It takes the maximum cache size into
00227     // account (allowing an overdraft of 10%).
00228     // It uses the given axisPath (i.e. traversal order) to determine
00229     // the optimum size. A window can be specified to indicate that only
00230     // the given subset of the hypercube will be accessed. The window
00231     // defaults to the entire hypercube.
00232     // <br>
00233     // The length of the slice and window arguments and <src>axisPath</src>
00234     // must be less or equal to the dimensionality of the hypercube.
00235     // The non-specified <src>windowStart</src> parts default to 0.
00236     // The non-specified <src>windowLength</src> parts default to
00237     // the hypercube shape.
00238     // The non-specified <src>sliceShape</src> parts default to 1.
00239     // <br>
00240     // Axispath = [2,0,1] indicates that the z-axis changes most rapidly,
00241     // thereafter x and y. An axis can occur only once in the axisPath.
00242     // The non-specified <src>axisPath</src> parts get the natural order.
00243     // E.g. in the previous example axisPath=[2] defines the same path.
00244     // <group>
00245     uInt calcCacheSize (uInt rownr, const IPosition& sliceShape,
00246                         const IPosition& axisPath) const;
00247     uInt calcCacheSize (uInt rownr, const IPosition& sliceShape,
00248                         const IPosition& windowStart,
00249                         const IPosition& windowLength,
00250                         const IPosition& axisPath) const;
00251     // </group>
00252 
00253     // Set the cache size using the corresponding <src>calcCacheSize</src>
00254     // function mentioned above.
00255     // <br>When forceSmaller is False, the cache is not resized when the
00256     // new size is smaller.
00257     // <group>
00258     void setCacheSize (uInt rownr, const IPosition& sliceShape,
00259                        const IPosition& axisPath,
00260                        Bool forceSmaller = True);
00261     void setCacheSize (uInt rownr, const IPosition& sliceShape,
00262                        const IPosition& windowStart,
00263                        const IPosition& windowLength,
00264                        const IPosition& axisPath,
00265                        Bool forceSmaller = True);
00266     // </group>
00267 
00268     // Set the cache size for accessing the hypercube containing the given row.
00269     // When the give cache size exceeds the maximum cache size with more
00270     // than 10%, the maximum cache size is used instead.
00271     // <br>When forceSmaller is False, the cache is not resized when the
00272     // new size is smaller.
00273     void setCacheSize (uInt rownr, uInt nbuckets, Bool forceSmaller = True);
00274 
00275     // Clear the caches used by the hypercubes in this storage manager.
00276     // It will flush the caches as needed and remove all buckets from them
00277     // resulting in a possibly large drop in memory used.
00278     void clearCaches();
00279 
00280 
00281 protected:
00282     // Get the data manager.
00283     DataManager* getDataManager() const;
00284 
00285 
00286 private:
00287     //# Declare the data members.
00288     TiledStMan* dataManPtr_p;
00289 };
00290 
00291 
00292 
00293 
00294 } //# NAMESPACE CASA - END
00295 
00296 #endif