From e08d13397ae30911f598c33a6a35f2155d321255 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 2 Feb 2010 22:15:42 +0000 Subject: [PATCH] fixed a completion issue in FT git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2174 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/ft/ftchunkmap.cc | 13 ++++++++----- libretroshare/src/ft/ftchunkmap.h | 7 +++++-- libretroshare/src/ft/ftfilecreator.cc | 4 ++-- libretroshare/src/ft/ftfilecreator.h | 2 +- libretroshare/src/ft/fttransfermodule.cc | 9 ++++++--- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/libretroshare/src/ft/ftchunkmap.cc b/libretroshare/src/ft/ftchunkmap.cc index 42f28726a..349ee7f17 100644 --- a/libretroshare/src/ft/ftchunkmap.cc +++ b/libretroshare/src/ft/ftchunkmap.cc @@ -62,7 +62,7 @@ void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map) if(map[i] > 0) { _map[i] = FileChunksInfo::CHUNK_DONE ; - _total_downloaded += _chunk_size ; + _total_downloaded += sizeOfChunk(i) ; } else _map[i] = FileChunksInfo::CHUNK_OUTSTANDING ; @@ -128,7 +128,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 ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed,bool& file_is_complete) { #ifdef DEBUG_FTCHUNK std::cerr << "*** ChunkMap::getDataChunk: size_hint = " << size_hint << std::endl ; @@ -145,10 +145,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) ; // very bold!! + case FileChunksInfo::CHUNK_STRATEGY_STREAMING: c = getAvailableChunk(0,peer_id,source_chunk_map_needed,file_is_complete) ; // very bold!! break ; - case FileChunksInfo::CHUNK_STRATEGY_RANDOM: c = getAvailableChunk(rand()%_map.size(),peer_id,source_chunk_map_needed) ; + case FileChunksInfo::CHUNK_STRATEGY_RANDOM: c = getAvailableChunk(rand()%_map.size(),peer_id,source_chunk_map_needed,file_is_complete) ; break ; default: #ifdef DEBUG_FTCHUNK @@ -288,7 +288,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) +uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string& peer_id,bool& map_is_too_old,bool& file_is_complete) { // Quite simple strategy: Check for 1st availabe chunk for this peer starting from the given start location. // @@ -345,6 +345,8 @@ 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 @@ -354,6 +356,7 @@ uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string& #ifdef DEBUG_FTCHUNK std::cerr << "ChunkMap::getAvailableChunk: returning chunk " << j << " for peer " << peer_id << std::endl; #endif + file_is_complete = false ; return j ; } } diff --git a/libretroshare/src/ft/ftchunkmap.h b/libretroshare/src/ft/ftchunkmap.h index ab7148e3a..14e56ebf9 100644 --- a/libretroshare/src/ft/ftchunkmap.h +++ b/libretroshare/src/ft/ftchunkmap.h @@ -106,8 +106,11 @@ class ChunkMap /// If not, randomly/streamly select a new chunk depending on the strategy. /// adds an entry in the chunk_ids map, and sets up 1 interval for it. /// 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) ; + virtual bool getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed,bool& file_is_complete) ; /// Notify received a slice of data. This needs to /// - carve in the map of chunks what is received, what is not. @@ -160,7 +163,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) ; + uint32_t getAvailableChunk(uint32_t start_location,const std::string& peer_id,bool& chunk_map_too_old,bool& file_is_complete) ; private: uint64_t _file_size ; //! total size of the file in bytes. diff --git a/libretroshare/src/ft/ftfilecreator.cc b/libretroshare/src/ft/ftfilecreator.cc index 75016126c..0ced1d89d 100644 --- a/libretroshare/src/ft/ftfilecreator.cc +++ b/libretroshare/src/ft/ftfilecreator.cc @@ -317,7 +317,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 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) { RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ #ifdef FILE_DEBUG @@ -356,7 +356,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)) + if(!chunkMap.getDataChunk(peer_id,size_hint,chunk,source_chunk_map_needed,file_is_complete)) return false ; #ifdef FILE_DEBUG diff --git a/libretroshare/src/ft/ftfilecreator.h b/libretroshare/src/ft/ftfilecreator.h index c5c79077c..bfab5cb8f 100644 --- a/libretroshare/src/ft/ftfilecreator.h +++ b/libretroshare/src/ft/ftfilecreator.h @@ -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 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); // 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 62b4fa2ca..74347f515 100644 --- a/libretroshare/src/ft/fttransfermodule.cc +++ b/libretroshare/src/ft/fttransfermodule.cc @@ -328,11 +328,16 @@ bool ftTransferModule::getChunk(const std::string& peer_id,uint32_t size_hint,ui #endif bool source_peer_map_needed ; - bool val = mFileCreator->getMissingChunk(peer_id,size_hint,offset, chunk_size,source_peer_map_needed); + bool file_is_complete ; + + bool val = mFileCreator->getMissingChunk(peer_id,size_hint,offset, chunk_size,source_peer_map_needed,file_is_complete); if(source_peer_map_needed) mMultiplexor->sendChunkMapRequest(peer_id, mHash) ; + if(file_is_complete) + mFlag = 1; + #ifdef FT_DEBUG if (val) { @@ -706,8 +711,6 @@ bool ftTransferModule::locked_tickPeerTransfer(peerInfo &info) std::cerr << std::endl; } } - else - mFlag = 1; return true; }