merged fast-extension => trunk. the fast extension branch is now closed

This commit is contained in:
Arvid Norberg
2007-08-14 17:47:48 +00:00
parent a4ad8a6442
commit b62bb7944f
11 changed files with 647 additions and 81 deletions

View File

@@ -187,17 +187,18 @@ namespace libtorrent
// have only one piece that we don't have, and it's the
// same piece for both peers. Then they might get into an
// infinite loop, fighting to request the same blocks.
void request_a_block(
torrent& t
, peer_connection& c)
void request_a_block(torrent& t, peer_connection& c)
{
assert(!t.is_seed());
assert(!c.has_peer_choked());
assert(t.valid_metadata());
assert(c.peer_info_struct() != 0 || !dynamic_cast<bt_peer_connection*>(&c));
int num_requests = c.desired_queue_size()
- (int)c.download_queue().size()
- (int)c.request_queue().size();
#ifdef TORRENT_VERBOSE_LOGGING
(*c.m_logger) << time_now_string() << " PIECE_PICKER [ req: " << num_requests << " ]\n";
#endif
assert(c.desired_queue_size() > 0);
// if our request queue is already full, we
// don't have to make any new requests yet
@@ -231,18 +232,6 @@ namespace libtorrent
else if (speed == peer_connection::medium) state = piece_picker::medium;
else state = piece_picker::slow;
// picks the interesting pieces from this peer
// the integer is the number of pieces that
// should be guaranteed to be available for download
// (if num_requests is too big, too many pieces are
// picked and cpu-time is wasted)
// the last argument is if we should prefer whole pieces
// for this peer. If we're downloading one piece in 20 seconds
// then use this mode.
p.pick_pieces(c.get_bitfield(), interesting_pieces
, num_requests, prefer_whole_pieces, c.peer_info_struct()
, state, rarest_first);
// this vector is filled with the interesting pieces
// that some other peer is currently downloading
// we should then compare this peer's download speed
@@ -251,6 +240,40 @@ namespace libtorrent
std::vector<piece_block> busy_pieces;
busy_pieces.reserve(num_requests);
if (c.has_peer_choked())
{
// if we are choked we can only pick pieces from the
// allowed fast set. The allowed fast set is sorted
// in ascending priority order
std::vector<int> const& allowed_fast = c.allowed_fast();
p.add_interesting_blocks(allowed_fast, c.get_bitfield()
, interesting_pieces, busy_pieces, num_requests
, prefer_whole_pieces, c.peer_info_struct(), state
, false);
interesting_pieces.insert(interesting_pieces.end()
, busy_pieces.begin(), busy_pieces.end());
busy_pieces.clear();
}
else
{
// picks the interesting pieces from this peer
// the integer is the number of pieces that
// should be guaranteed to be available for download
// (if num_requests is too big, too many pieces are
// picked and cpu-time is wasted)
// the last argument is if we should prefer whole pieces
// for this peer. If we're downloading one piece in 20 seconds
// then use this mode.
p.pick_pieces(c.get_bitfield(), interesting_pieces
, num_requests, prefer_whole_pieces, c.peer_info_struct()
, state, rarest_first);
busy_pieces.reserve(10);
}
#ifdef TORRENT_VERBOSE_LOGGING
(*c.m_logger) << time_now_string() << " PIECE_PICKER [ picked: " << interesting_pieces.size() << " ]\n";
#endif
for (std::vector<piece_block>::iterator i = interesting_pieces.begin();
i != interesting_pieces.end(); ++i)
{
@@ -277,13 +300,13 @@ namespace libtorrent
num_requests--;
}
// in this case, we could not find any blocks
// that was free. If we couldn't find any busy
// blocks as well, we cannot download anything
// more from this peer.
if (busy_pieces.empty() || num_requests == 0)
{
// in this case, we could not find any blocks
// that was free. If we couldn't find any busy
// blocks as well, we cannot download anything
// more from this peer.
c.send_block_requests();
return;
}
@@ -970,7 +993,7 @@ namespace libtorrent
INVARIANT_CHECK;
// just ignore the obviously invalid entries
if(remote.address() == address() || remote.port() == 0)
if (remote.address() == address() || remote.port() == 0)
return;
aux::session_impl& ses = m_torrent->session();
@@ -1056,7 +1079,10 @@ namespace libtorrent
if (i->failcount > 0 && src != peer_info::dht)
--i->failcount;
if (flags & 0x02) i->seed = true;
// if we're connected to this peer
// we already know if it's a seed or not
// so we don't have to trust this source
if ((flags & 0x02) && !i->connection) i->seed = true;
if (i->connection)
{
@@ -1327,7 +1353,9 @@ namespace libtorrent
INVARIANT_CHECK;
c.send_interested();
if (c.has_peer_choked()) return;
if (c.has_peer_choked()
&& c.allowed_fast().empty())
return;
request_a_block(*m_torrent, c);
}
@@ -1353,7 +1381,7 @@ namespace libtorrent
int total_connections = 0;
int nonempty_connections = 0;
std::set<address> unique_test;
for (const_iterator i = m_peers.begin();
i != m_peers.end(); ++i)