CPLErr GDALHashSetBandBlockCache::FlushCache() { FreeDanglingBlocks(); CPLErr eGlobalErr = poBand->eFlushBlockErr; std::set<GDALRasterBlock*, BlockComparator> oOldSet; { CPLLockHolderOptionalLockD( hLock ); oOldSet = std::move(m_oSet); } for( auto& poBlock: oOldSet ) { if( poBlock->DropLockForRemovalFromStorage() ) { CPLErr eErr = CE_None; if( eGlobalErr == CE_None && poBlock->GetDirty() ) eErr = poBlock->Write(); delete poBlock; if( eErr != CE_None ) eGlobalErr = eErr; } } WaitKeepAliveCounter(); return( eGlobalErr ); }
CPLErr GDALArrayBandBlockCache::AdoptBlock( GDALRasterBlock * poBlock ) { int nBlockIndex; int nXBlockOff = poBlock->GetXOff(); int nYBlockOff = poBlock->GetYOff(); FreeDanglingBlocks(); /* -------------------------------------------------------------------- */ /* Simple case without subblocking. */ /* -------------------------------------------------------------------- */ if( !bSubBlockingActive ) { nBlockIndex = nXBlockOff + nYBlockOff * poBand->nBlocksPerRow; CPLAssert( u.papoBlocks[nBlockIndex] == NULL ); u.papoBlocks[nBlockIndex] = poBlock; } else { /* -------------------------------------------------------------------- */ /* Identify the subblock in which our target occurs, and create */ /* it if necessary. */ /* -------------------------------------------------------------------- */ int nSubBlock = TO_SUBBLOCK(nXBlockOff) + TO_SUBBLOCK(nYBlockOff) * nSubBlocksPerRow; if( u.papapoBlocks[nSubBlock] == NULL ) { const int nSubGridSize = sizeof(GDALRasterBlock*) * SUBBLOCK_SIZE * SUBBLOCK_SIZE; u.papapoBlocks[nSubBlock] = (GDALRasterBlock **) VSICalloc(1, nSubGridSize); if( u.papapoBlocks[nSubBlock] == NULL ) { poBand->ReportError( CE_Failure, CPLE_OutOfMemory, "Out of memory in AdoptBlock()." ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Check within subblock. */ /* -------------------------------------------------------------------- */ GDALRasterBlock **papoSubBlockGrid = u.papapoBlocks[nSubBlock]; int nBlockInSubBlock = WITHIN_SUBBLOCK(nXBlockOff) + WITHIN_SUBBLOCK(nYBlockOff) * SUBBLOCK_SIZE; CPLAssert( papoSubBlockGrid[nBlockInSubBlock] == NULL ); papoSubBlockGrid[nBlockInSubBlock] = poBlock; } return CE_None; }
CPLErr GDALHashSetBandBlockCache::AdoptBlock( GDALRasterBlock * poBlock ) { FreeDanglingBlocks(); CPLLockHolderOptionalLockD( hLock ); m_oSet.insert(poBlock); return CE_None; }
GDALAbstractBandBlockCache::~GDALAbstractBandBlockCache() { CPLAssert(nKeepAliveCounter == 0); FreeDanglingBlocks(); if( hSpinLock ) CPLDestroyLock(hSpinLock); if( hCondMutex ) CPLDestroyMutex(hCondMutex); if( hCond ) CPLDestroyCond(hCond); }
CPLErr GDALArrayBandBlockCache::FlushCache() { FreeDanglingBlocks(); CPLErr eGlobalErr = poBand->eFlushBlockErr; /* -------------------------------------------------------------------- */ /* Flush all blocks in memory ... this case is without subblocking.*/ /* -------------------------------------------------------------------- */ if( !bSubBlockingActive ) { for( int iY = 0; iY < poBand->nBlocksPerColumn; iY++ ) { for( int iX = 0; iX < poBand->nBlocksPerRow; iX++ ) { if( u.papoBlocks[iX + iY*poBand->nBlocksPerRow] != NULL ) { CPLErr eErr; eErr = FlushBlock( iX, iY, eGlobalErr == CE_None ); if( eErr != CE_None ) eGlobalErr = eErr; } } } } /* -------------------------------------------------------------------- */ /* With subblocking. We can short circuit missing subblocks. */ /* -------------------------------------------------------------------- */ else { int iSBX, iSBY; for( iSBY = 0; iSBY < nSubBlocksPerColumn; iSBY++ ) { for( iSBX = 0; iSBX < nSubBlocksPerRow; iSBX++ ) { int nSubBlock = iSBX + iSBY * nSubBlocksPerRow; GDALRasterBlock **papoSubBlockGrid = u.papapoBlocks[nSubBlock]; if( papoSubBlockGrid == NULL ) continue; for( int iY = 0; iY < SUBBLOCK_SIZE; iY++ ) { for( int iX = 0; iX < SUBBLOCK_SIZE; iX++ ) { if( papoSubBlockGrid[iX + iY * SUBBLOCK_SIZE] != NULL ) { CPLErr eErr; eErr = FlushBlock( iX + iSBX * SUBBLOCK_SIZE, iY + iSBY * SUBBLOCK_SIZE, eGlobalErr == CE_None ); if( eErr != CE_None ) eGlobalErr = eErr; } } } // We might as well get rid of this grid chunk since we know // it is now empty. u.papapoBlocks[nSubBlock] = NULL; CPLFree( papoSubBlockGrid ); } } } WaitKeepAliveCounter(); return( eGlobalErr ); }