forked from premiere/premiere-libtorrent
made seeding choking algorithm configurable
This commit is contained in:
parent
6bb688f699
commit
e494cb219b
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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())
|
||||||
|
|
Loading…
Reference in New Issue