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.10  2002/04/16 13:11:49  warmerda
00028  * updated
00028  *
00029  * Revision 1.7  2001/09/27 16:33:41  warmerda
00030  * fixed problems with blocks larger than 2GB/8
00031  *
00032  * Revision 1.6  2001/07/18 04:04:30  warmerda
00033  * added CPL_CVSID
00034  *
00035  * Revision 1.5  2001/06/22 21:00:06  warmerda
00036  * fixed support for caching override by environment variable
00037  *
00038  * Revision 1.4  2001/06/22 20:09:13  warmerda
00039  * added GDAL_CACHEMAX environment variable support
00040  *
00041  * Revision 1.3  2000/03/31 13:42:49  warmerda
00042  * added debugging code
00043  *
00044  * Revision 1.2  2000/03/24 00:09:05  warmerda
00045  * rewrote cache management
00046  *
00047  * Revision 1.1  1998/12/31 18:52:58  warmerda
00048  * New
00049  *
00050  */
00051 
00052 #include "gdal_priv.h"
00053 
00054 CPL_CVSID("$Id: gdalrasterblock_cpp-source.html,v 1.10 2002/04/16 13:11:49 warmerda Exp $");
00055 
00056 static int nTileAgeTicker = 0; 
00057 static int bCacheMaxInitialized = FALSE;
00058 static int nCacheMax = 5 * 1024*1024;
00059 static int nCacheUsed = 0;
00060 
00061 static GDALRasterBlock   *poOldest = NULL;    /* tail */
00062 static GDALRasterBlock   *poNewest = NULL;    /* head */
00063 
00064 
00065 /************************************************************************/
00066 /*                          GDALSetCacheMax()                           */
00067 /************************************************************************/
00068 
00069 void GDALSetCacheMax( int nNewSize )
00070 
00071 {
00072     nCacheMax = nNewSize;
00073     if( nCacheUsed > nCacheMax )
00074         GDALFlushCacheBlock();
00075 }
00076 
00077 /************************************************************************/
00078 /*                          GDALGetCacheMax()                           */
00079 /************************************************************************/
00080 
00081 int GDALGetCacheMax()
00082 {
00083     if( !bCacheMaxInitialized )
00084     {
00085         if( getenv("GDAL_CACHEMAX") != NULL )
00086         {
00087             nCacheMax = atoi(getenv("GDAL_CACHEMAX"));
00088             if( nCacheMax < 1000 )
00089                 nCacheMax *= 1024 * 1024;
00090         }
00091         bCacheMaxInitialized = TRUE;
00092     }
00093     
00094     return nCacheMax;
00095 }
00096 
00097 /************************************************************************/
00098 /*                          GDALGetCacheUsed()                          */
00099 /************************************************************************/
00100 
00101 int GDALGetCacheUsed()
00102 {
00103     return nCacheUsed;
00104 }
00105 
00106 /************************************************************************/
00107 /*                        GDALFlushCacheBlock()                         */
00108 /*                                                                      */
00109 /*      The workhorse of cache management!                              */
00110 /************************************************************************/
00111 
00112 int GDALFlushCacheBlock()
00113 
00114 {
00115     if( poOldest == NULL )
00116         return FALSE;
00117     poOldest->GetBand()->FlushBlock( poOldest->GetXOff(), 
00118                                      poOldest->GetYOff() );
00119 
00120     return TRUE;
00121 }
00122 
00123 /************************************************************************/
00124 /*                           GDALRasterBand()                           */
00125 /************************************************************************/
00126 
00127 GDALRasterBlock::GDALRasterBlock( GDALRasterBand *poBandIn, 
00128                                   int nXOffIn, int nYOffIn )
00129 
00130 {
00131     poBand = poBandIn;
00132 
00133     poBand->GetBlockSize( &nXSize, &nYSize );
00134     eType = poBand->GetRasterDataType();
00135     pData = NULL;
00136     bDirty = FALSE;
00137 
00138     poNext = poPrevious = NULL;
00139 
00140     nXOff = nXOffIn;
00141     nYOff = nYOffIn;
00142 }
00143 
00144 /************************************************************************/
00145 /*                          ~GDALRasterBlock()                          */
00146 /************************************************************************/
00147 
00148 GDALRasterBlock::~GDALRasterBlock()
00149 
00150 {
00151     if( pData != NULL )
00152     {
00153         int nSizeInBytes;
00154 
00155         VSIFree( pData );
00156 
00157         nSizeInBytes = (nXSize * nYSize * GDALGetDataTypeSize(eType)+7)/8;
00158         nCacheUsed -= nSizeInBytes;
00159     }
00160 
00161     if( poOldest == this )
00162         poOldest = poPrevious;
00163 
00164     if( poNewest == this )
00165     {
00166         poNewest = poNext;
00167     }
00168 
00169     if( poPrevious != NULL )
00170         poPrevious->poNext = poNext;
00171 
00172     if( poNext != NULL )
00173         poNext->poPrevious = poPrevious;
00174 
00175 #ifdef ENABLE_DEBUG
00176     Verify();
00177 #endif
00178 
00179     nAge = -1;
00180 }
00181 
00182 /************************************************************************/
00183 /*                               Verify()                               */
00184 /************************************************************************/
00185 
00186 void GDALRasterBlock::Verify()
00187 
00188 {
00189     CPLAssert( (poNewest == NULL && poOldest == NULL)
00190                || (poNewest != NULL && poOldest != NULL) );
00191 
00192     if( poNewest != NULL )
00193     {
00194         CPLAssert( poNewest->poPrevious == NULL );
00195         CPLAssert( poOldest->poNext == NULL );
00196         
00197 
00198         for( GDALRasterBlock *poBlock = poNewest; 
00199              poBlock != NULL;
00200              poBlock = poBlock->poNext )
00201         {
00202             if( poBlock->poPrevious )
00203             {
00204                 CPLAssert( poBlock->poPrevious->poNext == poBlock );
00205             }
00206 
00207             if( poBlock->poNext )
00208             {
00209                 CPLAssert( poBlock->poNext->poPrevious == poBlock );
00210             }
00211         }
00212     }
00213 }
00214 
00215 /************************************************************************/
00216 /*                               Write()                                */
00217 /************************************************************************/
00218 
00219 CPLErr GDALRasterBlock::Write()
00220 
00221 {
00222     if( !GetDirty() )
00223         return CE_None;
00224 
00225     if( poBand == NULL )
00226         return CE_Failure;
00227 
00228     MarkClean();
00229 
00230     return poBand->IWriteBlock( nXOff, nYOff, pData );
00231 }
00232 
00233 /************************************************************************/
00234 /*                               Touch()                                */
00235 /************************************************************************/
00236 
00237 void GDALRasterBlock::Touch()
00238 
00239 {
00240     nAge = nTileAgeTicker++;
00241 
00242     if( poNewest == this )
00243         return;
00244 
00245     if( poOldest == this )
00246         poOldest = this->poPrevious;
00247     
00248     if( poPrevious != NULL )
00249         poPrevious->poNext = poNext;
00250 
00251     if( poNext != NULL )
00252         poNext->poPrevious = poPrevious;
00253 
00254     poPrevious = NULL;
00255     poNext = poNewest;
00256 
00257     if( poNewest != NULL )
00258     {
00259         CPLAssert( poNewest->poPrevious == NULL );
00260         poNewest->poPrevious = this;
00261     }
00262     poNewest = this;
00263     
00264     if( poOldest == NULL )
00265     {
00266         CPLAssert( poPrevious == NULL && poNext == NULL );
00267         poOldest = this;
00268     }
00269 #ifdef ENABLE_DEBUG
00270     Verify();
00271 #endif
00272 }
00273 
00274 /************************************************************************/
00275 /*                            Internalize()                             */
00276 /************************************************************************/
00277 
00278 CPLErr GDALRasterBlock::Internalize()
00279 
00280 {
00281     void        *pNewData;
00282     int         nSizeInBytes;
00283     int         nCurCacheMax = GDALGetCacheMax();
00284 
00285     nSizeInBytes = nXSize * nYSize * (GDALGetDataTypeSize(eType) / 8);
00286 
00287     pNewData = VSIMalloc( nSizeInBytes );
00288     if( pNewData == NULL )
00289         return( CE_Failure );
00290 
00291     if( pData != NULL )
00292         memcpy( pNewData, pData, nSizeInBytes );
00293     
00294     pData = pNewData;
00295 
00296 /* -------------------------------------------------------------------- */
00297 /*      Flush old blocks if we are nearing our memory limit.            */
00298 /* -------------------------------------------------------------------- */
00299     nCacheUsed += nSizeInBytes;
00300     while( nCacheUsed > nCurCacheMax )
00301     {
00302         int nOldCacheUsed = nCacheUsed;
00303 
00304         GDALFlushCacheBlock();
00305 
00306         if( nCacheUsed == nOldCacheUsed )
00307         {
00308             static int bReported = FALSE;
00309 
00310             if( !bReported )
00311             {
00312                 bReported = TRUE;
00313             }
00314             break;
00315         }
00316     }
00317 
00318 /* -------------------------------------------------------------------- */
00319 /*      Add this block to the list.                                     */
00320 /* -------------------------------------------------------------------- */
00321     Touch();
00322     return( CE_None );
00323 }
00324 
00325 /************************************************************************/
00326 /*                             MarkDirty()                              */
00327 /************************************************************************/
00328 
00329 void GDALRasterBlock::MarkDirty()
00330 
00331 {
00332     bDirty = TRUE;
00333 }
00334 
00335 
00336 /************************************************************************/
00337 /*                             MarkClean()                              */
00338 /************************************************************************/
00339 
00340 void GDALRasterBlock::MarkClean()
00341 
00342 {
00343     bDirty = FALSE;
00344 }
00345 
00346 

Generated at Thu Mar 28 09:47:30 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000