CPU optimization for end-game piece picker

This commit is contained in:
Arvid Norberg
2011-02-09 02:56:00 +00:00
parent cfd36ca53e
commit a42d42fd11
9 changed files with 82 additions and 100 deletions

View File

@@ -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);