keep counters of the number of active downloading and finished torrents in order to have a cheap way of prioritizing peer connections for downloading torrents over finished ones
This commit is contained in:
@@ -515,6 +515,19 @@ namespace libtorrent
|
|||||||
--m_disk_queues[channel];
|
--m_disk_queues[channel];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void inc_active_downloading() { ++m_num_active_downloading; }
|
||||||
|
void dec_active_downloading()
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(m_num_active_downloading > 0);
|
||||||
|
--m_num_active_downloading;
|
||||||
|
}
|
||||||
|
void inc_active_finished() { ++m_num_active_finished; }
|
||||||
|
void dec_active_finished()
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(m_num_active_finished > 0);
|
||||||
|
--m_num_active_finished;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
||||||
bool in_state_updates(boost::shared_ptr<torrent> t)
|
bool in_state_updates(boost::shared_ptr<torrent> t)
|
||||||
{
|
{
|
||||||
@@ -681,6 +694,13 @@ namespace libtorrent
|
|||||||
torrent_map m_torrents;
|
torrent_map m_torrents;
|
||||||
std::map<std::string, boost::shared_ptr<torrent> > m_uuids;
|
std::map<std::string, boost::shared_ptr<torrent> > m_uuids;
|
||||||
|
|
||||||
|
// counters of how many of the active (non-paused) torrents
|
||||||
|
// are finished and downloading. This is used to weigh the
|
||||||
|
// priority of downloading and finished torrents when connecting
|
||||||
|
// more peers.
|
||||||
|
int m_num_active_downloading;
|
||||||
|
int m_num_active_finished;
|
||||||
|
|
||||||
typedef std::list<boost::shared_ptr<torrent> > check_queue_t;
|
typedef std::list<boost::shared_ptr<torrent> > check_queue_t;
|
||||||
|
|
||||||
// this has all torrents that wants to be checked in it
|
// this has all torrents that wants to be checked in it
|
||||||
|
@@ -260,6 +260,20 @@ namespace libtorrent
|
|||||||
void force_recheck();
|
void force_recheck();
|
||||||
void save_resume_data(int flags);
|
void save_resume_data(int flags);
|
||||||
|
|
||||||
|
bool is_active_download() const
|
||||||
|
{
|
||||||
|
return (m_state == torrent_status::downloading
|
||||||
|
|| m_state == torrent_status::downloading_metadata)
|
||||||
|
&& m_allow_peers;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_active_finished() const
|
||||||
|
{
|
||||||
|
return (m_state == torrent_status::finished
|
||||||
|
|| m_state == torrent_status::seeding)
|
||||||
|
&& m_allow_peers;
|
||||||
|
}
|
||||||
|
|
||||||
bool need_save_resume_data() const
|
bool need_save_resume_data() const
|
||||||
{
|
{
|
||||||
// save resume data every 15 minutes regardless, just to
|
// save resume data every 15 minutes regardless, just to
|
||||||
|
@@ -610,6 +610,8 @@ namespace aux {
|
|||||||
, m_upload_rate(peer_connection::upload_channel)
|
, m_upload_rate(peer_connection::upload_channel)
|
||||||
#endif
|
#endif
|
||||||
, m_tracker_manager(*this, m_proxy)
|
, m_tracker_manager(*this, m_proxy)
|
||||||
|
, m_num_active_downloading(0)
|
||||||
|
, m_num_active_finished(0)
|
||||||
, m_listen_port_retries(listen_port_range.second - listen_port_range.first)
|
, m_listen_port_retries(listen_port_range.second - listen_port_range.first)
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
, m_i2p_conn(m_io_service)
|
, m_i2p_conn(m_io_service)
|
||||||
@@ -3430,16 +3432,17 @@ namespace aux {
|
|||||||
torrent& t = *m_next_connect_torrent->second;
|
torrent& t = *m_next_connect_torrent->second;
|
||||||
if (t.want_more_peers())
|
if (t.want_more_peers())
|
||||||
{
|
{
|
||||||
|
TORRENT_ASSERT(t.allows_peers());
|
||||||
// have a bias to give more connection attempts
|
// have a bias to give more connection attempts
|
||||||
// to downloading torrents than seed, and even
|
// to downloading torrents than seed, and even
|
||||||
// more to downloading torrents with less than
|
// more to downloading torrents with less than
|
||||||
// average number of connections
|
// average number of connections
|
||||||
int num_attempts = 1;
|
int num_attempts = 1;
|
||||||
if (!t.is_seed())
|
if (!t.is_finished())
|
||||||
{
|
{
|
||||||
++num_attempts;
|
// TODO: make this bias configurable
|
||||||
if (t.num_peers() < average_peers)
|
TORRENT_ASSERT(m_num_active_downloading > 0);
|
||||||
++num_attempts;
|
num_attempts += m_num_active_finished / m_num_active_downloading;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < num_attempts; ++i)
|
for (int i = 0; i < num_attempts; ++i)
|
||||||
{
|
{
|
||||||
@@ -4209,6 +4212,8 @@ namespace aux {
|
|||||||
|
|
||||||
void session_impl::recalculate_auto_managed_torrents()
|
void session_impl::recalculate_auto_managed_torrents()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
// these vectors are filled with auto managed torrents
|
// these vectors are filled with auto managed torrents
|
||||||
std::vector<torrent*> downloaders;
|
std::vector<torrent*> downloaders;
|
||||||
downloaders.reserve(m_torrents.size());
|
downloaders.reserve(m_torrents.size());
|
||||||
@@ -4301,7 +4306,6 @@ namespace aux {
|
|||||||
auto_manage_torrents(seeds, dht_limit, tracker_limit, lsd_limit
|
auto_manage_torrents(seeds, dht_limit, tracker_limit, lsd_limit
|
||||||
, hard_limit, num_seeds);
|
, hard_limit, num_seeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::recalculate_optimistic_unchoke_slots()
|
void session_impl::recalculate_optimistic_unchoke_slots()
|
||||||
@@ -4996,6 +5000,8 @@ namespace aux {
|
|||||||
|
|
||||||
void session_impl::remove_torrent(const torrent_handle& h, int options)
|
void session_impl::remove_torrent(const torrent_handle& h, int options)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
boost::shared_ptr<torrent> tptr = h.m_torrent.lock();
|
boost::shared_ptr<torrent> tptr = h.m_torrent.lock();
|
||||||
if (!tptr) return;
|
if (!tptr) return;
|
||||||
|
|
||||||
@@ -5037,6 +5043,13 @@ namespace aux {
|
|||||||
if (options & session::delete_files)
|
if (options & session::delete_files)
|
||||||
t.delete_files();
|
t.delete_files();
|
||||||
|
|
||||||
|
bool is_active_download = tptr->is_active_download();
|
||||||
|
bool is_active_finished = tptr->is_active_finished();
|
||||||
|
|
||||||
|
// update finished and downloading counters
|
||||||
|
if (is_active_download) dec_active_downloading();
|
||||||
|
if (is_active_finished) dec_active_finished();
|
||||||
|
|
||||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
||||||
sha1_hash i_hash = t.torrent_file().info_hash();
|
sha1_hash i_hash = t.torrent_file().info_hash();
|
||||||
#endif
|
#endif
|
||||||
@@ -6064,20 +6077,29 @@ namespace aux {
|
|||||||
// TORRENT_ASSERT(m_queued_for_checking.size() == num_queued_for_checking);
|
// TORRENT_ASSERT(m_queued_for_checking.size() == num_queued_for_checking);
|
||||||
|
|
||||||
std::set<int> unique;
|
std::set<int> unique;
|
||||||
|
int num_active_downloading = 0;
|
||||||
|
int num_active_finished = 0;
|
||||||
int total_downloaders = 0;
|
int total_downloaders = 0;
|
||||||
for (torrent_map::const_iterator i = m_torrents.begin()
|
for (torrent_map::const_iterator i = m_torrents.begin()
|
||||||
, end(m_torrents.end()); i != end; ++i)
|
, end(m_torrents.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
int pos = i->second->queue_position();
|
boost::shared_ptr<torrent> t = i->second;
|
||||||
|
if (t->is_active_download()) ++num_active_downloading;
|
||||||
|
else if (t->is_active_finished()) ++num_active_finished;
|
||||||
|
|
||||||
|
int pos = t->queue_position();
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(pos == -1);
|
TORRENT_ASSERT(pos == -1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++total_downloaders;
|
++total_downloaders;
|
||||||
unique.insert(i->second->queue_position());
|
|
||||||
|
unique.insert(t->queue_position());
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(int(unique.size()) == total_downloaders);
|
TORRENT_ASSERT(int(unique.size()) == total_downloaders);
|
||||||
|
TORRENT_ASSERT(num_active_downloading == m_num_active_downloading);
|
||||||
|
TORRENT_ASSERT(num_active_finished == m_num_active_finished);
|
||||||
|
|
||||||
std::set<peer_connection*> unique_peers;
|
std::set<peer_connection*> unique_peers;
|
||||||
TORRENT_ASSERT(m_settings.connections_limit > 0);
|
TORRENT_ASSERT(m_settings.connections_limit > 0);
|
||||||
|
@@ -441,6 +441,10 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (!m_apply_ip_filter) ++m_ses.m_non_filtered_torrents;
|
if (!m_apply_ip_filter) ++m_ses.m_non_filtered_torrents;
|
||||||
|
|
||||||
|
// update finished and downloading counters
|
||||||
|
if (is_active_download()) m_ses.inc_active_downloading();
|
||||||
|
if (is_active_finished()) m_ses.inc_active_finished();
|
||||||
|
|
||||||
if (!p.ti || !p.ti->is_valid())
|
if (!p.ti || !p.ti->is_valid())
|
||||||
{
|
{
|
||||||
// we don't have metadata for this torrent. We'll download
|
// we don't have metadata for this torrent. We'll download
|
||||||
@@ -5059,7 +5063,7 @@ namespace libtorrent
|
|||||||
int paused_ = rd.dict_find_int_value("paused", -1);
|
int paused_ = rd.dict_find_int_value("paused", -1);
|
||||||
if (paused_ != -1)
|
if (paused_ != -1)
|
||||||
{
|
{
|
||||||
m_allow_peers = !paused_;
|
set_allow_peers(!paused_);
|
||||||
m_announce_to_dht = !paused_;
|
m_announce_to_dht = !paused_;
|
||||||
m_announce_to_trackers = !paused_;
|
m_announce_to_trackers = !paused_;
|
||||||
m_announce_to_lsd = !paused_;
|
m_announce_to_lsd = !paused_;
|
||||||
@@ -7002,7 +7006,7 @@ namespace libtorrent
|
|||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (!m_allow_peers) return;
|
if (!m_allow_peers) return;
|
||||||
if (!graceful) m_allow_peers = false;
|
if (!graceful) set_allow_peers(false);
|
||||||
m_announce_to_dht = false;
|
m_announce_to_dht = false;
|
||||||
m_announce_to_trackers = false;
|
m_announce_to_trackers = false;
|
||||||
m_announce_to_lsd = false;
|
m_announce_to_lsd = false;
|
||||||
@@ -7134,10 +7138,19 @@ namespace libtorrent
|
|||||||
if (m_allow_peers == b
|
if (m_allow_peers == b
|
||||||
&& m_graceful_pause_mode == graceful) return;
|
&& m_graceful_pause_mode == graceful) return;
|
||||||
|
|
||||||
|
bool was_active_download = is_active_download();
|
||||||
|
bool was_active_finished = is_active_finished();
|
||||||
|
|
||||||
m_allow_peers = b;
|
m_allow_peers = b;
|
||||||
if (!m_ses.is_paused())
|
if (!m_ses.is_paused())
|
||||||
m_graceful_pause_mode = graceful;
|
m_graceful_pause_mode = graceful;
|
||||||
|
|
||||||
|
// update finished and downloading counters
|
||||||
|
if (was_active_download && !is_active_download()) m_ses.dec_active_downloading();
|
||||||
|
else if (!was_active_download && is_active_download()) m_ses.inc_active_downloading();
|
||||||
|
if (was_active_finished && !is_active_finished()) m_ses.dec_active_finished();
|
||||||
|
else if (!was_active_finished && is_active_finished()) m_ses.inc_active_finished();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
{
|
{
|
||||||
m_announce_to_dht = false;
|
m_announce_to_dht = false;
|
||||||
@@ -7160,7 +7173,7 @@ namespace libtorrent
|
|||||||
&& m_announce_to_dht
|
&& m_announce_to_dht
|
||||||
&& m_announce_to_trackers
|
&& m_announce_to_trackers
|
||||||
&& m_announce_to_lsd) return;
|
&& m_announce_to_lsd) return;
|
||||||
m_allow_peers = true;
|
set_allow_peers(true);
|
||||||
m_announce_to_dht = true;
|
m_announce_to_dht = true;
|
||||||
m_announce_to_trackers = true;
|
m_announce_to_trackers = true;
|
||||||
m_announce_to_lsd = true;
|
m_announce_to_lsd = true;
|
||||||
@@ -8244,8 +8257,18 @@ namespace libtorrent
|
|||||||
if (int(m_state) == s) return;
|
if (int(m_state) == s) return;
|
||||||
if (m_ses.m_alerts.should_post<state_changed_alert>())
|
if (m_ses.m_alerts.should_post<state_changed_alert>())
|
||||||
m_ses.m_alerts.post_alert(state_changed_alert(get_handle(), s, (torrent_status::state_t)m_state));
|
m_ses.m_alerts.post_alert(state_changed_alert(get_handle(), s, (torrent_status::state_t)m_state));
|
||||||
|
|
||||||
|
bool was_active_download = is_active_download();
|
||||||
|
bool was_active_finished = is_active_finished();
|
||||||
|
|
||||||
m_state = s;
|
m_state = s;
|
||||||
|
|
||||||
|
// update finished and downloading counters
|
||||||
|
if (was_active_download && !is_active_download()) m_ses.dec_active_downloading();
|
||||||
|
else if (!was_active_download && is_active_download()) m_ses.inc_active_downloading();
|
||||||
|
if (was_active_finished && !is_active_finished()) m_ses.dec_active_finished();
|
||||||
|
else if (!was_active_finished && is_active_finished()) m_ses.inc_active_finished();
|
||||||
|
|
||||||
state_updated();
|
state_updated();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
|
Reference in New Issue
Block a user