void * FixedAllocator::Allocate( void ) { // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); assert( CountEmptyChunks() < 2 ); if ( ( NULL == allocChunk_ ) || allocChunk_->IsFilled() ) { if ( NULL != emptyChunk_ ) { allocChunk_ = emptyChunk_; emptyChunk_ = NULL; } else { for ( ChunkIter i( chunks_.begin() ); ; ++i ) { if ( chunks_.end() == i ) { if ( !MakeNewChunk() ) return NULL; break; } if ( !i->IsFilled() ) { allocChunk_ = &*i; break; } } } } else if ( allocChunk_ == emptyChunk_) // detach emptyChunk_ from allocChunk_, because after // calling allocChunk_->Allocate(blockSize_); the chunk // is no longer empty. emptyChunk_ = NULL; assert( allocChunk_ != NULL ); assert( !allocChunk_->IsFilled() ); void * place = allocChunk_->Allocate( blockSize_ ); // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); assert( CountEmptyChunks() < 2 ); #ifdef LOKI_CHECK_FOR_CORRUPTION if ( allocChunk_->IsCorrupt( numBlocks_, blockSize_, true ) ) { assert( false ); return NULL; } #endif return place; }
void * FixedAllocator::Allocate() { if (!last_alloc_ || last_alloc_->blocks_available_ == 0) { // no memory available in the cached chunk, try to find one. Chunks::iterator e = chunks_.end(); Chunks::iterator i = chunks_.begin(); for (; i!=e; ++i) { if (i->blocks_available_ > 0) { // found a chunk! last_alloc_ = &*i; break; } } if (i == e) { // no chunks have blocks available, add a new one. chunks_.reserve(chunks_.size()+1); MemChunk chunk; chunk.Init(block_size_, blocks_); chunks_.push_back(chunk); last_alloc_ = &chunks_.back(); last_dealloc_ = &chunks_.back(); } } // chunk pointer vaild check assert(last_alloc_ != NULL); assert(last_alloc_->blocks_available_ > 0); return last_alloc_->Allocate(block_size_); }
const Chunk * FixedAllocator::HasBlock( void * p ) const { const std::size_t chunkLength = numBlocks_ * blockSize_; for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it ) { const Chunk & chunk = *it; if ( chunk.HasBlock( p, chunkLength ) ) return &chunk; } return NULL; }
void FsDirectoryImpl::deleteFile(const std::string& filename, Chunks& deletedChunks) { Path path(filename); DirNode* pDirNode; INode* pINode; //preconditions check if (path.isPureDir() ){ LOG4CPLUS_WARN(m_logger, "deleteFile, but filename is a pure dir " << filename); throw InvalidFileOrDirName("deleteFile : is pure dir"); } //#TODO, lock pDirNode = m_pDirTree->findDirNode(path.getDirName()); if(!pDirNode) { LOG4CPLUS_WARN(m_logger, "directory not exist :" << path.getDirName()); throw NoSuchFileOrDir("deleteFile : directory"); } if (!(pINode = pDirNode->findFile(path.getFileName()))){ LOG4CPLUS_WARN(m_logger, "file not exist : " << path.getFileName()); throw NoSuchFileOrDir("deleteFile : filename"); } Chunks chunks = pINode->getChunks(); deletedChunks.assign(chunks.begin(), chunks.end()); //#BUGFIX, [#13] INode:findChunk segment fatal error //ChunkTable not synchronized with deleteFile // for( int i = 0; i < chunks.size() ; i++){ m_pChunkTable->deleteItem(chunks[i].id); } //#BUGFIX, [#17] INode:findChunk segment fatal error //NewChunkTable not synchronized with deleteFile // vector<Long> deleteNewChunkIds; if(m_pNewChunkTable->deleteItem(pINode, deleteNewChunkIds)){ string chunkIdList; for (int i = 0 ; i < deleteNewChunkIds.size(); i++){ chunkIdList += deleteNewChunkIds[i]; chunkIdList += " "; } LOG4CPLUS_WARN(m_logger, "delete newchunks not committed: " << chunkIdList); } pDirNode->deleteFile(path.getFileName()); }
void GLSLChunker::dump(const std::string& msg, const Chunks& chunks) const { OE_INFO << msg << "\n"; for (Chunks::const_iterator i = chunks.begin(); i != chunks.end(); ++i) { std::string type = i->type == Chunk::TYPE_DIRECTIVE ? "DIRECTIVE" : i->type == Chunk::TYPE_COMMENT ? "COMMENT" : i->type == Chunk::TYPE_STATEMENT ? "STATEMENT" : i->type == Chunk::TYPE_FUNCTION ? "FUNCTION" : "????????"; OE_INFO << " " << type << ": " << i->text << std::endl; } }
std::size_t FixedAllocator::CountEmptyChunks( void ) const { #ifdef DO_EXTRA_LOKI_TESTS // This code is only used for specialized tests of the allocator. // It is #ifdef-ed so that its O(C) complexity does not overwhelm the // functions which call it. std::size_t count = 0; for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it ) { const Chunk & chunk = *it; if ( chunk.HasAvailable( numBlocks_ ) ) ++count; } return count; #else return ( NULL == emptyChunk_ ) ? 0 : 1; #endif }
void * FixedAllocator::Allocate( void ) { // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); if ( ( NULL == allocChunk_ ) || allocChunk_->IsFilled() ) { if ( NULL != emptyChunk_ ) { allocChunk_ = emptyChunk_; emptyChunk_ = NULL; } else { for ( ChunkIter i( chunks_.begin() ); ; ++i ) { if ( chunks_.end() == i ) { if ( !MakeNewChunk() ) return NULL; break; } if ( !i->IsFilled() ) { allocChunk_ = &*i; break; } } } } assert( allocChunk_ != NULL ); assert( !allocChunk_->IsFilled() ); // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); return allocChunk_->Allocate(blockSize_); }
bool FixedAllocator::IsCorrupt( void ) const { const bool isEmpty = chunks_.empty(); ChunkCIter start( chunks_.begin() ); ChunkCIter last( chunks_.end() ); const size_t emptyChunkCount = CountEmptyChunks(); if ( isEmpty ) { if ( start != last ) { assert( false ); return true; } if ( 0 < emptyChunkCount ) { assert( false ); return true; } if ( NULL != deallocChunk_ ) { assert( false ); return true; } if ( NULL != allocChunk_ ) { assert( false ); return true; } if ( NULL != emptyChunk_ ) { assert( false ); return true; } } else { const Chunk * front = &chunks_.front(); const Chunk * back = &chunks_.back(); if ( start >= last ) { assert( false ); return true; } if ( back < deallocChunk_ ) { assert( false ); return true; } if ( back < allocChunk_ ) { assert( false ); return true; } if ( front > deallocChunk_ ) { assert( false ); return true; } if ( front > allocChunk_ ) { assert( false ); return true; } switch ( emptyChunkCount ) { case 0: if ( emptyChunk_ != NULL ) { assert( false ); return true; } break; case 1: if ( emptyChunk_ == NULL ) { assert( false ); return true; } if ( back < emptyChunk_ ) { assert( false ); return true; } if ( front > emptyChunk_ ) { assert( false ); return true; } if ( !emptyChunk_->HasAvailable( numBlocks_ ) ) { // This may imply somebody tried to delete a block twice. assert( false ); return true; } break; default: assert( false ); return true; } for ( ChunkCIter it( start ); it != last; ++it ) { const Chunk & chunk = *it; if ( chunk.IsCorrupt( numBlocks_, blockSize_, true ) ) return true; } } return false; }