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:
parent
342a0b9306
commit
3c0e7e0a4a
|
@ -515,6 +515,19 @@ namespace libtorrent
|
|||
--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
|
||||
bool in_state_updates(boost::shared_ptr<torrent> t)
|
||||
{
|
||||
|
@ -681,6 +694,13 @@ namespace libtorrent
|
|||
torrent_map m_torrents;
|
||||
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;
|
||||
|
||||
// this has all torrents that wants to be checked in it
|
||||
|
|
|
@ -260,6 +260,20 @@ namespace libtorrent
|
|||
void force_recheck();
|
||||
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
|
||||
{
|
||||
// save resume data every 15 minutes regardless, just to
|
||||
|
|
|
@ -610,6 +610,8 @@ namespace aux {
|
|||
, m_upload_rate(peer_connection::upload_channel)
|
||||
#endif
|
||||
, 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)
|
||||
#if TORRENT_USE_I2P
|
||||
, m_i2p_conn(m_io_service)
|
||||
|
@ -3430,16 +3432,17 @@ namespace aux {
|
|||
torrent& t = *m_next_connect_torrent->second;
|
||||
if (t.want_more_peers())
|
||||
{
|
||||
TORRENT_ASSERT(t.allows_peers());
|
||||
// have a bias to give more connection attempts
|
||||
// to downloading torrents than seed, and even
|
||||
// more to downloading torrents with less than
|
||||
// average number of connections
|
||||
int num_attempts = 1;
|
||||
if (!t.is_seed())
|
||||
if (!t.is_finished())
|
||||
{
|
||||
++num_attempts;
|
||||
if (t.num_peers() < average_peers)
|
||||
++num_attempts;
|
||||
// TODO: make this bias configurable
|
||||
TORRENT_ASSERT(m_num_active_downloading > 0);
|
||||
num_attempts += m_num_active_finished / m_num_active_downloading;
|
||||
}
|
||||
for (int i = 0; i < num_attempts; ++i)
|
||||
{
|
||||
|
@ -4209,6 +4212,8 @@ namespace aux {
|
|||
|
||||
void session_impl::recalculate_auto_managed_torrents()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
// these vectors are filled with auto managed torrents
|
||||
std::vector<torrent*> downloaders;
|
||||
downloaders.reserve(m_torrents.size());
|
||||
|
@ -4301,7 +4306,6 @@ namespace aux {
|
|||
auto_manage_torrents(seeds, dht_limit, tracker_limit, lsd_limit
|
||||
, hard_limit, num_seeds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void session_impl::recalculate_optimistic_unchoke_slots()
|
||||
|
@ -4996,6 +5000,8 @@ namespace aux {
|
|||
|
||||
void session_impl::remove_torrent(const torrent_handle& h, int options)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
boost::shared_ptr<torrent> tptr = h.m_torrent.lock();
|
||||
if (!tptr) return;
|
||||
|
||||
|
@ -5037,6 +5043,13 @@ namespace aux {
|
|||
if (options & session::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
|
||||
sha1_hash i_hash = t.torrent_file().info_hash();
|
||||
#endif
|
||||
|
@ -6064,20 +6077,29 @@ namespace aux {
|
|||
// TORRENT_ASSERT(m_queued_for_checking.size() == num_queued_for_checking);
|
||||
|
||||
std::set<int> unique;
|
||||
int num_active_downloading = 0;
|
||||
int num_active_finished = 0;
|
||||
int total_downloaders = 0;
|
||||
for (torrent_map::const_iterator i = m_torrents.begin()
|
||||
, 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)
|
||||
{
|
||||
TORRENT_ASSERT(pos == -1);
|
||||
continue;
|
||||
}
|
||||
++total_downloaders;
|
||||
unique.insert(i->second->queue_position());
|
||||
|
||||
unique.insert(t->queue_position());
|
||||
}
|
||||
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;
|
||||
TORRENT_ASSERT(m_settings.connections_limit > 0);
|
||||
|
|
|
@ -441,6 +441,10 @@ namespace libtorrent
|
|||
|
||||
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())
|
||||
{
|
||||
// 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);
|
||||
if (paused_ != -1)
|
||||
{
|
||||
m_allow_peers = !paused_;
|
||||
set_allow_peers(!paused_);
|
||||
m_announce_to_dht = !paused_;
|
||||
m_announce_to_trackers = !paused_;
|
||||
m_announce_to_lsd = !paused_;
|
||||
|
@ -7002,7 +7006,7 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
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_trackers = false;
|
||||
m_announce_to_lsd = false;
|
||||
|
@ -7134,10 +7138,19 @@ namespace libtorrent
|
|||
if (m_allow_peers == b
|
||||
&& m_graceful_pause_mode == graceful) return;
|
||||
|
||||
bool was_active_download = is_active_download();
|
||||
bool was_active_finished = is_active_finished();
|
||||
|
||||
m_allow_peers = b;
|
||||
if (!m_ses.is_paused())
|
||||
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)
|
||||
{
|
||||
m_announce_to_dht = false;
|
||||
|
@ -7160,7 +7173,7 @@ namespace libtorrent
|
|||
&& m_announce_to_dht
|
||||
&& m_announce_to_trackers
|
||||
&& m_announce_to_lsd) return;
|
||||
m_allow_peers = true;
|
||||
set_allow_peers(true);
|
||||
m_announce_to_dht = true;
|
||||
m_announce_to_trackers = true;
|
||||
m_announce_to_lsd = true;
|
||||
|
@ -8244,8 +8257,18 @@ namespace libtorrent
|
|||
if (int(m_state) == s) return;
|
||||
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));
|
||||
|
||||
bool was_active_download = is_active_download();
|
||||
bool was_active_finished = is_active_finished();
|
||||
|
||||
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();
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
|
|
Loading…
Reference in New Issue