Improved multi-source file transfer in two ways:

- tunnels can borrow data chunks from only slower tunnels, to prevent blocking fast tunnels
- tunnels can handle up to 50 data chunks at once instead of 5
Multi-source transfers are generaly faster and more stable.


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5156 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2012-05-09 21:31:05 +00:00
parent 438651f693
commit f5c345659a
2 changed files with 40 additions and 16 deletions

View File

@ -282,16 +282,26 @@ bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChun
// 1 - find if this peer already has an active chunk.
//
std::map<std::string,Chunk>::iterator it = _active_chunks_feed.find(peer_id) ;
std::map<std::string,Chunk>::iterator falsafe_it = _active_chunks_feed.end() ;
if(it == _active_chunks_feed.end())
{
SourceChunksInfo *sci = getSourceChunksInfo(peer_id) ;
// 0 - Look into other pending chunks and slice from here.
// 0 - Look into other pending chunks and slice from here. We only consider chunks with size smaller than
// the requested size,
//
for(std::map<std::string,Chunk>::iterator pit(_active_chunks_feed.begin());pit!=_active_chunks_feed.end();++pit)
{
if(sci->is_full || sci->cmap[pit->second._start / _chunk_size])
uint32_t c = pit->second._start / _chunk_size ;
if(!(sci->is_full || sci->cmap[c])) // check that the chunk is available for requested peer.
continue ;
ChunkDownloadInfo& cdi(_slices_to_download[c]) ;
falsafe_it = pit ; // let's keep this one just in case.
if(cdi._slices.rbegin() != cdi._slices.rend() && cdi._slices.rbegin()->second*0.7 <= (float)size_hint)
{
it = pit ;
#ifdef DEBUG_FTCHUNK
@ -299,17 +309,30 @@ bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChun
#endif
break ;
}
#ifdef DEBUG_FTCHUNK
else
std::cerr << "*** ChunkMap::getDataChunk: Not Sharing slice " << pit->second._start << " of peer " << pit->first << " for peer " << peer_id << ", because current peer is too slow" << std::endl;
#endif
}
if(it == _active_chunks_feed.end()) // nor found. Find a new chunk.
if(it == _active_chunks_feed.end()) // not found. Find a new chunk.
{
// 1 - select an available chunk id for this peer.
//
uint32_t c = getAvailableChunk(peer_id,source_chunk_map_needed) ;
if(c >= _map.size())
return false ;
if(falsafe_it != _active_chunks_feed.end()) // no chunk available. Let's see if we can still take an active--faster--chunk.
{
it = falsafe_it ;
#ifdef DEBUG_FTCHUNK
std::cerr << "*** ChunkMap::getDataChunk: Using falsafe chunk " << it->second._start << " of peer " << it->first << " for peer " << peer_id << std::endl;
#endif
}
else
return false ; // no more availabel chunks, no falsafe case.
else
{
// 2 - add the chunk in the list of active chunks, and mark it as being downloaded
//
uint32_t soc = sizeOfChunk(c) ;
@ -322,6 +345,7 @@ bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChun
#endif
}
}
}
#ifdef DEBUG_FTCHUNK
else
std::cout << "*** ChunkMap::getDataChunk: Re-using chunk " << it->second._start/_chunk_size << " for peer " << peer_id << std::endl ;

View File

@ -9,7 +9,7 @@
******/
#define CHUNK_MAX_AGE 40
#define MAX_FTCHUNKS_PER_PEER 5
#define MAX_FTCHUNKS_PER_PEER 50
/***********************************************************
*
@ -366,7 +366,7 @@ int ftFileCreator::locked_notifyReceived(uint64_t offset, uint32_t chunk_size)
if(!found)
{
std::cerr << "ftFileCreator::locked_notifyReceived(): failed to find an active slice for " << offset << "+" << chunk_size << ": dropping data." << std::endl;
std::cerr << "ftFileCreator::locked_notifyReceived(): failed to find an active slice for " << offset << "+" << chunk_size << ", hash = " << hash << ": dropping data." << std::endl;
return 0; /* ignoring */
}
}
@ -466,7 +466,7 @@ bool ftFileCreator::getMissingChunk(const std::string& peer_id,uint32_t size_hin
if(chunks_for_this_peer >= MAX_FTCHUNKS_PER_PEER)
{
#ifdef FILE_DEBUG
std::cerr << "ffc::getMissingChunk() too many chunks for peer " << peer_id << std::endl ;
std::cerr << "ffc::getMissingChunk() too many chunks for peer " << peer_id << " for hash " << hash << ". Count = " << chunks_for_this_peer << std::endl ;
#endif
return false ;
}