diff --git a/docs/manual.rst b/docs/manual.rst index faa590c09..25fb6f541 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -3707,6 +3707,11 @@ this limit, and once the size hits the limit, peers are no longer added to the list. If this limit is set to 0, there is no limit on how many peers we'll keep in the peer list. +``max_paused_peerlist_size`` is the max peer list size used for torrents +that are paused. This default to the same as ``max_peerlist_size``, but +can be used to save memory for paused torrents, since it's not as +important for them to keep a large peer list. + ``min_announce_interval`` is the minimum allowed announce interval for a tracker. This is specified in seconds, defaults to 5 minutes and is used as a sanity check on what is returned from a tracker. It diff --git a/examples/client_test.cpp b/examples/client_test.cpp index e1694ec42..9cb7a2ccc 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -754,7 +754,7 @@ int main(int argc, char* argv[]) } using namespace libtorrent; - session_settings settings; + session_settings settings = min_memory_usage(); proxy_settings ps; settings.user_agent = "client_test/" LIBTORRENT_VERSION; diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 97a037887..2bdc6857a 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -145,6 +145,7 @@ namespace libtorrent , auto_scrape_interval(1800) , auto_scrape_min_interval(300) , max_peerlist_size(8000) + , max_paused_peerlist_size(8000) , min_announce_interval(5 * 60) , prioritize_partial_pieces(false) , auto_manage_startup(120) @@ -483,6 +484,10 @@ namespace libtorrent // about, not necessarily connected to. int max_peerlist_size; + // when a torrent is paused, this is the max peer + // list size that's used + int max_paused_peerlist_size; + // any announce intervals reported from a tracker // that is lower than this, will be clamped to this // value. It's specified in seconds diff --git a/src/policy.cpp b/src/policy.cpp index a5a4551c2..ff4190899 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -429,17 +429,18 @@ namespace libtorrent return pe.connection == 0 && pe.last_connected != 0 && !pe.banned - && !is_connect_candidate(pe, m_finished) - && m_peers.size() >= m_torrent->settings().max_peerlist_size * 0.95 - && m_torrent->settings().max_peerlist_size > 0; + && !is_connect_candidate(pe, m_finished); } void policy::erase_peers() { INVARIANT_CHECK; - if (m_torrent->settings().max_peerlist_size == 0 - || m_peers.empty()) return; + int max_peerlist_size = m_torrent->is_paused() + ?m_torrent->settings().max_paused_peerlist_size + :m_torrent->settings().max_peerlist_size; + + if (max_peerlist_size == 0 || m_peers.empty()) return; int erase_candidate = -1; @@ -450,7 +451,7 @@ namespace libtorrent for (int iterations = (std::min)(int(m_peers.size()), 300); iterations > 0; --iterations) { - if (m_peers.size() < m_torrent->settings().max_peerlist_size * 0.95) + if (m_peers.size() < max_peerlist_size * 0.95) break; if (round_robin == m_peers.size()) round_robin = 0; @@ -525,6 +526,10 @@ namespace libtorrent bool pinged = false; #endif + int max_peerlist_size = m_torrent->is_paused() + ?m_torrent->settings().max_paused_peerlist_size + :m_torrent->settings().max_peerlist_size; + for (int iterations = (std::min)(int(m_peers.size()), 300); iterations > 0; --iterations) { @@ -549,8 +554,8 @@ namespace libtorrent // if the number of peers is growing large // we need to start weeding. - if (m_peers.size() >= m_torrent->settings().max_peerlist_size * 0.95 - && m_torrent->settings().max_peerlist_size > 0) + if (m_peers.size() >= max_peerlist_size * 0.95 + && max_peerlist_size > 0) { if (is_erase_candidate(pe, m_finished) && (erase_candidate == -1 @@ -663,6 +668,7 @@ namespace libtorrent // override at a time error_code ec; TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec); + TORRENT_ASSERT(!m_torrent->is_paused()); aux::session_impl& ses = m_torrent->session(); @@ -895,6 +901,10 @@ namespace libtorrent iterator iter; peer* i = 0; + int max_peerlist_size = m_torrent->is_paused() + ?m_torrent->settings().max_paused_peerlist_size + :m_torrent->settings().max_peerlist_size; + bool found = false; if (m_torrent->settings().allow_multiple_connections_per_ip) { @@ -913,13 +923,13 @@ namespace libtorrent if (!found) { - if (m_torrent->settings().max_peerlist_size - && int(m_peers.size()) >= m_torrent->settings().max_peerlist_size) + if (max_peerlist_size + && int(m_peers.size()) >= max_peerlist_size) { if (src == peer_info::resume_data) return 0; erase_peers(); - if (int(m_peers.size()) >= m_torrent->settings().max_peerlist_size) + if (int(m_peers.size()) >= max_peerlist_size) return 0; // since some peers were removed, we need to diff --git a/src/session.cpp b/src/session.cpp index 3a867fdfd..9f44a41e9 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -154,6 +154,7 @@ namespace libtorrent set.close_redundant_connections = true; set.max_peerlist_size = 500; + set.max_paused_peerlist_size = 50; // udp trackers are cheaper to talk to set.prefer_udp_trackers = true; diff --git a/src/torrent.cpp b/src/torrent.cpp index f7ec87e23..a5478a24c 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -4826,6 +4826,27 @@ namespace libtorrent } #endif + m_time_scaler--; + if (m_time_scaler <= 0) + { + m_time_scaler = 10; + + if (settings().max_sparse_regions > 0 + && m_picker + && m_picker->sparse_regions() > settings().max_sparse_regions) + { + // we have too many sparse regions. Prioritize pieces + // that won't introduce new sparse regions + // prioritize pieces that will reduce the number of sparse + // regions even higher + int start = m_picker->cursor(); + int end = m_picker->reverse_cursor(); + for (int i = start; i < end; ++i) + update_sparse_piece_prio(i, start, end); + } + m_policy.pulse(); + } + if (is_paused()) { // let the stats fade out to 0 @@ -4940,27 +4961,6 @@ namespace libtorrent m_total_uploaded += m_stat.last_payload_uploaded(); m_total_downloaded += m_stat.last_payload_downloaded(); m_stat.second_tick(tick_interval); - - m_time_scaler--; - if (m_time_scaler <= 0) - { - m_time_scaler = 10; - - if (settings().max_sparse_regions > 0 - && m_picker - && m_picker->sparse_regions() > settings().max_sparse_regions) - { - // we have too many sparse regions. Prioritize pieces - // that won't introduce new sparse regions - // prioritize pieces that will reduce the number of sparse - // regions even higher - int start = m_picker->cursor(); - int end = m_picker->reverse_cursor(); - for (int i = start; i < end; ++i) - update_sparse_piece_prio(i, start, end); - } - m_policy.pulse(); - } } void torrent::request_time_critical_pieces()