take upload speed into account in round-robin choker

The unchoked peers need to be sorted by upload speed so that the slowest node
will get choked as part of optimistic unchoking.

Also change the minimum quanta to 1 minute instead of 256KB.

Also remove a useless multiply in the fastest peer choker since the priorities
are guarenteed to be equal at that point.

Fixes #1171
This commit is contained in:
Steven Siloti 2016-10-13 19:19:03 -07:00 committed by Arvid Norberg
parent 344eedb969
commit c13286b945
1 changed files with 19 additions and 13 deletions

View File

@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/choker.hpp"
#include "libtorrent/peer_connection.hpp"
#include "libtorrent/aux_/session_settings.hpp"
#include "libtorrent/aux_/time.hpp"
#include "libtorrent/torrent.hpp"
#include <boost/bind.hpp>
@ -82,21 +83,30 @@ namespace libtorrent
// if a peer is already unchoked, and the number of bytes sent since it was unchoked
// is greater than the send quanta, then it's done with it' upload slot, and we
// can de-prioritize it
bool c1_quota_complete = !lhs->is_choked() && c1
> (std::max)(t1->torrent_file().piece_length() * pieces, 256 * 1024);
bool c2_quota_complete = !rhs->is_choked() && c2
> (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024);
bool c1_quota_complete = !lhs->is_choked()
&& c1 > t1->torrent_file().piece_length() * pieces
&& aux::time_now() - lhs->time_of_last_unchoke() > minutes(1);
bool c2_quota_complete = !rhs->is_choked()
&& c2 > t2->torrent_file().piece_length() * pieces
&& aux::time_now() - rhs->time_of_last_unchoke() > minutes(1);
// if c2 has completed a quanta, it should be de-prioritized
// and vice versa
if (c1_quota_complete < c2_quota_complete) return true;
if (c1_quota_complete > c2_quota_complete) return false;
// if both peers have either completed a quanta, or not.
// keep unchoked peers prioritized over choked ones, to let
// peers keep working on uploading a full quanta
if (lhs->is_choked() < rhs->is_choked()) return true;
if (lhs->is_choked() > rhs->is_choked()) return false;
// when seeding, prefer the peer we're uploading the fastest to
// force the upload rate to zero for choked peers because
// if the peers just got choked the previous round
// there may have been a residual transfer which was already
// in-flight at the time and we don't want that to cause the peer
// to be ranked at the top of the choked peers
c1 = lhs->is_choked() ? 0 : lhs->uploaded_in_last_round();
c2 = rhs->is_choked() ? 0 : rhs->uploaded_in_last_round();
if (c1 > c2) return true;
if (c2 > c1) return false;
// if the peers are still identical (say, they're both waiting to be unchoked)
// prioritize the one that has waited the longest to be unchoked
@ -134,10 +144,6 @@ namespace libtorrent
c1 = lhs->uploaded_in_last_round();
c2 = rhs->uploaded_in_last_round();
// take torrent priority into account
c1 *= prio1;
c2 *= prio2;
if (c1 > c2) return true;
if (c2 > c1) return false;