deprecate old state saving functions, merge dht state with session state

This commit is contained in:
Arvid Norberg 2010-03-04 16:42:39 +00:00
parent 9edb348093
commit 281b6368f7
9 changed files with 149 additions and 84 deletions

View File

@ -20,6 +20,9 @@
0.15 release 0.15 release
* introduced a session state save mechanism. load_state() and save_state().
this saves all session settings and state (except torrents)
* deprecated dht_state functions and merged it with the session state
* added support for multiple trackers in magnet links * added support for multiple trackers in magnet links
* added support for explicitly flushing the disk cache * added support for explicitly flushing the disk cache
* added torrent priority to affect bandwidth allocation for its peers * added torrent priority to affect bandwidth allocation for its peers

View File

@ -185,9 +185,6 @@ The ``session`` class has the following synopsis::
bool load_country_db(wchar_t const* file); bool load_country_db(wchar_t const* file);
int as_for_ip(address const& adr); int as_for_ip(address const& adr);
void load_state(entry const& ses_state);
entry state() const;
void set_ip_filter(ip_filter const& f); void set_ip_filter(ip_filter const& f);
ip_filter const& get_ip_filter() const; ip_filter const& get_ip_filter() const;
@ -636,18 +633,6 @@ The ``wchar_t`` overloads are for wide character paths.
.. _`MaxMind ASN database`: http://www.maxmind.com/app/asnum .. _`MaxMind ASN database`: http://www.maxmind.com/app/asnum
.. _`MaxMind GeoIP database`: http://www.maxmind.com/app/geolitecountry .. _`MaxMind GeoIP database`: http://www.maxmind.com/app/geolitecountry
load_state() state()
--------------------
::
void load_state(entry const& ses_state);
entry state() const;
These functions loads and save session state. Currently, the only state
that's stored is peak download rates for ASes. This map is used to
determine which order to connect to peers.
set_ip_filter() set_ip_filter()
--------------- ---------------

View File

@ -803,7 +803,9 @@ int main(int argc, char* argv[])
std::vector<char> in; std::vector<char> in;
if (load_file(".ses_state", in) == 0) if (load_file(".ses_state", in) == 0)
{ {
ses.load_state(bdecode(in.begin(), in.end())); lazy_entry e;
if (lazy_bdecode(&in[0], &in[0] + in.size(), e) == 0)
ses.load_state(e);
} }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
@ -816,14 +818,7 @@ int main(int argc, char* argv[])
ses.add_dht_router(std::make_pair( ses.add_dht_router(std::make_pair(
std::string("router.bitcomet.com"), 6881)); std::string("router.bitcomet.com"), 6881));
if (load_file(".dht_state", in) == 0)
{
ses.start_dht(bdecode(in.begin(), in.end()));
}
else
{
ses.start_dht(); ses.start_dht();
}
#endif #endif
ses.start_lsd(); ses.start_lsd();
@ -1604,7 +1599,7 @@ int main(int argc, char* argv[])
if (a == 0) if (a == 0)
{ {
printf(" aborting with %d outstanding " printf(" aborting with %d outstanding "
"torrents to save resume data for", num_resume_data); "torrents to save resume data for\n", num_resume_data);
break; break;
} }
@ -1633,21 +1628,14 @@ int main(int argc, char* argv[])
} }
printf("saving session state\n"); printf("saving session state\n");
{ {
entry session_state = ses.state(); entry session_state;
ses.save_state(session_state);
std::vector<char> out; std::vector<char> out;
bencode(std::back_inserter(out), session_state); bencode(std::back_inserter(out), session_state);
save_file(".ses_state", out); save_file(".ses_state", out);
} }
#ifndef TORRENT_DISABLE_DHT
printf("saving DHT state\n");
entry dht_state = ses.dht_state();
std::vector<char> out;
bencode(std::back_inserter(out), dht_state);
save_file(".dht_state", out);
#endif
printf("closing session"); printf("closing session");
return 0; return 0;

View File

@ -195,10 +195,13 @@ namespace libtorrent
void add_dht_router(std::pair<std::string, int> const& node); void add_dht_router(std::pair<std::string, int> const& node);
void set_dht_settings(dht_settings const& s); void set_dht_settings(dht_settings const& s);
dht_settings const& get_dht_settings() const { return m_dht_settings; } dht_settings const& get_dht_settings() const { return m_dht_settings; }
void start_dht(entry const& startup_state); void start_dht();
void stop_dht(); void stop_dht();
void start_dht(entry const& startup_state);
#ifndef TORRENT_NO_DEPRECATE
entry dht_state(mutex::scoped_lock& l) const; entry dht_state(mutex::scoped_lock& l) const;
#endif
void maybe_update_udp_mapping(int nat, int local_port, int external_port); void maybe_update_udp_mapping(int nat, int local_port, int external_port);
void on_dht_announce(error_code const& e); void on_dht_announce(error_code const& e);
@ -288,7 +291,7 @@ namespace libtorrent
void announce_lsd(sha1_hash const& ih); void announce_lsd(sha1_hash const& ih);
void save_state(entry& e) const; void save_state(entry& e, mutex::scoped_lock& l) const;
void load_state(lazy_entry const& e); void load_state(lazy_entry const& e);
void set_peer_proxy(proxy_settings const& s) void set_peer_proxy(proxy_settings const& s)
@ -590,6 +593,9 @@ namespace libtorrent
proxy_settings m_dht_proxy; proxy_settings m_dht_proxy;
#endif #endif
#ifndef TORRENT_DISABLE_DHT
entry m_dht_state;
#endif
// set to true when the session object // set to true when the session object
// is being destructed and the thread // is being destructed and the thread
// should exit // should exit

View File

@ -76,6 +76,7 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent namespace libtorrent
{ {
struct lazy_entry;
struct TORRENT_EXPORT type_error: std::runtime_error struct TORRENT_EXPORT type_error: std::runtime_error
{ {
@ -119,6 +120,7 @@ namespace libtorrent
bool operator==(entry const& e) const; bool operator==(entry const& e) const;
void operator=(lazy_entry const&);
void operator=(entry const&); void operator=(entry const&);
void operator=(dictionary_type const&); void operator=(dictionary_type const&);
void operator=(string_type const&); void operator=(string_type const&);

View File

@ -244,10 +244,17 @@ namespace libtorrent
, std::vector<cached_piece_info>& ret) const; , std::vector<cached_piece_info>& ret) const;
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void start_dht(entry const& startup_state = entry()); void start_dht();
void stop_dht(); void stop_dht();
void set_dht_settings(dht_settings const& settings); void set_dht_settings(dht_settings const& settings);
entry dht_state() const; #ifndef TORRENT_NO_DEPRECATE
// deprecated in 0.15
// use save_state and load_state instead
TORRENT_DEPRECATED_PREFIX
entry dht_state() const TORRENT_DEPRECATED;
TORRENT_DEPRECATED_PREFIX
void start_dht(entry const& startup_state) TORRENT_DEPRECATED;
#endif
void add_dht_node(std::pair<std::string, int> const& node); void add_dht_node(std::pair<std::string, int> const& node);
void add_dht_router(std::pair<std::string, int> const& node); void add_dht_router(std::pair<std::string, int> const& node);
bool is_dht_running() const; bool is_dht_running() const;
@ -272,8 +279,14 @@ namespace libtorrent
#endif #endif
#endif #endif
void load_state(entry const& ses_state); #ifndef TORRENT_NO_DEPRECATE
entry state() const; // deprecated in 0.15
// use load_state and save_state instead
TORRENT_DEPRECATED_PREFIX
void load_state(entry const& ses_state) TORRENT_DEPRECATED;
TORRENT_DEPRECATED_PREFIX
entry state() const TORRENT_DEPRECATED;
#endif
void set_ip_filter(ip_filter const& f); void set_ip_filter(ip_filter const& f);
ip_filter const& get_ip_filter() const; ip_filter const& get_ip_filter() const;

View File

@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/entry.hpp" #include "libtorrent/entry.hpp"
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/escape_string.hpp" #include "libtorrent/escape_string.hpp"
#include "libtorrent/lazy_entry.hpp"
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define for if (false) {} else for #define for if (false) {} else for
@ -207,6 +208,40 @@ namespace libtorrent
m_type = int_t; m_type = int_t;
} }
// convert a lazy_entry into an old skool entry
void entry::operator=(lazy_entry const& e)
{
switch (e.type())
{
case lazy_entry::string_t:
this->string() = e.string_value();
break;
case lazy_entry::int_t:
this->integer() = e.int_value();
break;
case lazy_entry::dict_t:
{
dictionary_type& d = this->dict();
for (int i = 0; i < e.dict_size(); ++i)
{
std::pair<std::string, lazy_entry const*> elem = e.dict_at(i);
d[elem.first] = *elem.second;
}
break;
}
case lazy_entry::list_t:
{
list_type& l = this->list();
for (int i = 0; i < e.list_size(); ++i)
{
l.push_back(entry());
l.back() = *e.list_at(i);
}
break;
}
}
}
void entry::operator=(dictionary_type const& v) void entry::operator=(dictionary_type const& v)
{ {
destruct(); destruct();

View File

@ -316,7 +316,7 @@ namespace libtorrent
void session::save_state(entry& e) const void session::save_state(entry& e) const
{ {
mutex::scoped_lock l(m_impl->m_mutex); mutex::scoped_lock l(m_impl->m_mutex);
m_impl->save_state(e); m_impl->save_state(e, l);
} }
void session::load_state(lazy_entry const& e) void session::load_state(lazy_entry const& e)
@ -367,17 +367,25 @@ namespace libtorrent
#endif // TORRENT_USE_WSTRING #endif // TORRENT_USE_WSTRING
#endif // TORRENT_DISABLE_GEO_IP #endif // TORRENT_DISABLE_GEO_IP
#ifndef TORRENT_NO_DEPRECATE
void session::load_state(entry const& ses_state) void session::load_state(entry const& ses_state)
{ {
std::vector<char> buf;
bencode(std::back_inserter(buf), ses_state);
lazy_entry e;
lazy_bdecode(&buf[0], &buf[0] + buf.size(), e);
mutex::scoped_lock l(m_impl->m_mutex); mutex::scoped_lock l(m_impl->m_mutex);
m_impl->load_state(ses_state); m_impl->load_state(e);
} }
entry session::state() const entry session::state() const
{ {
entry ret;
mutex::scoped_lock l(m_impl->m_mutex); mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->state(); m_impl->save_state(ret, l);
return ret;
} }
#endif
void session::set_ip_filter(ip_filter const& f) void session::set_ip_filter(ip_filter const& f)
{ {
@ -582,10 +590,11 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void session::start_dht(entry const& startup_state) void session::start_dht()
{ {
mutex::scoped_lock l(m_impl->m_mutex); mutex::scoped_lock l(m_impl->m_mutex);
m_impl->start_dht(startup_state); // the state is loaded in load_state()
m_impl->start_dht();
} }
void session::stop_dht() void session::stop_dht()
@ -600,11 +609,19 @@ namespace libtorrent
m_impl->set_dht_settings(settings); m_impl->set_dht_settings(settings);
} }
#ifndef TORRENT_NO_DEPRECATE
void session::start_dht(entry const& startup_state)
{
mutex::scoped_lock l(m_impl->m_mutex);
m_impl->start_dht(startup_state);
}
entry session::dht_state() const entry session::dht_state() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->dht_state(l); return m_impl->dht_state(l);
} }
#endif
void session::add_dht_node(std::pair<std::string, int> const& node) void session::add_dht_node(std::pair<std::string, int> const& node)
{ {

View File

@ -647,7 +647,7 @@ namespace aux {
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this))); m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
} }
void session_impl::save_state(entry& e) const void session_impl::save_state(entry& e, mutex::scoped_lock& l) const
{ {
save_struct(e["settings"], &m_settings, session_settings_map save_struct(e["settings"], &m_settings, session_settings_map
, sizeof(session_settings_map)/sizeof(session_settings_map[0])); , sizeof(session_settings_map)/sizeof(session_settings_map[0]));
@ -656,6 +656,17 @@ namespace aux {
, sizeof(dht_settings_map)/sizeof(dht_settings_map[0])); , sizeof(dht_settings_map)/sizeof(dht_settings_map[0]));
save_struct(e["dht proxy"], &m_dht_proxy, proxy_settings_map save_struct(e["dht proxy"], &m_dht_proxy, proxy_settings_map
, sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0])); , sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0]));
if (m_dht)
{
condition cond;
entry& state = e["dht state"];
bool done = false;
m_io_service.post(boost::bind(&session_impl::on_dht_state_callback
, this, boost::ref(cond), boost::ref(state), boost::ref(done)));
while (!done) cond.wait(l);
}
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
save_struct(e["i2p"], &i2p_proxy(), proxy_settings_map save_struct(e["i2p"], &i2p_proxy(), proxy_settings_map
@ -672,12 +683,27 @@ namespace aux {
, sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0])); , sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0]));
save_struct(e["tracker proxy"], &m_tracker_proxy, proxy_settings_map save_struct(e["tracker proxy"], &m_tracker_proxy, proxy_settings_map
, sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0])); , sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0]));
#ifndef TORRENT_DISABLE_GEO_IP
entry::dictionary_type& as_map = e["AS map"].dict();
char buf[10];
for (std::map<int, int>::const_iterator i = m_as_peak.begin()
, end(m_as_peak.end()); i != end; ++i)
{
if (i->second == 0) continue;
sprintf(buf, "%05d", i->first);
as_map[buf] = i->second;
}
#endif
} }
void session_impl::load_state(lazy_entry const& e) void session_impl::load_state(lazy_entry const& e)
{ {
lazy_entry const* settings; lazy_entry const* settings;
if (e.type() != lazy_entry::dict_t) return;
settings = e.dict_find_dict("settings"); settings = e.dict_find_dict("settings");
if (settings) if (settings)
{ {
@ -705,6 +731,13 @@ namespace aux {
, sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0])); , sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0]));
set_dht_proxy(s); set_dht_proxy(s);
} }
settings = e.dict_find_dict("dht state");
if (settings)
{
m_dht_state = *settings;
}
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
@ -755,6 +788,21 @@ namespace aux {
, sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0])); , sizeof(proxy_settings_map)/sizeof(proxy_settings_map[0]));
set_tracker_proxy(s); set_tracker_proxy(s);
} }
#ifndef TORRENT_DISABLE_GEO_IP
settings = e.dict_find_dict("AS map");
if (settings)
{
for (int i = 0; i < settings->dict_size(); ++i)
{
std::pair<std::string, lazy_entry const*> item = settings->dict_at(i);
int as_num = atoi(item.firstc_str());
if (item.second.type() != lazy_entry::int_t || item.second.int_value() == 0) continue;
int& peak = m_as_peak[as_num];
if (peak < item.second.integer()) peak = item.second.integer();
}
}
#endif
} }
#ifndef TORRENT_DISABLE_GEO_IP #ifndef TORRENT_DISABLE_GEO_IP
@ -843,43 +891,6 @@ namespace aux {
#endif // TORRENT_DISABLE_GEO_IP #endif // TORRENT_DISABLE_GEO_IP
void session_impl::load_state(entry const& ses_state)
{
if (ses_state.type() != entry::dictionary_t) return;
#ifndef TORRENT_DISABLE_GEO_IP
entry const* as_map = ses_state.find_key("AS map");
if (as_map && as_map->type() == entry::dictionary_t)
{
entry::dictionary_type const& as_peak = as_map->dict();
for (entry::dictionary_type::const_iterator i = as_peak.begin()
, end(as_peak.end()); i != end; ++i)
{
int as_num = atoi(i->first.c_str());
if (i->second.type() != entry::int_t || i->second.integer() == 0) continue;
int& peak = m_as_peak[as_num];
if (peak < i->second.integer()) peak = i->second.integer();
}
}
#endif
}
entry session_impl::state() const
{
entry ret;
#ifndef TORRENT_DISABLE_GEO_IP
entry::dictionary_type& as_map = ret["AS map"].dict();
char buf[10];
for (std::map<int, int>::const_iterator i = m_as_peak.begin()
, end(m_as_peak.end()); i != end; ++i)
{
if (i->second == 0) continue;
sprintf(buf, "%05d", i->first);
as_map[buf] = i->second;
}
#endif
return ret;
}
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
void session_impl::add_extension( void session_impl::add_extension(
boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext) boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext)
@ -3241,6 +3252,9 @@ namespace aux {
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void session_impl::start_dht()
{ start_dht(m_dht_state); }
void session_impl::start_dht(entry const& startup_state) void session_impl::start_dht(entry const& startup_state)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3365,6 +3379,7 @@ namespace aux {
c.signal(l); c.signal(l);
} }
#ifndef TORRENT_NO_DEPRECATE
entry session_impl::dht_state(mutex::scoped_lock& l) const entry session_impl::dht_state(mutex::scoped_lock& l) const
{ {
condition cond; condition cond;
@ -3376,6 +3391,7 @@ namespace aux {
while (!done) cond.wait(l); while (!done) cond.wait(l);
return e; return e;
} }
#endif
void session_impl::add_dht_node(std::pair<std::string, int> const& node) void session_impl::add_dht_node(std::pair<std::string, int> const& node)
{ {