From 851e9069f6c38d28744c0c06c3347222e98d9c54 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 17 Feb 2010 22:10:12 +0000 Subject: [PATCH] corrected compled completion and file progress issues git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2356 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/ft/ftchunkmap.cc | 33 +++++++++++++++++------- libretroshare/src/ft/ftchunkmap.h | 9 ++++--- libretroshare/src/ft/ftfilecreator.cc | 10 +++++-- libretroshare/src/ft/ftfilecreator.h | 4 +-- libretroshare/src/ft/fttransfermodule.cc | 9 +++---- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/libretroshare/src/ft/ftchunkmap.cc b/libretroshare/src/ft/ftchunkmap.cc index bcba5103e..1aebd5f55 100644 --- a/libretroshare/src/ft/ftchunkmap.cc +++ b/libretroshare/src/ft/ftchunkmap.cc @@ -45,8 +45,9 @@ ChunkMap::ChunkMap(uint64_t s) ++n ; _map.resize(n,FileChunksInfo::CHUNK_OUTSTANDING) ; - _total_downloaded = 0 ; _strategy = FileChunksInfo::CHUNK_STRATEGY_STREAMING ; + _total_downloaded = 0 ; + _file_is_complete = false ; #ifdef DEBUG_FTCHUNK std::cerr << "*** ChunkMap::ChunkMap: starting new chunkmap:" << std::endl ; std::cerr << " File size: " << s << std::endl ; @@ -58,6 +59,9 @@ ChunkMap::ChunkMap(uint64_t s) void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map) { + _file_is_complete = true ; + _total_downloaded = 0 ; + for(uint32_t i=0;i<_map.size();++i) if(map[i] > 0) { @@ -65,7 +69,10 @@ void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map) _total_downloaded += sizeOfChunk(i) ; } else + { _map[i] = FileChunksInfo::CHUNK_OUTSTANDING ; + _file_is_complete = false ; + } } void ChunkMap::dataReceived(const ftChunk::ChunkId& cid) @@ -113,6 +120,17 @@ void ChunkMap::dataReceived(const ftChunk::ChunkId& cid) #endif _map[n] = FileChunksInfo::CHUNK_DONE ; _slices_to_download.erase(itc) ; + + // We also check whether the file is complete or not. + + _file_is_complete = true ; + + for(uint32_t i=0;i<_map.size();++i) + if(_map[i] != FileChunksInfo::CHUNK_DONE) + { + _file_is_complete = false ; + break ; + } } } @@ -128,7 +146,7 @@ void ChunkMap::dataReceived(const ftChunk::ChunkId& cid) // - chunks pushed when new chunks are needed // - chunks removed when completely downloaded // -bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed,bool& file_is_complete) +bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed) { #ifdef DEBUG_FTCHUNK std::cerr << "*** ChunkMap::getDataChunk: size_hint = " << size_hint << std::endl ; @@ -145,10 +163,10 @@ bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChun switch(_strategy) { - case FileChunksInfo::CHUNK_STRATEGY_STREAMING: c = getAvailableChunk(0,peer_id,source_chunk_map_needed,file_is_complete) ; // very bold!! + case FileChunksInfo::CHUNK_STRATEGY_STREAMING: c = getAvailableChunk(0,peer_id,source_chunk_map_needed) ; // very bold!! break ; - case FileChunksInfo::CHUNK_STRATEGY_RANDOM: c = getAvailableChunk(rand()%_map.size(),peer_id,source_chunk_map_needed,file_is_complete) ; + case FileChunksInfo::CHUNK_STRATEGY_RANDOM: c = getAvailableChunk(rand()%_map.size(),peer_id,source_chunk_map_needed) ; break ; default: #ifdef DEBUG_FTCHUNK @@ -288,7 +306,7 @@ uint32_t ChunkMap::sizeOfChunk(uint32_t cid) const return _chunk_size ; } -uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string& peer_id,bool& map_is_too_old,bool& file_is_complete) +uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string& peer_id,bool& map_is_too_old) { // Quite simple strategy: Check for 1st availabe chunk for this peer starting from the given start location. // @@ -345,15 +363,10 @@ uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string& else map_is_too_old = false ;// the map is not too old - file_is_complete = true ; - for(unsigned int i=0;i<_map.size();++i) { uint32_t j = (start_location+i)%(int)_map.size() ; // index of the chunk - if(_map[j] != FileChunksInfo::CHUNK_DONE) - file_is_complete = false ; - if(_map[j] == FileChunksInfo::CHUNK_OUTSTANDING && (peer_chunks->is_full || peer_chunks->cmap[j])) { #ifdef DEBUG_FTCHUNK diff --git a/libretroshare/src/ft/ftchunkmap.h b/libretroshare/src/ft/ftchunkmap.h index 14e56ebf9..b3a3b3227 100644 --- a/libretroshare/src/ft/ftchunkmap.h +++ b/libretroshare/src/ft/ftchunkmap.h @@ -108,9 +108,8 @@ class ChunkMap /// the chunk should be available from the designated peer. /// On return: /// - source_chunk_map_needed = true if the source map should be asked - /// - file_is_complete = true if the file is complete. - virtual bool getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed,bool& file_is_complete) ; + virtual bool getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed) ; /// Notify received a slice of data. This needs to /// - carve in the map of chunks what is received, what is not. @@ -156,6 +155,9 @@ class ChunkMap /// Returns the total size of downloaded data in the file. uint64_t getTotalReceived() const { return _total_downloaded ; } + /// returns true is the file is complete + bool isComplete() const { return _file_is_complete ; } + void getChunksInfo(FileChunksInfo& info) const ; protected: /// handles what size the last chunk has. @@ -163,7 +165,7 @@ class ChunkMap /// Returns the first chunk available starting from start_location for this peer_id. // - uint32_t getAvailableChunk(uint32_t start_location,const std::string& peer_id,bool& chunk_map_too_old,bool& file_is_complete) ; + uint32_t getAvailableChunk(uint32_t start_location,const std::string& peer_id,bool& chunk_map_too_old) ; private: uint64_t _file_size ; //! total size of the file in bytes. @@ -174,6 +176,7 @@ class ChunkMap std::vector _map ; //! vector of chunk state over the whole file std::map _peers_chunks_availability ; //! what does each source peer have uint64_t _total_downloaded ; //! completion for the file + bool _file_is_complete ; //! set to true when the file is complete. }; diff --git a/libretroshare/src/ft/ftfilecreator.cc b/libretroshare/src/ft/ftfilecreator.cc index fdba57527..8e572a6bd 100644 --- a/libretroshare/src/ft/ftfilecreator.cc +++ b/libretroshare/src/ft/ftfilecreator.cc @@ -320,7 +320,7 @@ void ftFileCreator::setChunkStrategy(FileChunksInfo::ChunkStrategy s) * But can return size = 0, if we are still waiting for the data. */ -bool ftFileCreator::getMissingChunk(const std::string& peer_id,uint32_t size_hint,uint64_t &offset, uint32_t& size,bool& source_chunk_map_needed,bool& file_is_complete) +bool ftFileCreator::getMissingChunk(const std::string& peer_id,uint32_t size_hint,uint64_t &offset, uint32_t& size,bool& source_chunk_map_needed) { RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ #ifdef FILE_DEBUG @@ -359,7 +359,7 @@ bool ftFileCreator::getMissingChunk(const std::string& peer_id,uint32_t size_hin ftChunk chunk ; - if(!chunkMap.getDataChunk(peer_id,size_hint,chunk,source_chunk_map_needed,file_is_complete)) + if(!chunkMap.getDataChunk(peer_id,size_hint,chunk,source_chunk_map_needed)) return false ; #ifdef FILE_DEBUG @@ -429,4 +429,10 @@ void ftFileCreator::setSourceMap(const std::string& peer_id,const CompressedChun chunkMap.setPeerAvailabilityMap(peer_id,compressed_map) ; } +bool ftFileCreator::finished() +{ + RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ + + return chunkMap.isComplete() ; +} diff --git a/libretroshare/src/ft/ftfilecreator.h b/libretroshare/src/ft/ftfilecreator.h index bfab5cb8f..d411bbb19 100644 --- a/libretroshare/src/ft/ftfilecreator.h +++ b/libretroshare/src/ft/ftfilecreator.h @@ -46,7 +46,7 @@ class ftFileCreator: public ftFileProvider /* overloaded from FileProvider */ virtual bool getFileData(uint64_t offset, uint32_t &chunk_size, void *data); - bool finished() { return getRecvd() == getFileSize(); } + bool finished() ; uint64_t getRecvd(); void getChunkMap(FileChunksInfo& info) ; @@ -63,7 +63,7 @@ class ftFileCreator: public ftFileProvider // - no chunkmap info is available. In such a case, the chunk info is irrelevant and false is returned. // - the chunk info is too old. In tis case, true is returned, and the chunks info can be used. // - bool getMissingChunk(const std::string& peer_id,uint32_t size_hint,uint64_t& offset, uint32_t& size,bool& is_chunk_map_too_old,bool& file_is_complete); + bool getMissingChunk(const std::string& peer_id,uint32_t size_hint,uint64_t& offset, uint32_t& size,bool& is_chunk_map_too_old); // Takes care of purging any inactive chunks. This should be called regularly, because some peers may disconnect // and let inactive chunks not finished. diff --git a/libretroshare/src/ft/fttransfermodule.cc b/libretroshare/src/ft/fttransfermodule.cc index a0e8a2d7e..702940211 100644 --- a/libretroshare/src/ft/fttransfermodule.cc +++ b/libretroshare/src/ft/fttransfermodule.cc @@ -328,16 +328,12 @@ bool ftTransferModule::getChunk(const std::string& peer_id,uint32_t size_hint,ui #endif bool source_peer_map_needed ; - bool file_is_complete = false; - bool val = mFileCreator->getMissingChunk(peer_id,size_hint,offset, chunk_size,source_peer_map_needed,file_is_complete); + bool val = mFileCreator->getMissingChunk(peer_id,size_hint,offset, chunk_size,source_peer_map_needed); if(source_peer_map_needed) mMultiplexor->sendChunkMapRequest(peer_id, mHash) ; - if(file_is_complete) - mFlag = 1; - #ifdef FT_DEBUG if (val) { @@ -401,6 +397,9 @@ bool ftTransferModule::queryInactive() { locked_tickPeerTransfer(mit->second); } + if(mFileCreator->finished()) // transfer is complete + mFlag = 1; + return true; }