mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
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
This commit is contained in:
parent
2b58d2fc02
commit
851e9069f6
@ -45,8 +45,9 @@ ChunkMap::ChunkMap(uint64_t s)
|
|||||||
++n ;
|
++n ;
|
||||||
|
|
||||||
_map.resize(n,FileChunksInfo::CHUNK_OUTSTANDING) ;
|
_map.resize(n,FileChunksInfo::CHUNK_OUTSTANDING) ;
|
||||||
_total_downloaded = 0 ;
|
|
||||||
_strategy = FileChunksInfo::CHUNK_STRATEGY_STREAMING ;
|
_strategy = FileChunksInfo::CHUNK_STRATEGY_STREAMING ;
|
||||||
|
_total_downloaded = 0 ;
|
||||||
|
_file_is_complete = false ;
|
||||||
#ifdef DEBUG_FTCHUNK
|
#ifdef DEBUG_FTCHUNK
|
||||||
std::cerr << "*** ChunkMap::ChunkMap: starting new chunkmap:" << std::endl ;
|
std::cerr << "*** ChunkMap::ChunkMap: starting new chunkmap:" << std::endl ;
|
||||||
std::cerr << " File size: " << s << std::endl ;
|
std::cerr << " File size: " << s << std::endl ;
|
||||||
@ -58,6 +59,9 @@ ChunkMap::ChunkMap(uint64_t s)
|
|||||||
|
|
||||||
void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map)
|
void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map)
|
||||||
{
|
{
|
||||||
|
_file_is_complete = true ;
|
||||||
|
_total_downloaded = 0 ;
|
||||||
|
|
||||||
for(uint32_t i=0;i<_map.size();++i)
|
for(uint32_t i=0;i<_map.size();++i)
|
||||||
if(map[i] > 0)
|
if(map[i] > 0)
|
||||||
{
|
{
|
||||||
@ -65,7 +69,10 @@ void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map)
|
|||||||
_total_downloaded += sizeOfChunk(i) ;
|
_total_downloaded += sizeOfChunk(i) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_map[i] = FileChunksInfo::CHUNK_OUTSTANDING ;
|
_map[i] = FileChunksInfo::CHUNK_OUTSTANDING ;
|
||||||
|
_file_is_complete = false ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChunkMap::dataReceived(const ftChunk::ChunkId& cid)
|
void ChunkMap::dataReceived(const ftChunk::ChunkId& cid)
|
||||||
@ -113,6 +120,17 @@ void ChunkMap::dataReceived(const ftChunk::ChunkId& cid)
|
|||||||
#endif
|
#endif
|
||||||
_map[n] = FileChunksInfo::CHUNK_DONE ;
|
_map[n] = FileChunksInfo::CHUNK_DONE ;
|
||||||
_slices_to_download.erase(itc) ;
|
_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 pushed when new chunks are needed
|
||||||
// - chunks removed when completely downloaded
|
// - 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
|
#ifdef DEBUG_FTCHUNK
|
||||||
std::cerr << "*** ChunkMap::getDataChunk: size_hint = " << size_hint << std::endl ;
|
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)
|
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 ;
|
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 ;
|
break ;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG_FTCHUNK
|
#ifdef DEBUG_FTCHUNK
|
||||||
@ -288,7 +306,7 @@ uint32_t ChunkMap::sizeOfChunk(uint32_t cid) const
|
|||||||
return _chunk_size ;
|
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.
|
// 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
|
else
|
||||||
map_is_too_old = false ;// the map is not too old
|
map_is_too_old = false ;// the map is not too old
|
||||||
|
|
||||||
file_is_complete = true ;
|
|
||||||
|
|
||||||
for(unsigned int i=0;i<_map.size();++i)
|
for(unsigned int i=0;i<_map.size();++i)
|
||||||
{
|
{
|
||||||
uint32_t j = (start_location+i)%(int)_map.size() ; // index of the chunk
|
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]))
|
if(_map[j] == FileChunksInfo::CHUNK_OUTSTANDING && (peer_chunks->is_full || peer_chunks->cmap[j]))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_FTCHUNK
|
#ifdef DEBUG_FTCHUNK
|
||||||
|
@ -108,9 +108,8 @@ class ChunkMap
|
|||||||
/// the chunk should be available from the designated peer.
|
/// the chunk should be available from the designated peer.
|
||||||
/// On return:
|
/// On return:
|
||||||
/// - source_chunk_map_needed = true if the source map should be asked
|
/// - 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
|
/// Notify received a slice of data. This needs to
|
||||||
/// - carve in the map of chunks what is received, what is not.
|
/// - 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.
|
/// Returns the total size of downloaded data in the file.
|
||||||
uint64_t getTotalReceived() const { return _total_downloaded ; }
|
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 ;
|
void getChunksInfo(FileChunksInfo& info) const ;
|
||||||
protected:
|
protected:
|
||||||
/// handles what size the last chunk has.
|
/// 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.
|
/// 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:
|
private:
|
||||||
uint64_t _file_size ; //! total size of the file in bytes.
|
uint64_t _file_size ; //! total size of the file in bytes.
|
||||||
@ -174,6 +176,7 @@ class ChunkMap
|
|||||||
std::vector<FileChunksInfo::ChunkState> _map ; //! vector of chunk state over the whole file
|
std::vector<FileChunksInfo::ChunkState> _map ; //! vector of chunk state over the whole file
|
||||||
std::map<std::string,SourceChunksInfo> _peers_chunks_availability ; //! what does each source peer have
|
std::map<std::string,SourceChunksInfo> _peers_chunks_availability ; //! what does each source peer have
|
||||||
uint64_t _total_downloaded ; //! completion for the file
|
uint64_t _total_downloaded ; //! completion for the file
|
||||||
|
bool _file_is_complete ; //! set to true when the file is complete.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ void ftFileCreator::setChunkStrategy(FileChunksInfo::ChunkStrategy s)
|
|||||||
* But can return size = 0, if we are still waiting for the data.
|
* 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 ******/
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
#ifdef FILE_DEBUG
|
#ifdef FILE_DEBUG
|
||||||
@ -359,7 +359,7 @@ bool ftFileCreator::getMissingChunk(const std::string& peer_id,uint32_t size_hin
|
|||||||
|
|
||||||
ftChunk chunk ;
|
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 ;
|
return false ;
|
||||||
|
|
||||||
#ifdef FILE_DEBUG
|
#ifdef FILE_DEBUG
|
||||||
@ -429,4 +429,10 @@ void ftFileCreator::setSourceMap(const std::string& peer_id,const CompressedChun
|
|||||||
chunkMap.setPeerAvailabilityMap(peer_id,compressed_map) ;
|
chunkMap.setPeerAvailabilityMap(peer_id,compressed_map) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ftFileCreator::finished()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
|
return chunkMap.isComplete() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class ftFileCreator: public ftFileProvider
|
|||||||
|
|
||||||
/* overloaded from FileProvider */
|
/* overloaded from FileProvider */
|
||||||
virtual bool getFileData(uint64_t offset, uint32_t &chunk_size, void *data);
|
virtual bool getFileData(uint64_t offset, uint32_t &chunk_size, void *data);
|
||||||
bool finished() { return getRecvd() == getFileSize(); }
|
bool finished() ;
|
||||||
uint64_t getRecvd();
|
uint64_t getRecvd();
|
||||||
|
|
||||||
void getChunkMap(FileChunksInfo& info) ;
|
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.
|
// - 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.
|
// - 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
|
// Takes care of purging any inactive chunks. This should be called regularly, because some peers may disconnect
|
||||||
// and let inactive chunks not finished.
|
// and let inactive chunks not finished.
|
||||||
|
@ -328,16 +328,12 @@ bool ftTransferModule::getChunk(const std::string& peer_id,uint32_t size_hint,ui
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool source_peer_map_needed ;
|
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)
|
if(source_peer_map_needed)
|
||||||
mMultiplexor->sendChunkMapRequest(peer_id, mHash) ;
|
mMultiplexor->sendChunkMapRequest(peer_id, mHash) ;
|
||||||
|
|
||||||
if(file_is_complete)
|
|
||||||
mFlag = 1;
|
|
||||||
|
|
||||||
#ifdef FT_DEBUG
|
#ifdef FT_DEBUG
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
@ -401,6 +397,9 @@ bool ftTransferModule::queryInactive()
|
|||||||
{
|
{
|
||||||
locked_tickPeerTransfer(mit->second);
|
locked_tickPeerTransfer(mit->second);
|
||||||
}
|
}
|
||||||
|
if(mFileCreator->finished()) // transfer is complete
|
||||||
|
mFlag = 1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user