CPLErr GDALHashSetBandBlockCache::AdoptBlock( GDALRasterBlock * poBlock ) { FreeDanglingBlocks(); CPLLockHolderOptionalLockD( hLock ); m_oSet.insert(poBlock); return CE_None; }
GDALRasterBlock *GDALHashSetBandBlockCache::TryGetLockedBlockRef( int nXBlockOff, int nYBlockOff ) { GDALRasterBlock oBlockForLookup(nXBlockOff, nYBlockOff); GDALRasterBlock* poBlock; { CPLLockHolderOptionalLockD( hLock ); auto oIter = m_oSet.find(&oBlockForLookup); if( oIter == m_oSet.end() ) return nullptr; poBlock = *oIter; } if( !poBlock->TakeLock() ) return nullptr; return poBlock; }
void GDALAbstractBandBlockCache::FreeDanglingBlocks() { GDALRasterBlock* poList; { CPLLockHolderOptionalLockD(hSpinLock); poList = psListBlocksToFree; psListBlocksToFree = NULL; } while( poList ) { #ifdef DEBUG_VERBOSE_ABBC CPLAtomicDec(&nAllBandsKeptAlivedBlocks); fprintf(stderr, "FreeDanglingBlocks(): nAllBandsKeptAlivedBlocks=%d\n", nAllBandsKeptAlivedBlocks); #endif GDALRasterBlock* poNext = poList->poNext; poList->poNext = NULL; delete poList; poList = poNext; } }
void GDALAbstractBandBlockCache::AddBlockToFreeList( GDALRasterBlock *poBlock ) { CPLAssert(poBlock->poPrevious == NULL); CPLAssert(poBlock->poNext == NULL); { #ifdef DEBUG_VERBOSE_ABBC CPLAtomicInc(&nAllBandsKeptAlivedBlocks); fprintf(stderr, "AddBlockToFreeList(): nAllBandsKeptAlivedBlocks=%d\n", nAllBandsKeptAlivedBlocks); #endif CPLLockHolderOptionalLockD(hSpinLock); poBlock->poNext = psListBlocksToFree; psListBlocksToFree = poBlock; } // If no more blocks in transient state, then warn WaitKeepAliveCounter() CPLAcquireMutex(hCondMutex, 1000); if( CPLAtomicDec(&nKeepAliveCounter) == 0 ) { CPLCondSignal(hCond); } CPLReleaseMutex(hCondMutex); }
GDALRasterBlock* GDALAbstractBandBlockCache::CreateBlock(int nXBlockOff, int nYBlockOff) { GDALRasterBlock* poBlock; { CPLLockHolderOptionalLockD(hSpinLock); poBlock = psListBlocksToFree; if( poBlock ) { #ifdef DEBUG_VERBOSE_ABBC CPLAtomicDec(&nAllBandsKeptAlivedBlocks); fprintf(stderr, "CreateBlock(): nAllBandsKeptAlivedBlocks=%d\n", nAllBandsKeptAlivedBlocks); #endif psListBlocksToFree = poBlock->poNext; } } if( poBlock ) poBlock->RecycleFor(nXBlockOff, nYBlockOff); else poBlock = new (std::nothrow) GDALRasterBlock( poBand, nXBlockOff, nYBlockOff ); return poBlock; }
CPLErr GDALHashSetBandBlockCache::FlushCache() { FreeDanglingBlocks(); CPLErr eGlobalErr = poBand->eFlushBlockErr; std::set<GDALRasterBlock*, BlockComparator> oOldSet; { CPLLockHolderOptionalLockD( hLock ); oOldSet = std::move(m_oSet); } StartDirtyBlockFlushingLog(); for( auto& poBlock: oOldSet ) { if( poBlock->DropLockForRemovalFromStorage() ) { CPLErr eErr = CE_None; if( eGlobalErr == CE_None && poBlock->GetDirty() ) { UpdateDirtyBlockFlushingLog(); eErr = poBlock->Write(); } delete poBlock; if( eErr != CE_None ) eGlobalErr = eErr; } } EndDirtyBlockFlushingLog(); WaitKeepAliveCounter(); return( eGlobalErr ); }