improve queuing logic of inactive torrents (dont_count_slow_torrents)

This commit is contained in:
Arvid Norberg 2014-05-18 22:17:51 +00:00
parent 3e25e56f0e
commit a1e7d3229d
6 changed files with 88 additions and 34 deletions

View File

@ -1,5 +1,6 @@
1.0 release
* improve queuing logic of inactive torrents (dont_count_slow_torrents)
* expose optimistic unchoke logic to plugins
* fix issue with large UDP packets on windows
* remove set_ratio() feature

View File

@ -1383,6 +1383,15 @@ namespace libtorrent
// side effect that the disk cache is less likely and slower at returning
// memory to the kernel when cache pressure is low.
bool use_disk_cache_pool;
// the download and upload rate limits for a torrent to be considered
// active by the queuing mechanism. A torrent whose download rate is less
// than ``inactive_down_rate`` and whose upload rate is less than
// ``inactive_up_rate`` for ``auto_manage_startup`` seconds, is
// considered inactive, and another queued torrent may be startert.
// This logic is disabled if ``dont_count_slow_torrents`` is false.
int inactive_down_rate;
int inactive_up_rate;
};
// structure used to hold configuration options for the DHT

View File

@ -736,6 +736,9 @@ namespace libtorrent
- m_picker->num_have() - m_picker->num_filtered() == 0;
}
bool is_inactive() const
{ return m_inactive; }
std::string save_path() const;
alert_manager& alerts() const;
piece_picker& picker()
@ -1333,7 +1336,10 @@ namespace libtorrent
// set to true while moving the storage
bool m_moving_storage:1;
// TODO: there's space for another bit here
// this is true if this torrent is considered inactive from the
// queuing mechanism's point of view. If a torrent doesn't transfer
// at high enough rates, it's inactive.
bool m_inactive:1;
// ----
@ -1402,6 +1408,13 @@ namespace libtorrent
// millionths of completeness)
unsigned int m_progress_ppm:20;
// the number of seconds this torrent has been under the inactive
// threshold in terms of sending and receiving data. When this counter
// reaches the settings.inactive_torrent_timeout it will be considered
// inactive and possibly open up another queue slot, to start another,
// queued, torrent. Every second it's above the threshold
boost::int16_t m_inactive_counter;
#if TORRENT_USE_ASSERTS
public:
// set to false until we've loaded resume data

View File

@ -1316,7 +1316,7 @@ namespace libtorrent
, max_paused_peerlist_size(4000)
, min_announce_interval(5 * 60)
, prioritize_partial_pieces(false)
, auto_manage_startup(120)
, auto_manage_startup(60)
, rate_limit_ip_overhead(true)
, announce_to_all_trackers(false)
, announce_to_all_tiers(false)
@ -1415,6 +1415,8 @@ namespace libtorrent
, support_merkle_torrents(false)
, report_redundant_bytes(true)
, use_disk_cache_pool(false)
, inactive_down_rate(2048)
, inactive_up_rate(2048)
{}
session_settings::~session_settings() {}

View File

@ -4181,24 +4181,6 @@ retry:
m_next_lsd_torrent = m_torrents.begin();
}
namespace
{
bool is_active(torrent* t, session_settings const& s)
{
// if we count slow torrents, every torrent
// is considered active
if (!s.dont_count_slow_torrents) return true;
// if the torrent started less than 2 minutes
// ago (default), let it count as active since
// the rates are probably not accurate yet
if (time_now() - t->started() < seconds(s.auto_manage_startup)) return true;
return t->statistics().upload_payload_rate() != 0.f
|| t->statistics().download_payload_rate() != 0.f;
}
}
void session_impl::auto_manage_torrents(std::vector<torrent*>& list
, int& dht_limit, int& tracker_limit, int& lsd_limit
, int& hard_limit, int type_limit)
@ -4212,20 +4194,6 @@ retry:
|| t->state() == torrent_status::queued_for_checking))
continue;
--dht_limit;
--lsd_limit;
--tracker_limit;
t->set_announce_to_dht(dht_limit >= 0);
t->set_announce_to_trackers(tracker_limit >= 0);
t->set_announce_to_lsd(lsd_limit >= 0);
if (!t->is_paused() && !is_active(t, settings())
&& hard_limit > 0)
{
--hard_limit;
continue;
}
if (type_limit > 0 && hard_limit > 0)
{
--hard_limit;
@ -4234,6 +4202,21 @@ retry:
t->log_to_all_peers("AUTO MANAGER STARTING TORRENT");
#endif
t->set_allow_peers(true);
--dht_limit;
--lsd_limit;
--tracker_limit;
t->set_announce_to_dht(dht_limit >= 0);
t->set_announce_to_trackers(tracker_limit >= 0);
t->set_announce_to_lsd(lsd_limit >= 0);
if (!t->is_paused() && t->is_inactive()
&& hard_limit > 0)
{
// the hard limit takes inactive torrents into account, but the
// download and seed limits don't.
continue;
}
}
else
{

View File

@ -232,6 +232,7 @@ namespace libtorrent
, m_ssl_torrent(false)
, m_deleted(false)
, m_moving_storage(false)
, m_inactive(false)
, m_incomplete(0xffffff)
, m_abort(false)
, m_announce_to_dht((p.flags & add_torrent_params::flag_paused) == 0)
@ -247,6 +248,7 @@ namespace libtorrent
, m_downloaded(0xffffff)
, m_interface_index(0)
, m_progress_ppm(0)
, m_inactive_counter(0)
{
// if there is resume data already, we don't need to trigger the initial save
// resume data
@ -7351,6 +7353,8 @@ namespace libtorrent
}
#endif
m_inactive = false;
state_updated();
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || defined TORRENT_LOGGING
@ -7846,6 +7850,48 @@ namespace libtorrent
// if the rate is 0, there's no update because of network transfers
if (m_stat.low_pass_upload_rate() > 0 || m_stat.low_pass_download_rate() > 0)
state_updated();
// this section determines whether the torrent is active or not. When it
// changes state, it may also trigger the auto-manage logic to reconsider
// which torrents should be queued and started. There is a low pass
// filter in order to avoid flapping (auto_manage_startup).
if (m_stat.download_payload_rate() < m_ses.m_settings.inactive_down_rate
&& m_stat.upload_payload_rate() < m_ses.m_settings.inactive_up_rate)
{
if (m_inactive_counter < 0) m_inactive_counter = 0;
if (m_inactive_counter < INT16_MAX)
{
++m_inactive_counter;
// if this torrent was just considered inactive, we may want
// to dequeue some other torrent
if (m_inactive == false
&& m_inactive_counter >= m_ses.m_settings.auto_manage_startup)
{
m_inactive = true;
if (m_ses.m_settings.dont_count_slow_torrents)
m_ses.trigger_auto_manage();
}
}
}
else
{
if (m_inactive_counter > 0) m_inactive_counter = 0;
if (m_inactive_counter > INT16_MIN)
{
--m_inactive_counter;
// if this torrent was just considered active, we may want
// to queue some other torrent
if (m_inactive == true
&& m_inactive_counter <= -m_ses.m_settings.auto_manage_startup)
{
m_inactive = false;
if (m_ses.m_settings.dont_count_slow_torrents)
m_ses.trigger_auto_manage();
}
}
}
}
void torrent::maybe_connect_web_seeds()