made seeding choking algorithm configurable

This commit is contained in:
Arvid Norberg 2010-10-09 21:11:03 +00:00
parent 6bb688f699
commit e494cb219b
5 changed files with 79 additions and 20 deletions

View File

@ -1,3 +1,4 @@
* made seeding choking algorithm configurable
* deprecated setters for max connections, max half-open, upload and download * deprecated setters for max connections, max half-open, upload and download
rates and unchoke slots. These are now set through session_settings rates and unchoke slots. These are now set through session_settings
* added functions to query an individual peer's upload and download limit * added functions to query an individual peer's upload and download limit

View File

@ -3713,6 +3713,14 @@ session_settings
int choking_algorithm; int choking_algorithm;
enum seed_choking_algorithm_t
{
round_robin,
fastest_upload
};
int seed_choking_algorithm;
bool use_parole_mode; bool use_parole_mode;
int cache_size; int cache_size;
int cache_buffer_chunk_size; int cache_buffer_chunk_size;
@ -4064,6 +4072,16 @@ The options for choking algorithms are:
.. _paper: http://bittyrant.cs.washington.edu/#papers .. _paper: http://bittyrant.cs.washington.edu/#papers
``seed_choking_algorithm`` controls the seeding unchoke behavior. The available
options are:
* ``round_robin`` which round-robins the peers that are unchoked when seeding. This
distributes the upload bandwidht uniformly and fairly. It minimizes the ability
for a peer to download everything without redistributing it.
* ``fastest_upload`` unchokes the peers we can send to the fastest. This might be
a bit more reliable in utilizing all available capacity.
``use_parole_mode`` specifies if parole mode should be used. Parole mode means ``use_parole_mode`` specifies if parole mode should be used. Parole mode means
that peers that participate in pieces that fail the hash check are put in a mode that peers that participate in pieces that fail the hash check are put in a mode
where they are only allowed to download whole pieces. If the whole piece a peer where they are only allowed to download whole pieces. If the whole piece a peer

View File

@ -136,6 +136,7 @@ namespace libtorrent
, auto_upload_slots_rate_based(true) , auto_upload_slots_rate_based(true)
#endif #endif
, choking_algorithm(rate_based_choker) , choking_algorithm(rate_based_choker)
, seed_choking_algorithm(round_robin)
, use_parole_mode(true) , use_parole_mode(true)
, cache_size(1024) , cache_size(1024)
, cache_buffer_chunk_size(16) , cache_buffer_chunk_size(16)
@ -460,6 +461,15 @@ namespace libtorrent
}; };
int choking_algorithm; int choking_algorithm;
enum seed_choking_algorithm_t
{
round_robin,
fastest_upload
};
// the choking algorithm to use for seeding torrents
int seed_choking_algorithm;
// if set to true, peers that participate in a failing // if set to true, peers that participate in a failing
// piece is put in parole mode. i.e. They will only // piece is put in parole mode. i.e. They will only

View File

@ -398,15 +398,30 @@ namespace libtorrent
if (d1 > d2) return true; if (d1 > d2) return true;
if (d1 < d2) return false; if (d1 < d2) return false;
// in order to not switch back and forth too often, if (m_ses.settings().seed_choking_algorithm == session_settings::round_robin)
// unchoked peers must be at least one piece ahead {
// of a choked peer to be sorted at a lower unchoke-priority // in order to not switch back and forth too often,
int pieces = m_ses.settings().seeding_piece_quota; // unchoked peers must be at least one piece ahead
bool c1_done = is_choked() || u1 > (std::max)(t1->torrent_file().piece_length() * pieces, 256 * 1024); // of a choked peer to be sorted at a lower unchoke-priority
bool c2_done = rhs.is_choked() || u2 > (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024); int pieces = m_ses.settings().seeding_piece_quota;
bool c1_done = is_choked() || u1 > (std::max)(t1->torrent_file().piece_length() * pieces, 256 * 1024);
bool c2_done = rhs.is_choked() || u2 > (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024);
if (!c1_done && c2_done) return true; if (!c1_done && c2_done) return true;
if (c1_done && !c2_done) return false; if (c1_done && !c2_done) return false;
}
else if (m_ses.settings().seed_choking_algorithm == session_settings::fastest_upload)
{
size_type c1 = m_statistics.total_payload_upload() - m_uploaded_at_last_unchoke;
size_type c2 = rhs.m_statistics.total_payload_upload() - rhs.m_uploaded_at_last_unchoke;
// take torrent priority into account
c1 *= 1 + t1->priority();
c2 *= 1 + t2->priority();
if (c1 > c2) return true;
if (c2 > c1) return false;
}
// if both peers are still in their send quota or not in their send quota // if both peers are still in their send quota or not in their send quota
// prioritize the one that has waited the longest to be unchoked // prioritize the one that has waited the longest to be unchoked
@ -437,20 +452,34 @@ namespace libtorrent
if (c1 > c2) return true; if (c1 > c2) return true;
if (c1 < c2) return false; if (c1 < c2) return false;
// if they are equal, compare how much we have uploaded if (m_ses.settings().seed_choking_algorithm == session_settings::round_robin)
c1 = m_statistics.total_payload_upload() - m_uploaded_at_last_unchoke; {
c2 = rhs.m_statistics.total_payload_upload() - rhs.m_uploaded_at_last_unchoke; // if they are equal, compare how much we have uploaded
c1 = m_statistics.total_payload_upload() - m_uploaded_at_last_unchoke;
c2 = rhs.m_statistics.total_payload_upload() - rhs.m_uploaded_at_last_unchoke;
// in order to not switch back and forth too often, // in order to not switch back and forth too often,
// unchoked peers must be at least one piece ahead // unchoked peers must be at least one piece ahead
// of a choked peer to be sorted at a lower unchoke-priority // of a choked peer to be sorted at a lower unchoke-priority
int pieces = m_ses.settings().seeding_piece_quota; int pieces = m_ses.settings().seeding_piece_quota;
bool c1_done = is_choked() || c1 > (std::max)(t1->torrent_file().piece_length() * pieces, 256 * 1024); bool c1_done = is_choked() || c1 > (std::max)(t1->torrent_file().piece_length() * pieces, 256 * 1024);
bool c2_done = rhs.is_choked() || c2 > (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024); bool c2_done = rhs.is_choked() || c2 > (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024);
if (!c1_done && c2_done) return true; if (!c1_done && c2_done) return true;
if (c1_done && !c2_done) return false; if (c1_done && !c2_done) return false;
}
else if (m_ses.settings().seed_choking_algorithm == session_settings::fastest_upload)
{
c1 = m_statistics.total_payload_upload() - m_uploaded_at_last_unchoke;
c2 = rhs.m_statistics.total_payload_upload() - rhs.m_uploaded_at_last_unchoke;
// take torrent priority into account
c1 *= 1 + t1->priority();
c2 *= 1 + t2->priority();
if (c1 > c2) return true;
if (c2 > c1) return false;
}
// if both peers have are still in their send quota or not in their send quota // if both peers have are still in their send quota or not in their send quota
// prioritize the one that has waited the longest to be unchoked // prioritize the one that has waited the longest to be unchoked
return m_last_unchoke < rhs.m_last_unchoke; return m_last_unchoke < rhs.m_last_unchoke;

View File

@ -242,6 +242,7 @@ namespace aux {
TORRENT_SETTING(boolean, auto_upload_slots_rate_based) TORRENT_SETTING(boolean, auto_upload_slots_rate_based)
#endif #endif
TORRENT_SETTING(integer, choking_algorithm) TORRENT_SETTING(integer, choking_algorithm)
TORRENT_SETTING(integer, seed_choking_algorithm)
TORRENT_SETTING(boolean, use_parole_mode) TORRENT_SETTING(boolean, use_parole_mode)
TORRENT_SETTING(integer, cache_size) TORRENT_SETTING(integer, cache_size)
TORRENT_SETTING(integer, cache_buffer_chunk_size) TORRENT_SETTING(integer, cache_buffer_chunk_size)
@ -2870,7 +2871,7 @@ namespace aux {
if (m_settings.choking_algorithm == session_settings::bittyrant_choker) if (m_settings.choking_algorithm == session_settings::bittyrant_choker)
{ {
if (!p->is_choked()) if (!p->is_choked() && p->is_interesting())
{ {
policy::peer* pi = p->peer_info_struct(); policy::peer* pi = p->peer_info_struct();
if (!p->has_peer_choked()) if (!p->has_peer_choked())