added new DL mode: Progressive. This is a random mode that ensures no more than 50MB of free space will be written in the file at once. This should effectively remove the lag when initiating a DL on a big file, while keeping enough entropy to ensure a good dissemination of chunks

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6164 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-02-28 20:42:01 +00:00
parent 2d74a3012a
commit 4f1dda2ffb
10 changed files with 76 additions and 24 deletions

View file

@ -38,6 +38,7 @@
static const uint32_t SOURCE_CHUNK_MAP_UPDATE_PERIOD = 60 ; //! TTL for chunkmap info
static const uint32_t INACTIVE_CHUNK_TIME_LAPSE = 300 ; //! TTL for an inactive chunk
static const uint32_t FT_CHUNKMAP_MAX_CHUNK_JUMP = 50 ; //! Maximum chunk jump in progressive DL mode
std::ostream& operator<<(std::ostream& o,const ftChunk& c)
{
@ -74,7 +75,7 @@ ChunkMap::ChunkMap(uint64_t s,bool availability)
++n ;
_map.resize(n,FileChunksInfo::CHUNK_OUTSTANDING) ;
_strategy = FileChunksInfo::CHUNK_STRATEGY_RANDOM ;
_strategy = FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE ;
_total_downloaded = 0 ;
_file_is_complete = false ;
#ifdef DEBUG_FTCHUNK
@ -537,27 +538,45 @@ uint32_t ChunkMap::getAvailableChunk(const std::string& peer_id,bool& map_is_too
map_is_too_old = false ;// the map is not too old
uint32_t available_chunks = 0 ;
uint32_t available_chunks_before_max_dist = 0 ;
uint32_t max_dist = 0; // id of the highest downloaded chunk
for(unsigned int i=0;i<_map.size();++i)
if(_map[i] == FileChunksInfo::CHUNK_OUTSTANDING && (peer_chunks->is_full || peer_chunks->cmap[i]))
if(_map[i] == FileChunksInfo::CHUNK_OUTSTANDING)
{
if(_strategy == FileChunksInfo::CHUNK_STRATEGY_STREAMING)
{
#ifdef DEBUG_FTCHUNK
std::cerr << "ChunkMap::getAvailableChunk: returning chunk " << i << " for peer " << peer_id << std::endl;
#endif
return i ;
}
else
if(peer_chunks->is_full || peer_chunks->cmap[i])
++available_chunks ;
}
else
{
max_dist = i ;
available_chunks_before_max_dist = available_chunks ;
}
if(available_chunks > 0)
{
uint32_t chosen_chunk_number = rand() % available_chunks ;
uint32_t chunk_jump ;
uint32_t chosen_chunk_number ;
switch(_strategy)
{
case FileChunksInfo::CHUNK_STRATEGY_STREAMING: chunk_jump = 1 ;
chosen_chunk_number = 0 ;
break ;
case FileChunksInfo::CHUNK_STRATEGY_RANDOM: chunk_jump = _map.size() ;
chosen_chunk_number = rand() % available_chunks ;
break ;
case FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE: chunk_jump = FT_CHUNKMAP_MAX_CHUNK_JUMP ;
chosen_chunk_number = rand() % std::min(available_chunks, available_chunks_before_max_dist+FT_CHUNKMAP_MAX_CHUNK_JUMP) ;
break ;
default:
chunk_jump = _map.size() ;
chosen_chunk_number = 0 ;
}
uint32_t max_chunk = std::min((uint32_t)_map.size(),max_dist + chunk_jump) ;
uint32_t j=0 ;
for(uint32_t i=0;i<_map.size();++i)
for(uint32_t i=0;i<max_chunk;++i)
if(_map[i] == FileChunksInfo::CHUNK_OUTSTANDING && (peer_chunks->is_full || peer_chunks->cmap[i]))
{
if(j == chosen_chunk_number)

View file

@ -104,7 +104,7 @@ ftController::ftController(CacheStrapper *cs, ftDataMultiplex *dm, std::string /
ctrlMutex("ftController"),
doneMutex("ftController"),
mFtActive(false),
mDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM)
mDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE)
{
_max_active_downloads = 5 ; // default queue size
_min_prioritized_transfers = 3 ;
@ -2235,6 +2235,11 @@ bool ftController::loadConfigMap(std::map<std::string, std::string> &configMap)
setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) ;
std::cerr << "Note: loading default value for chunk strategy: random" << std::endl;
}
else if(mit->second == "PROGRESSIVE")
{
setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE) ;
std::cerr << "Note: loading default value for chunk strategy: progressive" << std::endl;
}
else
std::cerr << "**** ERROR ***: Unknown value for default chunk strategy in keymap." << std::endl ;
}

View file

@ -416,10 +416,10 @@ void ftFileCreator::setChunkStrategy(FileChunksInfo::ChunkStrategy s)
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
// Let's check, for safety.
if(s != FileChunksInfo::CHUNK_STRATEGY_STREAMING && s != FileChunksInfo::CHUNK_STRATEGY_RANDOM)
if(s != FileChunksInfo::CHUNK_STRATEGY_STREAMING && s != FileChunksInfo::CHUNK_STRATEGY_RANDOM && s != FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE)
{
std::cerr << "ftFileCreator::ERROR: invalid chunk strategy " << s << "!" << " setting default value " << FileChunksInfo::CHUNK_STRATEGY_STREAMING << std::endl ;
s = FileChunksInfo::CHUNK_STRATEGY_STREAMING ;
s = FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE ;
}
#ifdef FILE_DEBUG