CPU optimization for end-game piece picker
This commit is contained in:
@@ -1578,6 +1578,7 @@ namespace libtorrent
|
||||
// don't double-pick anything if the peer is on parole
|
||||
if (options & on_parole) return;
|
||||
|
||||
std::vector<piece_block> temp;
|
||||
for (std::vector<downloading_piece>::const_iterator i = m_downloads.begin()
|
||||
, end(m_downloads.end()); i != end; ++i)
|
||||
{
|
||||
@@ -1588,16 +1589,24 @@ namespace libtorrent
|
||||
|
||||
// fill in with blocks requested from other peers
|
||||
// as backups
|
||||
bool done = false;
|
||||
for (int j = 0; j < num_blocks_in_piece; ++j)
|
||||
{
|
||||
block_info const& info = i->info[j];
|
||||
if (info.state != block_info::state_requested
|
||||
|| info.peer == peer)
|
||||
continue;
|
||||
interesting_blocks.push_back(piece_block(i->index, j));
|
||||
if (info.num_peers >= 2) continue;
|
||||
temp.push_back(piece_block(i->index, j));
|
||||
done = true;
|
||||
}
|
||||
if (done) break;
|
||||
}
|
||||
|
||||
// pick one random block from the first busy piece we encountered
|
||||
// none of these blocks have more than one request to them
|
||||
if (!temp.empty()) interesting_blocks.push_back(temp[rand() % temp.size()]);
|
||||
|
||||
#ifdef TORRENT_DEBUG
|
||||
// make sure that we at this point have added requests to all unrequested blocks
|
||||
// in all downloading pieces
|
||||
@@ -1668,6 +1677,16 @@ namespace libtorrent
|
||||
|
||||
}
|
||||
|
||||
int piece_picker::blocks_in_piece(int index) const
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0);
|
||||
TORRENT_ASSERT(index < (int)m_piece_map.size());
|
||||
if (index+1 == (int)m_piece_map.size())
|
||||
return m_blocks_in_last_piece;
|
||||
else
|
||||
return m_blocks_per_piece;
|
||||
}
|
||||
|
||||
bool piece_picker::is_piece_free(int piece, bitfield const& bitmask) const
|
||||
{
|
||||
TORRENT_ASSERT(piece >= 0 && piece < int(m_piece_map.size()));
|
||||
@@ -1839,8 +1858,6 @@ namespace libtorrent
|
||||
block_info const& info = dp.info[j];
|
||||
if (info.state != block_info::state_none) continue;
|
||||
|
||||
TORRENT_ASSERT(dp.info[j].state == block_info::state_none);
|
||||
|
||||
// if the piece is fast and the peer is slow, or vice versa,
|
||||
// add the block as a backup.
|
||||
// override this behavior if all the other blocks
|
||||
@@ -2012,8 +2029,8 @@ namespace libtorrent
|
||||
if (prio >= 0 && !m_dirty) update(prio, p.index);
|
||||
|
||||
downloading_piece& dp = add_download_piece();
|
||||
dp.state = state;
|
||||
dp.index = block.piece_index;
|
||||
dp.state = state;
|
||||
block_info& info = dp.info[block.block_index];
|
||||
info.state = block_info::state_requested;
|
||||
info.peer = peer;
|
||||
@@ -2091,6 +2108,9 @@ namespace libtorrent
|
||||
piece_pos& p = m_piece_map[block.piece_index];
|
||||
if (p.downloading == 0)
|
||||
{
|
||||
// if we already have this piece, just ignore this
|
||||
if (have_piece(block.piece_index)) return false;
|
||||
|
||||
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
#endif
|
||||
@@ -2195,6 +2215,9 @@ namespace libtorrent
|
||||
|
||||
if (p.downloading == 0)
|
||||
{
|
||||
// if we already have this piece, just ignore this
|
||||
if (have_piece(block.piece_index)) return;
|
||||
|
||||
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
#endif
|
||||
@@ -2207,8 +2230,8 @@ namespace libtorrent
|
||||
if (prio >= 0 && !m_dirty) update(prio, p.index);
|
||||
|
||||
downloading_piece& dp = add_download_piece();
|
||||
dp.state = none;
|
||||
dp.index = block.piece_index;
|
||||
dp.state = none;
|
||||
block_info& info = dp.info[block.block_index];
|
||||
info.peer = peer;
|
||||
TORRENT_ASSERT(info.state == block_info::state_none);
|
||||
|
Reference in New Issue
Block a user