casa
$Rev:20696$
|
00001 //# PagedArray.h: templated Lattice, paged from disk to memory on demand 00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2003 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: PagedArray.h 20364 2008-06-30 06:10:38Z gervandiepen $ 00027 00028 #ifndef LATTICES_PAGEDARRAY_H 00029 #define LATTICES_PAGEDARRAY_H 00030 00031 //# Includes 00032 #include <lattices/Lattices/Lattice.h> 00033 #include <lattices/Lattices/TiledShape.h> 00034 #include <tables/Tables/ArrayColumn.h> 00035 #include <tables/Tables/Table.h> 00036 #include <tables/Tables/TiledStManAccessor.h> 00037 #include <casa/BasicSL/String.h> 00038 00039 00040 namespace casa { //# NAMESPACE CASA - BEGIN 00041 00042 // <summary> 00043 // A Lattice that is read from or written to disk. 00044 // </summary> 00045 00046 // <use visibility=export> 00047 00048 // <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tPagedArray.cc" demos="dPagedArray.cc"> 00049 // </reviewed> 00050 00051 // <prerequisite> 00052 // <li> <linkto class="Lattice">Lattice</linkto> 00053 // <li> <linkto class="TiledShape">TiledShape</linkto> 00054 // </prerequisite> 00055 00056 // <etymology> 00057 // "Demand paging" is a technique used to implement virtual memory in 00058 // computer operating systems. In this scheme, code or data are read from 00059 // disk to memory only as needed by a process, and are read in fixed-sized 00060 // chunks called "pages". PagedArrays are somewhat the same -- though 00061 // without the automatic features found in virtual memory demand paging. 00062 // However PagedArrays do allow the user to access chunks of the disk in a 00063 // flexible way, that can match the requirements of many algorithms. 00064 // </etymology> 00065 00066 // <synopsis> 00067 // At the time of writing, typical scientific computers provide sufficient 00068 // memory for storing and manipulating 2-dimensional astronomical images, 00069 // which have average size of around 8 MBytes. Astronomy is increasingly 00070 // using three or higher dimensional arrays, which can be larger by one or 00071 // two orders of magnitude. PagedArrays provide a convenient way of 00072 // accessing these large arrays without requiring all the data to be read 00073 // into real or virtual memory. 00074 // <p> 00075 // When you construct a PagedArray you do not read any data into 00076 // memory. Instead a disk file (ie. a Table) is created, in a place you 00077 // specify, to hold the data. This means you need to have enough disk space 00078 // to hold the array. Constructing a PagedArray is equivalent to opening a 00079 // file. 00080 // <p> 00081 // Because the data is stored on disk it can be saved after the program, 00082 // function, or task that created the PagedArray has finished. This saved 00083 // array can then be read again at a later stage. 00084 // <p> 00085 // So there are two reasons for using a PagedArray: 00086 // <ol> 00087 // <li> To provide for arrays that are too large for the computer's memory. 00088 // <li> To provide a way of saving arrays to disk for later access. 00089 // </ol> 00090 // 00091 // To access the data in a PagedArray you can either: 00092 // <ol> 00093 // <li> Use a <linkto class=LatticeIterator>LatticeIterator</linkto> 00094 // <li> Use the getSlice and putSlice member functions 00095 // <li> Use the parenthesis operator or getAt and putAt functions 00096 // </ol> 00097 // These access methods are given in order of preference. Some examples of 00098 // these access methods are in the documentation for the 00099 // <linkto class=Lattice>Lattice</linkto> class as well as below. 00100 // <p> 00101 // In nearly all cases you access the PagedArray by reading a "slice" of the 00102 // PagedArray into an AIPS++ <linkto class=Array>Array</linkto>. Because the 00103 // slice is stored in memory it is important that the slice you read is not 00104 // too big compared to the physical memory on your computer. Otherwise your 00105 // computer will page excessively and performance will be poor. 00106 // <p> 00107 // To overcome this you may be tempted to access the PagedArray a pixel at a 00108 // time. This will use little memory but the overhead of accessing a large 00109 // data set by separately reading each pixel from disk will also lead to poor 00110 // performance. 00111 // <p> 00112 // In general the best way to access the data in PagedArrays is to use a 00113 // LatticeIterator with a cursor size that "fits" nicely into memory. Not 00114 // only do the LaticeIterator classes provide a relatively simple way to 00115 // read/write all the data but they optimally set up the cache that is 00116 // associated with each PagedArray. 00117 // <p> 00118 // If the LatticeIterator classes do not access the data the way you want 00119 // you can use the getSlice and putSlice member functions. These functions 00120 // do not set up the cache for you and improved performance may be obtained 00121 // by tweaking the cache using the setCacheSizeFromPath member frunction. 00122 // 00123 // <ANCHOR NAME="PagedArray:Advanced"><h3>More Details</h3></ANCHOR> 00124 // In order to utilise PagedArrays fully and understand many of the member 00125 // functions and data access methods in this class, you need to be familiar 00126 // with some of the concepts involved in the implementation of PagedArrays. 00127 // <p> 00128 // Each PagedArray is stored in one cell of a Table as an indirect Array 00129 // (see the documentation for the <linkto module="Tables">Tables</linkto> 00130 // module for more information). This means that multiple PagedArrays can be 00131 // stored in one Table. To specify which PagedArray you are referring to in 00132 // a given Table you need to specify the cell using its column name and row 00133 // number during construction. If a cell is not specified the default column 00134 // name (as given by the defaultColumnName function) and row number (as 00135 // given by the defaultRowNumber function) are used. This ability to store 00136 // multiple PagedArrays's is used in the PagedImage class where the image is 00137 // stored in one cell and a mask is optionally stored in a another column in 00138 // the same row. 00139 // <p> 00140 // There are currently a number of limitations when storing multiple 00141 // PagedArrays in the same Table. 00142 // <ul> 00143 // <li> All the PagedArrays in the same column MUST have the same number of 00144 // dimensions. The dimension used for any particular column is set when the 00145 // first PagedArray in that column is constructed. If you want to put a 00146 // say two-dimensional PagedArray into another row of a column that 00147 // already contains a four-dimensional PagedArray you need to add two 00148 // degenerate axes. In principle you could use the resize function, but see 00149 // below for why this is not recommended. It is better to just ensure that 00150 // all the PagedArrays have the same number of dimensions. 00151 // <li> All the cells in a column that contains PagedArrays must have their 00152 // shape defined. This becomes important if you are creating a PagedArray in 00153 // say row five of a Table that currently only has one row. The PagedArray 00154 // constructor will add another four rows to the Table, and put your 00155 // PagedArray (with the shape you specify) in row five. For the three 00156 // rows for which no shape was specified, the constructor will construct 00157 // PagedArrays with only one element (and of an appropriate 00158 // dimensionality). As you cannot resize these single element PagedArrays 00159 // without difficulty (see below), it is recommended that you add 00160 // PagedArrays to rows in your Table sequentially. It is necessary to have 00161 // the constructor define the shape of all cells in the Table as it is an 00162 // error to write a Table to disk with undefined cell shapes. 00163 // </ul> 00164 // 00165 // Each PagedArray is stored on disk using the tiled cell storage manager 00166 // (<linkto class=TiledCellStMan>TiledCellStMan</linkto>). This stores the 00167 // data in tiles which are regular subsections of the PagedArray. For 00168 // example a PagedArray of shape [1024,1024,4,128] may have a tile shape of 00169 // [32,16,4,16]. The data in each tile is stored as a unit on the disk. This 00170 // means that there is no preferred axis when accessing multi-dimensional 00171 // data. 00172 // <br> 00173 // The tile shape can be specified when constructing a new PagedArray but 00174 // not when reading an old one as it is intrinsic to the way the data is 00175 // stored on disk. It is NOT recommended that you specify the tile shape 00176 // unless you can control the lifetime of the PagedArray (this includes the 00177 // time it spends on disk), or can guarantee the access pattern. For example 00178 // if you know that a PagedArray of shape [512,512,4,32] will always be 00179 // sliced plane by plane you may prefer to specify a tile shape of 00180 // [512,64,1,1] rather than the default of [32,16,4,16]. 00181 // <br> 00182 // Tiles can be cached by the tile storage manager so that it does not need 00183 // to read the data from disk every time you are accessing the a pixel in a 00184 // different tile. In order to cache the correct tiles you should tell the 00185 // storage manager what section of the PagedArray you will be 00186 // accessing. This is done using the setCacheSizeFromPath member 00187 // function. Alternatively you can set the size of the cache using the 00188 // setCacheSizeInTiles member function. 00189 // <br> 00190 // By default there is no limit on how much memory the tile cache can 00191 // consume. This can be changed using the setMaximumCacheSize member 00192 // function. The tiled storage manager always tries to cache enough tiles to 00193 // ensure that each tile is read from disk only once, so setting the maximum 00194 // cache size will trade off memory usage for disk I/O. Setting the cache 00195 // size is illustrated in example 5 below. 00196 // <br> 00197 // The showCacheStatistics member function is provided to allow you to 00198 // evaluate the performance of the tile cache. 00199 // </synopsis> 00200 00201 // <example> 00202 // All the examples in this section are available in dPagedArray.cc 00203 // 00204 // <h4>Example 1:</h4> 00205 // Create a PagedArray of Floats of shape [1024,1024,4,256] in a file 00206 // called "myData_tmp.array" and initialize it to zero. This will create a 00207 // directory on disk called "myData_tmp.array" that contains files that 00208 // exceed 1024*1024*4*256*4 (= 4 GBytes) in size. 00209 // <srcblock> 00210 // const IPosition arrayShape(4,1024,1024,4,256); 00211 // const String filename("myData_tmp.array"); 00212 // PagedArray<Float> diskArray(arrayShape, filename); 00213 // cout << "Created a PagedArray of shape " << diskArray.shape() 00214 // << " (" << diskArray.shape().product()/1024/1024*sizeof(Float) 00215 // << " MBytes)" << endl 00216 // << "in the table called " << diskArray.tableName() << endl; 00217 // diskArray.set(0.0f); 00218 // // Using the set function is an efficient way to initialize the PagedArray 00219 // // as it uses a PagedArrIter internally. Note that the set function is 00220 // // defined in the Lattice class that PagedArray is derived from. 00221 // </srcblock> 00222 // 00223 // <h4>Example 2:</h4> 00224 // Read the PagedArray produced in Example 1 and put a Gaussian profile into 00225 // each spectral channel. 00226 // <srcblock> 00227 // PagedArray<Float> diskArray("myData_tmp.array"); 00228 // IPosition shape = diskArray.shape(); 00229 // // Construct a Gaussian Profile to be 10 channels wide and centred on 00230 // // channel 16. Its height is 1.0. 00231 // Gaussian1D<Float> g(1.0f, 16.0f, 10.0f); 00232 // // Create a vector to cache a sampled version of this profile. 00233 // Vector<Float> profile(shape(3)); 00234 // indgen(profile); 00235 // profile.apply(g); 00236 // // Now put this profile into every spectral channel in the paged array. This 00237 // // is best done using an iterator. 00238 // LatticeIterator<Float> iter(diskArray, 00239 // TiledLineStepper(shape, diskArray.tileShape(), 3)); 00240 // for (iter.reset(); !iter.atEnd(); iter++) { 00241 // iter.woCursor() = profile; 00242 // } 00243 // </srcblock> 00244 // 00245 // <h4>Example 3:</h4> 00246 // Now multiply the I-polarization data by 10.0 in this PagedArray. The 00247 // I-polarization data occupies 1 GByte of RAM which is too big to read 00248 // into the memory of most computers. So an iterator is used to get suitable 00249 // sized chunks. 00250 // <srcblock> 00251 // Table t("myData_tmp.array", Table::Update); 00252 // PagedArray<Float> da(t); 00253 // const IPosition latticeShape = da.shape(); 00254 // const nx = latticeShape(0); 00255 // const ny = latticeShape(1); 00256 // const npol = latticeShape(2); 00257 // const nchan = latticeShape(3); 00258 // IPosition cursorShape = da.niceCursorShape(); 00259 // cursorShape(2) = 1; 00260 // LatticeStepper step(latticeShape, cursorShape); 00261 // step.subSection(IPosition(4,0), IPosition(4,nx-1,ny-1,0,nchan-1)); 00262 // LatticeIterator<Float> iter(da, step); 00263 // for (iter.reset(); !iter.atEnd(); iter++) { 00264 // iter.rwCursor() *= 10.0f; 00265 // } 00266 // </srcblock> 00267 // 00268 // <h4>Example 4:</h4> 00269 // Use a direct call to getSlice to access a small central region of the 00270 // V-polarization in spectral channel 0 only. The region is small enough 00271 // to not warrant constructing iterators and setting up 00272 // LatticeNavigators. In this example the call to the getSlice function 00273 // is unnecessary but is done for illustration purposes anyway. 00274 // <srcblock> 00275 // SetupNewTable maskSetup("mask_tmp.array", TableDesc(), Table::New); 00276 // Table maskTable(maskSetup); 00277 // PagedArray<Bool> maskArray(IPosition(4,1024,1024,4,256), maskTable); 00278 // maskArray.set(False); 00279 // COWPtr<Array<Bool> > maskPtr; 00280 // maskArray.getSlice(maskPtr, IPosition(4,240,240,3,0), 00281 // IPosition(4,32,32,1,1), IPosition(4,1)); 00282 // maskPtr.rwRef() = True; 00283 // maskArray.putSlice(*maskPtr, IPosition(4,240,240,3,1)); 00284 // </srcblock> 00285 // 00286 // <h4>Example 5:</h4> 00287 // In this example the data in the PagedArray will be accessed a row at 00288 // a time while setting the cache size to different values. The comments 00289 // illustrate the results when running on an Ultra 1/140 with 64MBytes 00290 // of memory. 00291 // <srcblock> 00292 // PagedArray<Float> pa(IPosition(4,128,128,4,32)); 00293 // const IPosition latticeShape = pa.shape(); 00294 // cout << "The tile shape is:" << pa.tileShape() << endl; 00295 // // The tile shape is:[32, 16, 4, 16] 00296 // 00297 // // Setup to access the PagedArray a row at a time 00298 // const IPosition sliceShape(4,latticeShape(0), 1, 1, 1); 00299 // const IPosition stride(4,1); 00300 // Array<Float> row(sliceShape); 00301 // IPosition start(4, 0); 00302 // 00303 // // Set the cache size to enough pixels for one tile only. This uses 00304 // // 128kBytes of cache memory and takes 125 secs. 00305 // pa.setCacheSizeInTiles (1); 00306 // Timer clock; 00307 // for (start(3) = 0; start(3) < latticeShape(3); start(3)++) { 00308 // for (start(2) = 0; start(2) < latticeShape(2); start(2)++) { 00309 // for (start(1) = 0; start(1) < latticeShape(1); start(1)++) { 00310 // pa.getSlice(row, start, sliceShape, stride); 00311 // } 00312 // } 00313 // } 00314 // clock.show(); 00315 // pa.showCacheStatistics(cout); 00316 // pa.clearCache(); 00317 // 00318 // // Set the cache size to enough pixels for one row of tiles (ie. 4). 00319 // // This uses 512 kBytes of cache memory and takes 10 secs. 00320 // pa.setCacheSizeInTiles (4); 00321 // clock.mark(); 00322 // for (start(3) = 0; start(3) < latticeShape(3); start(3)++) { 00323 // for (start(2) = 0; start(2) < latticeShape(2); start(2)++) { 00324 // for (start(1) = 0; start(1) < latticeShape(1); start(1)++) { 00325 // pa.getSlice(row, start, sliceShape, stride); 00326 // } 00327 // } 00328 // } 00329 // clock.show(); 00330 // pa.showCacheStatistics(cout); 00331 // pa.clearCache(); 00332 // 00333 // // Set the cache size to enough pixels for one plane of tiles 00334 // // (ie. 4*8). This uses 4 MBytes of cache memory and takes 2 secs. 00335 // pa.setCacheSizeInTiles (4*8); 00336 // clock.mark(); 00337 // for (start(3) = 0; start(3) < latticeShape(3); start(3)++) { 00338 // for (start(2) = 0; start(2) < latticeShape(2); start(2)++) { 00339 // for (start(1) = 0; start(1) < latticeShape(1); start(1)++) { 00340 // pa.getSlice(row, start, sliceShape, stride); 00341 // } 00342 // } 00343 // } 00344 // clock.show(); 00345 // pa.showCacheStatistics(cout); 00346 // pa.clearCache(); 00347 // </srcblock> 00348 // </example> 00349 00350 // <motivation> 00351 // Arrays of data are sometimes much too large to hold in random access memory. 00352 // PagedArrays, especially in combination with LatticeIterator, 00353 // provide convenient access to such large data sets. 00354 // </motivation> 00355 00356 // <templating arg=T> 00357 // <li> Due to storage in Tables, the templated type must be able to be 00358 // stored in an AIPS++ Table. This restricts the template argument to all 00359 // the common types Bool, Float, Double, Complex, String etc.) More details 00360 // can be found in the RetypedArrayEngine class. 00361 // </templating> 00362 00363 // <todo asof="1997/04/14"> 00364 // <li> A better way of resizing PagedArrays 00365 // </todo> 00366 00367 // <linkfrom anchor="PagedArray" classes="Lattice ArrayLattice"> 00368 // <here>PagedArray</here> - a disk based Lattice. 00369 // </linkfrom> 00370 00371 00372 template <class T> class PagedArray : public Lattice<T> 00373 { 00374 //# Make members of parent class known. 00375 public: 00376 using Lattice<T>::ndim; 00377 00378 public: 00379 // The default constructor creates a PagedArray that is useless for just 00380 // about everything, except that it can be assigned to with the assignment 00381 // operator. 00382 PagedArray(); 00383 00384 // Construct a new PagedArray with the specified shape. A new Table with 00385 // the specified filename is constructed to hold the array. The Table will 00386 // remain on disk after the PagedArray goes out of scope or is deleted. 00387 PagedArray (const TiledShape& shape, const String& filename); 00388 00389 // Construct a new PagedArray with the specified shape. A scratch Table is 00390 // created in the current working directory to hold the array. This Table 00391 // will be deleted automatically when the PagedArray goes out of scope or 00392 // is deleted. 00393 explicit PagedArray (const TiledShape& shape); 00394 00395 // Construct a new PagedArray, with the specified shape, in the default 00396 // row and column of the supplied Table. 00397 PagedArray (const TiledShape& shape, Table& file); 00398 00399 // Construct a new PagedArray, with the specified shape, in the specified 00400 // row and column of the supplied Table. 00401 PagedArray (const TiledShape& shape, Table& file, 00402 const String& columnName, uInt rowNum); 00403 00404 // Reconstruct from a pre-existing PagedArray in the default row and 00405 // column of the supplied Table with the supplied filename. 00406 explicit PagedArray (const String& filename); 00407 00408 // Reconstruct from a pre-existing PagedArray in the default row and 00409 // column of the supplied Table. 00410 explicit PagedArray (Table& file); 00411 00412 // Reconstruct from a pre-existing PagedArray in the specified row and 00413 // column of the supplied Table. 00414 PagedArray (Table& file, const String& columnName, uInt rowNum); 00415 00416 // The copy constructor which uses reference semantics. Copying by value 00417 // doesn't make sense, because it would require the creation of a 00418 // temporary (but possibly huge) file on disk. 00419 PagedArray (const PagedArray<T>& other); 00420 00421 // The destructor flushes the PagedArrays contents to disk. 00422 ~PagedArray(); 00423 00424 // The assignment operator with reference semantics. As with the copy 00425 // constructor assigning by value does not make sense. 00426 PagedArray<T>& operator= (const PagedArray<T>& other); 00427 00428 // Make a copy of the object (reference semantics). 00429 virtual Lattice<T>* clone() const; 00430 00431 // A PagedArray is always persistent. 00432 virtual Bool isPersistent() const; 00433 00434 // A PagedArray is always paged to disk. 00435 virtual Bool isPaged() const; 00436 00437 // Is the PagedArray writable? 00438 virtual Bool isWritable() const; 00439 00440 // Returns the shape of the PagedArray. 00441 virtual IPosition shape() const; 00442 00443 // Return the current Table name. By default this includes the full path. 00444 // The path preceeding the file name can be stripped off on request. 00445 virtual String name (Bool stripPath=False) const; 00446 00447 // Functions to resize the PagedArray. The old contents are lost. Usage of 00448 // this function is NOT currently recommended (see the <linkto 00449 // class="PagedArray:Advanced">More Details</linkto> section above). 00450 void resize (const TiledShape& newShape); 00451 00452 // Returns the current table name (ie. filename) of this PagedArray. 00453 const String& tableName() const; 00454 00455 // Return the current table object. 00456 // <group> 00457 Table& table(); 00458 const Table& table() const; 00459 // </group> 00460 00461 // Returns the current Table column name of this PagedArray. 00462 const String& columnName() const; 00463 00464 // Returns the default TableColumn name for a PagedArray. 00465 static String defaultColumn(); 00466 00467 // Returns an accessor to the tiled storage manager. 00468 const ROTiledStManAccessor& accessor() const; 00469 00470 // Returns the current row number of this PagedArray. 00471 uInt rowNumber() const; 00472 00473 // Returns the default row number for a PagedArray. 00474 static uInt defaultRow(); 00475 00476 // Returns the current tile shape for this PagedArray. 00477 IPosition tileShape() const; 00478 00479 // Returns the maximum recommended number of pixels for a cursor. This is 00480 // the number of pixels in a tile. 00481 virtual uInt advisedMaxPixels() const; 00482 00483 // Set the maximum allowed cache size for all Arrays in this column of the 00484 // Table. The actual value used may be smaller. A value of zero means 00485 // that there is no maximum. 00486 virtual void setMaximumCacheSize (uInt howManyPixels); 00487 00488 // Return the maximum allowed cache size (in pixels) for all Arrays in 00489 // this column of the Table. The actual cache size may be smaller. A 00490 // value of zero means that no maximum is currently defined. 00491 virtual uInt maximumCacheSize() const; 00492 00493 // Set the actual cache size for this Array to be big enough for the 00494 // indicated number of tiles. This cache is not shared with PagedArrays 00495 // in other rows and is always clipped to be less than the maximum value 00496 // set using the setMaximumCacheSize member function. 00497 // Tiles are cached using a first in first out algorithm. 00498 virtual void setCacheSizeInTiles (uInt howManyTiles); 00499 00500 // Set the actual cache size for this Array to "fit" the indicated 00501 // path. This cache is not shared with PagedArrays in other rows and is 00502 // always less than the maximum value. The sliceShape is the cursor or 00503 // slice that you will be requiring (with each call to 00504 // {get,put}Slice). The windowStart and windowLength delimit the range of 00505 // pixels that will ultimatly be accessed. The AxisPath is described in 00506 // the documentation for the LatticeStepper class. 00507 virtual void setCacheSizeFromPath (const IPosition& sliceShape, 00508 const IPosition& windowStart, 00509 const IPosition& windowLength, 00510 const IPosition& axisPath); 00511 00512 // Clears and frees up the tile cache. The maximum allowed cache size is 00513 // unchanged from when <src>setMaximumCacheSize</src> was last called. 00514 virtual void clearCache(); 00515 00516 // Generate a report on how the cache is doing. This is reset every 00517 // time <src>clearCache</src> is called. 00518 virtual void showCacheStatistics (ostream& os) const; 00519 00520 // Return the value of the single element located at the argument 00521 // IPosition. 00522 // Note that <src>Lattice::operator()</src> can also be used. 00523 virtual T getAt (const IPosition& where) const; 00524 00525 // Put the value of a single element. 00526 virtual void putAt (const T& value, const IPosition& where); 00527 00528 // A function which checks for internal consistency. Returns False if 00529 // something nasty has happened to the PagedArray. In that case 00530 // it also throws an exception. 00531 virtual Bool ok() const; 00532 00533 // This function is used by the LatticeIterator class to generate an 00534 // iterator of the correct type for a specified Lattice. Not recommended 00535 // for general use. 00536 virtual LatticeIterInterface<T>* makeIter (const LatticeNavigator& navigator, 00537 Bool useRef) const; 00538 00539 // Do the actual getting of an array of values. 00540 virtual Bool doGetSlice (Array<T>& buffer, const Slicer& section); 00541 00542 // Do the actual getting of an array of values. 00543 virtual void doPutSlice (const Array<T>& sourceBuffer, 00544 const IPosition& where, 00545 const IPosition& stride); 00546 00547 // Get the best cursor shape. 00548 virtual IPosition doNiceCursorShape (uInt maxPixels) const; 00549 00550 // Handle the (un)locking. 00551 // <group> 00552 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00553 virtual void unlock(); 00554 virtual Bool hasLock (FileLocker::LockType) const; 00555 // </group> 00556 00557 // Resynchronize the PagedArray object with the lattice file. 00558 // This function is only useful if no read-locking is used, ie. 00559 // if the table lock option is UserNoReadLocking or AutoNoReadLocking. 00560 // In that cases the table system does not acquire a read-lock, thus 00561 // does not synchronize itself automatically. 00562 virtual void resync(); 00563 00564 // Flush the data (but do not unlock). 00565 virtual void flush(); 00566 00567 // Temporarily close the lattice. 00568 // It will be reopened automatically on the next access. 00569 virtual void tempClose(); 00570 00571 // Explicitly reopen the temporarily closed lattice. 00572 virtual void reopen(); 00573 00574 private: 00575 // Set the data in the TableInfo file 00576 void setTableType(); 00577 // make the ArrayColumn 00578 void makeArray (const TiledShape& shape); 00579 // Make a Table to hold this PagedArray 00580 void makeTable (const String& filename, Table::TableOption option); 00581 // The default comment for PagedArray Colums 00582 static String defaultComment(); 00583 // Get the writable ArrayColumn object. It is created when needed. 00584 ArrayColumn<T>& getRWArray(); 00585 // Create the writable ArrayColumn object. 00586 // It reopens the table for write when needed. 00587 void makeRWArray(); 00588 // Do the reopen of the table (if not open already). 00589 // <group> 00590 void doReopen() const; 00591 void tempReopen() const; 00592 // </group> 00593 00594 mutable Table itsTable; 00595 String itsColumnName; 00596 uInt itsRowNumber; 00597 mutable Bool itsIsClosed; 00598 mutable Bool itsMarkDelete; 00599 String itsTableName; 00600 Bool itsWritable; 00601 TableLock itsLockOpt; 00602 mutable ArrayColumn<T> itsRWArray; 00603 mutable ROArrayColumn<T> itsROArray; 00604 mutable ROTiledStManAccessor itsAccessor; 00605 }; 00606 00607 00608 template<class T> 00609 inline ArrayColumn<T>& PagedArray<T>::getRWArray() 00610 { 00611 if (itsRWArray.isNull()) { 00612 makeRWArray(); 00613 } 00614 return itsRWArray; 00615 } 00616 00617 template<class T> 00618 inline Table& PagedArray<T>::table() 00619 { 00620 doReopen(); 00621 return itsTable; 00622 } 00623 template<class T> 00624 inline const Table& PagedArray<T>::table() const 00625 { 00626 doReopen(); 00627 return itsTable; 00628 } 00629 00630 template<class T> 00631 inline const String& PagedArray<T>::columnName() const 00632 { 00633 return itsColumnName; 00634 } 00635 00636 template<class T> 00637 inline String PagedArray<T>::defaultColumn() 00638 { 00639 return "PagedArray"; 00640 } 00641 00642 template<class T> 00643 inline const ROTiledStManAccessor& PagedArray<T>::accessor() const 00644 { 00645 return itsAccessor; 00646 } 00647 00648 template<class T> 00649 inline uInt PagedArray<T>::rowNumber() const 00650 { 00651 return itsRowNumber; 00652 } 00653 00654 template<class T> 00655 inline uInt PagedArray<T>::defaultRow() 00656 { 00657 return 0; 00658 } 00659 00660 template<class T> 00661 void PagedArray<T>::doReopen() const 00662 { 00663 if (itsIsClosed) { 00664 tempReopen(); 00665 } 00666 } 00667 00668 00669 00670 } //# NAMESPACE CASA - END 00671 00672 #ifndef CASACORE_NO_AUTO_TEMPLATES 00673 #include <lattices/Lattices/PagedArray.tcc> 00674 #endif //# CASACORE_NO_AUTO_TEMPLATES 00675 #endif