mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
implemented slice sharing between peers.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4650 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
8e40fd6360
commit
1fc8c5ef70
@ -84,7 +84,7 @@ ChunkMap::ChunkMap(uint64_t s,bool availability)
|
|||||||
std::cerr << " ChunkSize: " << _chunk_size << std::endl ;
|
std::cerr << " ChunkSize: " << _chunk_size << std::endl ;
|
||||||
std::cerr << " Number of Chunks: " << n << std::endl ;
|
std::cerr << " Number of Chunks: " << n << std::endl ;
|
||||||
std::cerr << " Data: " ;
|
std::cerr << " Data: " ;
|
||||||
for(int i=0;i<_map.size();++i)
|
for(uint32_t i=0;i<_map.size();++i)
|
||||||
std::cerr << _map[i] ;
|
std::cerr << _map[i] ;
|
||||||
std::cerr << std::endl ;
|
std::cerr << std::endl ;
|
||||||
#endif
|
#endif
|
||||||
@ -190,22 +190,42 @@ bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChun
|
|||||||
|
|
||||||
if(it == _active_chunks_feed.end())
|
if(it == _active_chunks_feed.end())
|
||||||
{
|
{
|
||||||
// 1 - select an available chunk id for this peer.
|
// 0 - Look into other pending chunks and slice from here.
|
||||||
//
|
//
|
||||||
uint32_t c = getAvailableChunk(peer_id,source_chunk_map_needed) ;
|
for(std::map<std::string,Chunk>::iterator pit(_active_chunks_feed.begin());pit!=_active_chunks_feed.end();++pit)
|
||||||
|
{
|
||||||
|
SourceChunksInfo *sci = getSourceChunksInfo(pit->first) ;
|
||||||
|
|
||||||
if(c >= _map.size())
|
if(sci->is_full || sci->cmap[pit->second._start / _chunk_size])
|
||||||
return false ;
|
{
|
||||||
|
it = pit ;
|
||||||
// 2 - add the chunk in the list of active chunks, and mark it as being downloaded
|
|
||||||
//
|
|
||||||
uint32_t soc = sizeOfChunk(c) ;
|
|
||||||
_active_chunks_feed[peer_id] = Chunk( c*(uint64_t)_chunk_size, soc ) ;
|
|
||||||
_map[c] = FileChunksInfo::CHUNK_ACTIVE ;
|
|
||||||
_slices_to_download[c]._remains = soc ; // init the list of slices to download
|
|
||||||
#ifdef DEBUG_FTCHUNK
|
#ifdef DEBUG_FTCHUNK
|
||||||
std::cout << "*** ChunkMap::getDataChunk: Allocating new chunk " << c << " for peer " << peer_id << std::endl ;
|
std::cerr << "*** ChunkMap::getDataChunk: Sharing slice " << pit->second._start << " of peer " << pit->first << " for peer " << peer_id << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(it == _active_chunks_feed.end()) // nor 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 ;
|
||||||
|
|
||||||
|
// 2 - add the chunk in the list of active chunks, and mark it as being downloaded
|
||||||
|
//
|
||||||
|
uint32_t soc = sizeOfChunk(c) ;
|
||||||
|
_active_chunks_feed[peer_id] = Chunk( c*(uint64_t)_chunk_size, soc ) ;
|
||||||
|
_map[c] = FileChunksInfo::CHUNK_ACTIVE ;
|
||||||
|
_slices_to_download[c]._remains = soc ; // init the list of slices to download
|
||||||
|
it = _active_chunks_feed.find(peer_id) ;
|
||||||
|
#ifdef DEBUG_FTCHUNK
|
||||||
|
std::cout << "*** ChunkMap::getDataChunk: Allocating new chunk " << c << " for peer " << peer_id << std::endl ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_FTCHUNK
|
#ifdef DEBUG_FTCHUNK
|
||||||
else
|
else
|
||||||
@ -214,16 +234,17 @@ bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChun
|
|||||||
|
|
||||||
// Get the first slice of the chunk, that is at most of length size
|
// Get the first slice of the chunk, that is at most of length size
|
||||||
//
|
//
|
||||||
_active_chunks_feed[peer_id].getSlice(size_hint,chunk) ;
|
it->second.getSlice(size_hint,chunk) ;
|
||||||
_slices_to_download[chunk.offset/_chunk_size]._slices[chunk.id] = chunk.size ;
|
_slices_to_download[chunk.offset/_chunk_size]._slices[chunk.id] = chunk.size ;
|
||||||
_slices_to_download[chunk.offset/_chunk_size]._last_data_received = time(NULL) ;
|
_slices_to_download[chunk.offset/_chunk_size]._last_data_received = time(NULL) ;
|
||||||
|
|
||||||
if(_active_chunks_feed[peer_id].empty())
|
|
||||||
_active_chunks_feed.erase(_active_chunks_feed.find(peer_id)) ;
|
|
||||||
|
|
||||||
chunk.peer_id = peer_id ;
|
chunk.peer_id = peer_id ;
|
||||||
|
|
||||||
|
if(it->second.empty())
|
||||||
|
_active_chunks_feed.erase(it) ;
|
||||||
|
|
||||||
#ifdef DEBUG_FTCHUNK
|
#ifdef DEBUG_FTCHUNK
|
||||||
std::cout << "*** ChunkMap::getDataChunk: returning slice " << chunk << " for peer " << peer_id << std::endl ;
|
std::cout << "*** ChunkMap::getDataChunk: returning slice " << chunk << " for peer " << it->first << std::endl ;
|
||||||
#endif
|
#endif
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@ -336,12 +357,9 @@ uint32_t ChunkMap::sizeOfChunk(uint32_t cid) const
|
|||||||
return _chunk_size ;
|
return _chunk_size ;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ChunkMap::getAvailableChunk(const std::string& peer_id,bool& map_is_too_old)
|
SourceChunksInfo *ChunkMap::getSourceChunksInfo(const std::string& peer_id)
|
||||||
{
|
{
|
||||||
// Quite simple strategy: Check for 1st availabe chunk for this peer starting from the given start location.
|
|
||||||
//
|
|
||||||
std::map<std::string,SourceChunksInfo>::iterator it(_peers_chunks_availability.find(peer_id)) ;
|
std::map<std::string,SourceChunksInfo>::iterator it(_peers_chunks_availability.find(peer_id)) ;
|
||||||
SourceChunksInfo *peer_chunks = NULL;
|
|
||||||
|
|
||||||
// Do we have a chunk map for this file source ?
|
// Do we have a chunk map for this file source ?
|
||||||
// - if yes, we use it
|
// - if yes, we use it
|
||||||
@ -375,7 +393,14 @@ uint32_t ChunkMap::getAvailableChunk(const std::string& peer_id,bool& map_is_too
|
|||||||
|
|
||||||
it = _peers_chunks_availability.find(peer_id) ;
|
it = _peers_chunks_availability.find(peer_id) ;
|
||||||
}
|
}
|
||||||
peer_chunks = &(it->second) ;
|
return &(it->second) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ChunkMap::getAvailableChunk(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.
|
||||||
|
//
|
||||||
|
SourceChunksInfo *peer_chunks = getSourceChunksInfo(peer_id) ;
|
||||||
|
|
||||||
// If the info is too old, we ask for a new one. When the map is full, we ask 10 times less, as it's probably not
|
// If the info is too old, we ask for a new one. When the map is full, we ask 10 times less, as it's probably not
|
||||||
// useful to get a new map that will also be full, but because we need to be careful not to mislead information,
|
// useful to get a new map that will also be full, but because we need to be careful not to mislead information,
|
||||||
|
@ -157,6 +157,11 @@ class ChunkMap
|
|||||||
//
|
//
|
||||||
void setPeerAvailabilityMap(const std::string& peer_id,const CompressedChunkMap& peer_map) ;
|
void setPeerAvailabilityMap(const std::string& peer_id,const CompressedChunkMap& peer_map) ;
|
||||||
|
|
||||||
|
/// Returns a pointer to the availability chunk map of the given source, and possibly
|
||||||
|
/// allocates it if necessary.
|
||||||
|
//
|
||||||
|
SourceChunksInfo *getSourceChunksInfo(const std::string& peer_id) ;
|
||||||
|
|
||||||
/// 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 ; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user