optimize num_seeds() and num_downloaders() to not count the peers every time

This commit is contained in:
Arvid Norberg 2014-09-24 09:03:57 +00:00
parent 60119bf0ca
commit 9a985d197f
4 changed files with 78 additions and 31 deletions

View File

@ -1577,7 +1577,13 @@ namespace libtorrent
// specified in session_time // specified in session_time
boost::uint16_t m_last_download; boost::uint16_t m_last_download;
// TODO: There are 8 bits free here // the number of peer connections to seeds. This should be the same as
// counting the peer connections that say true for is_seed()
boost::uint16_t m_num_seeds;
// the timestamp of the last byte uploaded from this torrent
// specified in session_time
boost::uint16_t m_last_upload;
// this is a second count-down to when we should tick the // this is a second count-down to when we should tick the
// storage for this torrent. Ticking the storage is used // storage for this torrent. Ticking the storage is used
@ -1589,12 +1595,6 @@ namespace libtorrent
// ---- // ----
// the timestamp of the last byte uploaded from this torrent
// specified in session_time
boost::uint16_t m_last_upload;
// TODO: There are 8 bits here
// if this is true, libtorrent may pause and resume // if this is true, libtorrent may pause and resume
// this torrent depending on queuing rules. Torrents // this torrent depending on queuing rules. Torrents
// started with auto_managed flag set may be added in // started with auto_managed flag set may be added in

View File

@ -2184,7 +2184,6 @@ namespace libtorrent
peer_log("*** THIS IS A SEED [ p: %p ]", m_peer_info); peer_log("*** THIS IS A SEED [ p: %p ]", m_peer_info);
#endif #endif
// if this is a web seed. we don't have a peer_info struct
t->set_seed(m_peer_info, true); t->set_seed(m_peer_info, true);
m_upload_only = true; m_upload_only = true;

View File

@ -270,7 +270,11 @@ namespace libtorrent
TORRENT_ASSERT(m_locked_peer != *i); TORRENT_ASSERT(m_locked_peer != *i);
state->erased.push_back(*i); state->erased.push_back(*i);
if ((*i)->seed) --m_num_seeds; if ((*i)->seed)
{
TORRENT_ASSERT(m_num_seeds > 0);
--m_num_seeds;
}
if (is_connect_candidate(**i)) if (is_connect_candidate(**i))
update_connect_candidates(-1); update_connect_candidates(-1);
TORRENT_ASSERT(m_num_connect_candidates < int(m_peers.size())); TORRENT_ASSERT(m_num_connect_candidates < int(m_peers.size()));
@ -861,10 +865,16 @@ namespace libtorrent
update_connect_candidates(-1); update_connect_candidates(-1);
if (p->web_seed) return; if (p->web_seed) return;
if (s) ++m_num_seeds; if (s)
else --m_num_seeds; {
TORRENT_ASSERT(m_num_seeds >= 0); TORRENT_ASSERT(m_num_seeds < int(m_peers.size()));
TORRENT_ASSERT(m_num_seeds <= int(m_peers.size())); ++m_num_seeds;
}
else
{
TORRENT_ASSERT(m_num_seeds > 0);
--m_num_seeds;
}
} }
// this is an internal function // this is an internal function
@ -911,6 +921,7 @@ namespace libtorrent
if (flags & flag_seed) if (flags & flag_seed)
{ {
p->seed = true; p->seed = true;
TORRENT_ASSERT(m_num_seeds < int(m_peers.size()));
++m_num_seeds; ++m_num_seeds;
} }
if (flags & flag_utp) if (flags & flag_utp)
@ -948,7 +959,11 @@ namespace libtorrent
// so we don't have to trust this source // so we don't have to trust this source
if ((flags & flag_seed) && !p->connection) if ((flags & flag_seed) && !p->connection)
{ {
if (!p->seed) ++m_num_seeds; if (!p->seed)
{
TORRENT_ASSERT(m_num_seeds < int(m_peers.size()));
++m_num_seeds;
}
p->seed = true; p->seed = true;
} }
if (flags & flag_utp) if (flags & flag_utp)

View File

@ -224,8 +224,9 @@ namespace libtorrent
, m_pinned(p.flags & add_torrent_params::flag_pinned) , m_pinned(p.flags & add_torrent_params::flag_pinned)
, m_should_be_loaded(true) , m_should_be_loaded(true)
, m_last_download(0) , m_last_download(0)
, m_storage_tick(0) , m_num_seeds(0)
, m_last_upload(0) , m_last_upload(0)
, m_storage_tick(0)
, m_auto_managed(p.flags & add_torrent_params::flag_auto_managed) , m_auto_managed(p.flags & add_torrent_params::flag_auto_managed)
, m_current_gauge_state(no_gauge_state) , m_current_gauge_state(no_gauge_state)
, m_moving_storage(false) , m_moving_storage(false)
@ -5764,8 +5765,6 @@ namespace libtorrent
void torrent::remove_peer(peer_connection* p) void torrent::remove_peer(peer_connection* p)
{ {
INVARIANT_CHECK;
TORRENT_ASSERT(p != 0); TORRENT_ASSERT(p != 0);
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
@ -5820,6 +5819,12 @@ namespace libtorrent
TORRENT_ASSERT(pp->prev_amount_download == 0); TORRENT_ASSERT(pp->prev_amount_download == 0);
pp->prev_amount_download += p->statistics().total_payload_download() >> 10; pp->prev_amount_download += p->statistics().total_payload_download() >> 10;
pp->prev_amount_upload += p->statistics().total_payload_upload() >> 10; pp->prev_amount_upload += p->statistics().total_payload_upload() >> 10;
if (pp->seed)
{
TORRENT_ASSERT(m_num_seeds > 0);
--m_num_seeds;
}
} }
torrent_state st = get_policy_state(); torrent_state st = get_policy_state();
@ -6140,6 +6145,8 @@ namespace libtorrent
void torrent::connect_web_seed(std::list<web_seed_entry>::iterator web, tcp::endpoint a) void torrent::connect_web_seed(std::list<web_seed_entry>::iterator web, tcp::endpoint a)
{ {
INVARIANT_CHECK;
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
if (m_abort) return; if (m_abort) return;
@ -6275,6 +6282,12 @@ namespace libtorrent
update_want_tick(); update_want_tick();
m_ses.insert_peer(c); m_ses.insert_peer(c);
if (web->peer_info.seed)
{
TORRENT_ASSERT(m_num_seeds < 0xffff);
++m_num_seeds;
}
TORRENT_ASSERT(!web->peer_info.connection); TORRENT_ASSERT(!web->peer_info.connection);
web->peer_info.connection = c.get(); web->peer_info.connection = c.get();
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS
@ -7287,6 +7300,11 @@ namespace libtorrent
m_ses.insert_peer(c); m_ses.insert_peer(c);
need_policy(); need_policy();
m_policy->set_connection(peerinfo, c.get()); m_policy->set_connection(peerinfo, c.get());
if (peerinfo->seed)
{
TORRENT_ASSERT(m_num_seeds < 0xffff);
++m_num_seeds;
}
update_want_peers(); update_want_peers();
update_want_tick(); update_want_tick();
c->start(); c->start();
@ -7617,6 +7635,12 @@ namespace libtorrent
update_want_peers(); update_want_peers();
update_want_tick(); update_want_tick();
if (p->peer_info_struct() && p->peer_info_struct()->seed)
{
TORRENT_ASSERT(m_num_seeds < 0xffff);
++m_num_seeds;
}
#if defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING #if defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
debug_log("incoming peer (%d)", int(m_connections.size())); debug_log("incoming peer (%d)", int(m_connections.size()));
#endif #endif
@ -8326,6 +8350,7 @@ namespace libtorrent
TORRENT_ASSERT(!m_resume_data || m_resume_data->entry.type() == lazy_entry::dict_t TORRENT_ASSERT(!m_resume_data || m_resume_data->entry.type() == lazy_entry::dict_t
|| m_resume_data->entry.type() == lazy_entry::none_t); || m_resume_data->entry.type() == lazy_entry::none_t);
int seeds = 0;
int num_uploads = 0; int num_uploads = 0;
std::map<piece_block, int> num_requests; std::map<piece_block, int> num_requests;
for (const_peer_iterator i = this->begin(); i != this->end(); ++i) for (const_peer_iterator i = this->begin(); i != this->end(); ++i)
@ -8335,6 +8360,10 @@ namespace libtorrent
TORRENT_ASSERT(m_ses.has_peer(*i)); TORRENT_ASSERT(m_ses.has_peer(*i));
#endif #endif
peer_connection const& p = *(*i); peer_connection const& p = *(*i);
if (p.peer_info_struct() && p.peer_info_struct()->seed)
++seeds;
for (std::vector<pending_block>::const_iterator i = p.request_queue().begin() for (std::vector<pending_block>::const_iterator i = p.request_queue().begin()
, end(p.request_queue().end()); i != end; ++i) , end(p.request_queue().end()); i != end; ++i)
if (!i->not_wanted && !i->timed_out) ++num_requests[i->block]; if (!i->not_wanted && !i->timed_out) ++num_requests[i->block];
@ -8347,6 +8376,7 @@ namespace libtorrent
TORRENT_ASSERT(false); TORRENT_ASSERT(false);
} }
TORRENT_ASSERT(num_uploads == int(m_num_uploads)); TORRENT_ASSERT(num_uploads == int(m_num_uploads));
TORRENT_ASSERT(seeds == int(m_num_seeds));
if (has_picker()) if (has_picker())
{ {
@ -10682,6 +10712,20 @@ namespace libtorrent
void torrent::set_seed(torrent_peer* p, bool s) void torrent::set_seed(torrent_peer* p, bool s)
{ {
if (p->seed != s)
{
if (s)
{
TORRENT_ASSERT(m_num_seeds < 0xffff);
++m_num_seeds;
}
else
{
TORRENT_ASSERT(m_num_seeds > 0);
--m_num_seeds;
}
}
need_policy(); need_policy();
m_policy->set_seed(p, s); m_policy->set_seed(p, s);
update_auto_sequential(); update_auto_sequential();
@ -11350,32 +11394,21 @@ namespace libtorrent
m_stats_counters.inc_stats_counter(counters::recv_failed_bytes, b); m_stats_counters.inc_stats_counter(counters::recv_failed_bytes, b);
} }
// TODO: 3 make this a gauge that's kept up to date rather than counting
// every time
int torrent::num_seeds() const int torrent::num_seeds() const
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
int ret = 0; return m_num_seeds;
for (const_peer_iterator i = m_connections.begin()
, end(m_connections.end()); i != end; ++i)
if ((*i)->is_seed()) ++ret;
return ret;
} }
// TODO: 3 make this a gauge that's kept up to date rather than counting
// every time
int torrent::num_downloaders() const int torrent::num_downloaders() const
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
int ret = 0; TORRENT_ASSERT(m_connections.size() >= m_num_seeds);
for (const_peer_iterator i = m_connections.begin() return m_connections.size() - m_num_seeds;
, end(m_connections.end()); i != end; ++i)
if ((*i)->is_connected() && !(*i)->is_seed()) ++ret;
return ret;
} }
void torrent::tracker_request_error(tracker_request const& r void torrent::tracker_request_error(tracker_request const& r