Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

gdalrasterblock.cpp

00001 /******************************************************************************
00002  * Copyright (c) 1998, Frank Warmerdam
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00017  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00020  * DEALINGS IN THE SOFTWARE.
00021  ******************************************************************************
00022  *
00023  * gdalrasterblock.cpp
00024  *
00025  * The GDALRasterBlock class.
00026  *
00027  * 
00028  * $Log: gdalrasterblock_cpp-source.html,v $
00028  * Revision 1.13  2002/12/21 19:13:13  warmerda
00028  * updated
00028  *
00029  * Revision 1.8  2002/07/09 20:33:12  warmerda
00030  * expand tabs
00031  *
00032  * Revision 1.7  2001/09/27 16:33:41  warmerda
00033  * fixed problems with blocks larger than 2GB/8
00034  *
00035  * Revision 1.6  2001/07/18 04:04:30  warmerda
00036  * added CPL_CVSID
00037  *
00038  * Revision 1.5  2001/06/22 21:00:06  warmerda
00039  * fixed support for caching override by environment variable
00040  *
00041  * Revision 1.4  2001/06/22 20:09:13  warmerda
00042  * added GDAL_CACHEMAX environment variable support
00043  *
00044  * Revision 1.3  2000/03/31 13:42:49  warmerda
00045  * added debugging code
00046  *
00047  * Revision 1.2  2000/03/24 00:09:05  warmerda
00048  * rewrote cache management
00049  *
00050  * Revision 1.1  1998/12/31 18:52:58  warmerda
00051  * New
00052  *
00053  */
00054 
00055 #include "gdal_priv.h"
00056 
00057 CPL_CVSID("$Id: gdalrasterblock_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $");
00058 
00059 static int nTileAgeTicker = 0; 
00060 static int bCacheMaxInitialized = FALSE;
00061 static int nCacheMax = 5 * 1024*1024;
00062 static int nCacheUsed = 0;
00063 
00064 static GDALRasterBlock   *poOldest = NULL;    /* tail */
00065 static GDALRasterBlock   *poNewest = NULL;    /* head */
00066 
00067 
00068 /************************************************************************/
00069 /*                          GDALSetCacheMax()                           */
00070 /************************************************************************/
00071 
00072 void GDALSetCacheMax( int nNewSize )
00073 
00074 {
00075     nCacheMax = nNewSize;
00076     if( nCacheUsed > nCacheMax )
00077         GDALFlushCacheBlock();
00078 }
00079 
00080 /************************************************************************/
00081 /*                          GDALGetCacheMax()                           */
00082 /************************************************************************/
00083 
00084 int GDALGetCacheMax()
00085 {
00086     if( !bCacheMaxInitialized )
00087     {
00088         if( getenv("GDAL_CACHEMAX") != NULL )
00089         {
00090             nCacheMax = atoi(getenv("GDAL_CACHEMAX"));
00091             if( nCacheMax < 1000 )
00092                 nCacheMax *= 1024 * 1024;
00093         }
00094         bCacheMaxInitialized = TRUE;
00095     }
00096     
00097     return nCacheMax;
00098 }
00099 
00100 /************************************************************************/
00101 /*                          GDALGetCacheUsed()                          */
00102 /************************************************************************/
00103 
00104 int GDALGetCacheUsed()
00105 {
00106     return nCacheUsed;
00107 }
00108 
00109 /************************************************************************/
00110 /*                        GDALFlushCacheBlock()                         */
00111 /*                                                                      */
00112 /*      The workhorse of cache management!                              */
00113 /************************************************************************/
00114 
00115 int GDALFlushCacheBlock()
00116 
00117 {
00118     if( poOldest == NULL )
00119         return FALSE;
00120     poOldest->GetBand()->FlushBlock( poOldest->GetXOff(), 
00121                                      poOldest->GetYOff() );
00122 
00123     return TRUE;
00124 }
00125 
00126 /************************************************************************/
00127 /*                           GDALRasterBand()                           */
00128 /************************************************************************/
00129 
00130 GDALRasterBlock::GDALRasterBlock( GDALRasterBand *poBandIn, 
00131                                   int nXOffIn, int nYOffIn )
00132 
00133 {
00134     poBand = poBandIn;
00135 
00136     poBand->GetBlockSize( &nXSize, &nYSize );
00137     eType = poBand->GetRasterDataType();
00138     pData = NULL;
00139     bDirty = FALSE;
00140 
00141     poNext = poPrevious = NULL;
00142 
00143     nXOff = nXOffIn;
00144     nYOff = nYOffIn;
00145 }
00146 
00147 /************************************************************************/
00148 /*                          ~GDALRasterBlock()                          */
00149 /************************************************************************/
00150 
00151 GDALRasterBlock::~GDALRasterBlock()
00152 
00153 {
00154     if( pData != NULL )
00155     {
00156         int nSizeInBytes;
00157 
00158         VSIFree( pData );
00159 
00160         nSizeInBytes = (nXSize * nYSize * GDALGetDataTypeSize(eType)+7)/8;
00161         nCacheUsed -= nSizeInBytes;
00162     }
00163 
00164     if( poOldest == this )
00165         poOldest = poPrevious;
00166 
00167     if( poNewest == this )
00168     {
00169         poNewest = poNext;
00170     }
00171 
00172     if( poPrevious != NULL )
00173         poPrevious->poNext = poNext;
00174 
00175     if( poNext != NULL )
00176         poNext->poPrevious = poPrevious;
00177 
00178 #ifdef ENABLE_DEBUG
00179     Verify();
00180 #endif
00181 
00182     nAge = -1;
00183 }
00184 
00185 /************************************************************************/
00186 /*                               Verify()                               */
00187 /************************************************************************/
00188 
00189 void GDALRasterBlock::Verify()
00190 
00191 {
00192     CPLAssert( (poNewest == NULL && poOldest == NULL)
00193                || (poNewest != NULL && poOldest != NULL) );
00194 
00195     if( poNewest != NULL )
00196     {
00197         CPLAssert( poNewest->poPrevious == NULL );
00198         CPLAssert( poOldest->poNext == NULL );
00199         
00200 
00201         for( GDALRasterBlock *poBlock = poNewest; 
00202              poBlock != NULL;
00203              poBlock = poBlock->poNext )
00204         {
00205             if( poBlock->poPrevious )
00206             {
00207                 CPLAssert( poBlock->poPrevious->poNext == poBlock );
00208             }
00209 
00210             if( poBlock->poNext )
00211             {
00212                 CPLAssert( poBlock->poNext->poPrevious == poBlock );
00213             }
00214         }
00215     }
00216 }
00217 
00218 /************************************************************************/
00219 /*                               Write()                                */
00220 /************************************************************************/
00221 
00222 CPLErr GDALRasterBlock::Write()
00223 
00224 {
00225     if( !GetDirty() )
00226         return CE_None;
00227 
00228     if( poBand == NULL )
00229         return CE_Failure;
00230 
00231     MarkClean();
00232 
00233     return poBand->IWriteBlock( nXOff, nYOff, pData );
00234 }
00235 
00236 /************************************************************************/
00237 /*                               Touch()                                */
00238 /************************************************************************/
00239 
00240 void GDALRasterBlock::Touch()
00241 
00242 {
00243     nAge = nTileAgeTicker++;
00244 
00245     if( poNewest == this )
00246         return;
00247 
00248     if( poOldest == this )
00249         poOldest = this->poPrevious;
00250     
00251     if( poPrevious != NULL )
00252         poPrevious->poNext = poNext;
00253 
00254     if( poNext != NULL )
00255         poNext->poPrevious = poPrevious;
00256 
00257     poPrevious = NULL;
00258     poNext = poNewest;
00259 
00260     if( poNewest != NULL )
00261     {
00262         CPLAssert( poNewest->poPrevious == NULL );
00263         poNewest->poPrevious = this;
00264     }
00265     poNewest = this;
00266     
00267     if( poOldest == NULL )
00268     {
00269         CPLAssert( poPrevious == NULL && poNext == NULL );
00270         poOldest = this;
00271     }
00272 #ifdef ENABLE_DEBUG
00273     Verify();
00274 #endif
00275 }
00276 
00277 /************************************************************************/
00278 /*                            Internalize()                             */
00279 /************************************************************************/
00280 
00281 CPLErr GDALRasterBlock::Internalize()
00282 
00283 {
00284     void        *pNewData;
00285     int         nSizeInBytes;
00286     int         nCurCacheMax = GDALGetCacheMax();
00287 
00288     nSizeInBytes = nXSize * nYSize * (GDALGetDataTypeSize(eType) / 8);
00289 
00290     pNewData = VSIMalloc( nSizeInBytes );
00291     if( pNewData == NULL )
00292         return( CE_Failure );
00293 
00294     if( pData != NULL )
00295         memcpy( pNewData, pData, nSizeInBytes );
00296     
00297     pData = pNewData;
00298 
00299 /* -------------------------------------------------------------------- */
00300 /*      Flush old blocks if we are nearing our memory limit.            */
00301 /* -------------------------------------------------------------------- */
00302     nCacheUsed += nSizeInBytes;
00303     while( nCacheUsed > nCurCacheMax )
00304     {
00305         int nOldCacheUsed = nCacheUsed;
00306 
00307         GDALFlushCacheBlock();
00308 
00309         if( nCacheUsed == nOldCacheUsed )
00310         {
00311             static int bReported = FALSE;
00312 
00313             if( !bReported )
00314             {
00315                 bReported = TRUE;
00316             }
00317             break;
00318         }
00319     }
00320 
00321 /* -------------------------------------------------------------------- */
00322 /*      Add this block to the list.                                     */
00323 /* -------------------------------------------------------------------- */
00324     Touch();
00325     return( CE_None );
00326 }
00327 
00328 /************************************************************************/
00329 /*                             MarkDirty()                              */
00330 /************************************************************************/
00331 
00332 void GDALRasterBlock::MarkDirty()
00333 
00334 {
00335     bDirty = TRUE;
00336 }
00337 
00338 
00339 /************************************************************************/
00340 /*                             MarkClean()                              */
00341 /************************************************************************/
00342 
00343 void GDALRasterBlock::MarkClean()
00344 
00345 {
00346     bDirty = FALSE;
00347 }
00348 
00349 

Generated at Sat Dec 21 14:01:59 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000