added auto-sequential feature

This commit is contained in:
Arvid Norberg 2014-09-24 00:02:00 +00:00
parent 8cbef3876a
commit 60119bf0ca
8 changed files with 72 additions and 4 deletions

View File

@ -1,3 +1,4 @@
* added auto-sequential feature. download well-seeded torrents in-order
* removed built-in GeoIP support (this functionality is orthogonal to libtorrent)
* deprecate proxy settings in favor of regular settings
* deprecate separate settings for peer protocol encryption

View File

@ -672,6 +672,7 @@ namespace libtorrent
void update_outgoing_interfaces();
void update_listen_interfaces();
void update_privileged_ports();
void update_auto_sequential();
void update_upnp();
void update_natpmp();

View File

@ -619,6 +619,12 @@ namespace libtorrent
// configured proxy, if any.
proxy_peer_connections,
// if this setting is true, torrents with a very high availability
// of pieces (and seeds) are downloaded sequentially. This is more
// efficient for the disk I/O. With many seeds, the download order
// is unlikely to matter anyway
auto_sequential,
max_bool_setting_internal,
num_bool_settings = max_bool_setting_internal - bool_type_base
};

View File

@ -375,7 +375,8 @@ namespace libtorrent
void new_external_ip();
torrent_status::state_t state() const { return (torrent_status::state_t)m_state; }
torrent_status::state_t state() const
{ return (torrent_status::state_t)m_state; }
void set_state(torrent_status::state_t s);
aux::session_settings const& settings() const;
@ -383,7 +384,7 @@ namespace libtorrent
void set_sequential_download(bool sd);
bool is_sequential_download() const
{ return m_sequential_download; }
{ return m_sequential_download || m_auto_sequential; }
void queue_up();
void queue_down();
@ -625,6 +626,7 @@ namespace libtorrent
// the number of peers that belong to this torrent
int num_peers() const { return (int)m_connections.size(); }
int num_seeds() const;
int num_downloaders() const;
typedef std::vector<peer_connection*>::iterator peer_iterator;
typedef std::vector<peer_connection*>::const_iterator const_peer_iterator;
@ -643,6 +645,7 @@ namespace libtorrent
void add_suggest_piece(int piece);
void update_suggest_piece(int index, int change);
void update_auto_sequential();
void refresh_suggest_pieces();
void do_refresh_suggest_pieces();
void on_cache_info(disk_io_job const* j);
@ -1611,7 +1614,11 @@ namespace libtorrent
// at high enough rates, it's inactive.
bool m_inactive:1;
// TODO: there's space for 1 bits here
// this is set if the auto_sequential setting is true and this swarm
// satisfies the criteria to be considered high-availability. i.e. if
// there's mostly seeds in the swarm, download the files sequentially
// for improved disk I/O performance.
bool m_auto_sequential:1;
// ----

View File

@ -6945,7 +6945,8 @@ namespace libtorrent
// if m_num_pieces == 0, we probably don't have the
// metadata yet.
boost::shared_ptr<torrent> t = m_torrent.lock();
return m_num_pieces == (int)m_have_piece.size() && m_num_pieces > 0 && t && t->valid_metadata();
return m_num_pieces == (int)m_have_piece.size()
&& m_num_pieces > 0 && t && t->valid_metadata();
}
void peer_connection::set_share_mode(bool u)

View File

@ -6188,6 +6188,13 @@ retry:
}
}
void session_impl::update_auto_sequential()
{
for (torrent_map::iterator i = m_torrents.begin()
, end(m_torrents.end()); i != end; ++i)
i->second->update_auto_sequential();
}
void session_impl::update_proxy()
{
// in case we just set a socks proxy, we might have to

View File

@ -200,6 +200,7 @@ namespace libtorrent
SET_NOPREV(prefer_rc4, false, 0),
SET_NOPREV(proxy_hostnames, true, 0),
SET_NOPREV(proxy_peer_connections, true, 0),
SET_NOPREV(auto_sequential, true, &session_impl::update_auto_sequential),
};
int_setting_entry_t int_settings[settings_pack::num_int_settings] =

View File

@ -3110,6 +3110,8 @@ namespace libtorrent
m_incomplete = incomplete;
m_downloaded = downloaded;
update_auto_sequential();
// these numbers are cached in the resume data
m_need_save_resume_data = true;
}
@ -3306,6 +3308,31 @@ namespace libtorrent
state_updated();
}
void torrent::update_auto_sequential()
{
if (!m_ses.settings().get_bool(settings_pack::auto_sequential))
{
m_auto_sequential = false;
return;
}
if (int(m_connections.size()) - m_num_connecting < 10)
{
// there are too few peers. Be conservative and don't assume it's
// well seeded until we can connect to more peers
m_auto_sequential = false;
return;
}
// if there are at least 10 seeds, and there are 10 times more
// seeds than downloaders, enter sequential download mode
// (for performance)
int downloaders = num_downloaders();
int seeds = num_seeds();
m_auto_sequential = downloaders * 10 <= seeds
&& seeds > 9;
}
void torrent::do_connect_boost()
{
if (!m_need_connect_boost) return;
@ -10657,6 +10684,7 @@ namespace libtorrent
{
need_policy();
m_policy->set_seed(p, s);
update_auto_sequential();
}
void torrent::clear_failcount(torrent_peer* p)
@ -11322,6 +11350,8 @@ namespace libtorrent
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
{
TORRENT_ASSERT(is_single_thread());
@ -11334,6 +11364,20 @@ namespace libtorrent
return ret;
}
// TODO: 3 make this a gauge that's kept up to date rather than counting
// every time
int torrent::num_downloaders() const
{
TORRENT_ASSERT(is_single_thread());
INVARIANT_CHECK;
int ret = 0;
for (const_peer_iterator i = m_connections.begin()
, 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
, int response_code, error_code const& ec, const std::string& msg
, int retry_interval)