forked from premiere/premiere-libtorrent
updated client_test to use post_torrent_updates()
This commit is contained in:
parent
2877903e75
commit
d7103ab5b0
|
@ -1,6 +1,6 @@
|
|||
* deprecate set_ratio(), and per-peer rate limits
|
||||
* add web seed support for torrents with pad files
|
||||
* introduced a more scalable API for torrent status updates (post_torrent_updates())
|
||||
* introduced a more scalable API for torrent status updates (post_torrent_updates()) and updated client_test to use it
|
||||
* updated the API to add_torrent_params turning all bools into flags of a flags field
|
||||
* added async_add_torrent() function to significantly improve performance when
|
||||
adding many torrents
|
||||
|
|
|
@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
|
@ -277,26 +278,41 @@ bool show_torrent(libtorrent::torrent_status const& st, int torrent_filter, int*
|
|||
bool yes(libtorrent::torrent_status const&)
|
||||
{ return true; }
|
||||
|
||||
bool compare_torrent(torrent_status const& lhs, torrent_status const& rhs)
|
||||
{
|
||||
if (lhs.queue_position != -1 && rhs.queue_position != -1)
|
||||
{
|
||||
// both are downloading, sort by queue pos
|
||||
return lhs.queue_position < rhs.queue_position;
|
||||
}
|
||||
else if (lhs.queue_position == -1 && rhs.queue_position == -1)
|
||||
{
|
||||
// both are seeding, sort by seed-rank
|
||||
return lhs.seed_rank > rhs.seed_rank;
|
||||
}
|
||||
|
||||
return (lhs.queue_position == -1) < (rhs.queue_position == -1);
|
||||
}
|
||||
|
||||
FILE* g_log_file = 0;
|
||||
|
||||
int active_torrent = 0;
|
||||
|
||||
bool compare_torrent(torrent_status const* lhs, torrent_status const* rhs)
|
||||
{
|
||||
if (lhs->queue_position != -1 && rhs->queue_position != -1)
|
||||
{
|
||||
// both are downloading, sort by queue pos
|
||||
return lhs->queue_position < rhs->queue_position;
|
||||
}
|
||||
else if (lhs->queue_position == -1 && rhs->queue_position == -1)
|
||||
{
|
||||
// both are seeding, sort by seed-rank
|
||||
return lhs->seed_rank > rhs->seed_rank;
|
||||
}
|
||||
|
||||
return (lhs->queue_position == -1) < (rhs->queue_position == -1);
|
||||
}
|
||||
|
||||
void update_filtered_torrents(boost::unordered_set<torrent_status>& all_handles
|
||||
, std::vector<torrent_status const*>& filtered_handles, int* counters)
|
||||
{
|
||||
filtered_handles.clear();
|
||||
memset(counters, 0, sizeof(int) * torrents_max);
|
||||
for (boost::unordered_set<torrent_status>::iterator i = all_handles.begin()
|
||||
, end(all_handles.end()); i != end; ++i)
|
||||
{
|
||||
if (!show_torrent(*i, torrent_filter, counters)) continue;
|
||||
filtered_handles.push_back(&*i);
|
||||
}
|
||||
if (active_torrent >= int(filtered_handles.size())) active_torrent = filtered_handles.size() - 1;
|
||||
std::sort(filtered_handles.begin(), filtered_handles.end(), &compare_torrent);
|
||||
}
|
||||
|
||||
char const* esc(char const* code)
|
||||
{
|
||||
#ifdef ANSI_TERMINAL_COLORS
|
||||
|
@ -785,13 +801,11 @@ void scan_dir(std::string const& dir_path
|
|||
}
|
||||
}
|
||||
|
||||
torrent_status const& get_active_torrent(std::vector<torrent_status> const& torrents)
|
||||
torrent_status const& get_active_torrent(std::vector<torrent_status const*> const& filtered_handles)
|
||||
{
|
||||
if (active_torrent >= int(torrents.size())
|
||||
if (active_torrent >= int(filtered_handles.size())
|
||||
|| active_torrent < 0) active_torrent = 0;
|
||||
std::vector<torrent_status>::const_iterator i = torrents.begin();
|
||||
std::advance(i, active_torrent);
|
||||
return *i;
|
||||
return *filtered_handles[active_torrent];
|
||||
}
|
||||
|
||||
void print_alert(libtorrent::alert const* a, std::string& str)
|
||||
|
@ -835,8 +849,13 @@ int save_file(std::string const& filename, std::vector<char>& v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
||||
, handles_t& files, std::set<libtorrent::torrent_handle> const& non_files)
|
||||
// returns true if the alert was handled (and should not be printed to the log)
|
||||
// returns false if the alert was not handled
|
||||
bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
||||
, handles_t& files, std::set<libtorrent::torrent_handle> const& non_files
|
||||
, int* counters, boost::unordered_set<torrent_status>& all_handles
|
||||
, std::vector<torrent_status const*>& filtered_handles
|
||||
, bool& need_resort)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
|
@ -854,7 +873,7 @@ void handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "ERROR. could not load certificate %s: %s\n", cert.c_str(), ec.message().c_str());
|
||||
if (g_log_file) fprintf(g_log_file, "[%s] %s\n", time_now_string(), msg);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
stat_file(priv, &st, ec);
|
||||
if (ec)
|
||||
|
@ -862,7 +881,7 @@ void handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "ERROR. could not load private key %s: %s\n", priv.c_str(), ec.message().c_str());
|
||||
if (g_log_file) fprintf(g_log_file, "[%s] %s\n", time_now_string(), msg);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
char msg[256];
|
||||
|
@ -897,6 +916,14 @@ void handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
h.resolve_countries(true);
|
||||
#endif
|
||||
|
||||
boost::unordered_set<torrent_status>::iterator j
|
||||
= all_handles.insert(h.status()).first;
|
||||
if (show_torrent(*j, torrent_filter, counters))
|
||||
{
|
||||
filtered_handles.push_back(&*j);
|
||||
need_resort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (torrent_finished_alert* p = alert_cast<torrent_finished_alert>(a))
|
||||
|
@ -946,6 +973,21 @@ void handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
h.save_resume_data();
|
||||
++num_outstanding_resume_data;
|
||||
}
|
||||
else if (state_update_alert* p = alert_cast<state_update_alert>(a))
|
||||
{
|
||||
for (std::vector<torrent_status>::iterator i = p->status.begin();
|
||||
i != p->status.end(); ++i)
|
||||
{
|
||||
boost::unordered_set<torrent_status>::iterator j = all_handles.find(*i);
|
||||
// don't add new entries here, that's done in the handler
|
||||
// for add_torrent_alert
|
||||
if (j == all_handles.end()) continue;
|
||||
((torrent_status&)*j) = *i;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void print_piece(libtorrent::partial_piece_info* pp
|
||||
|
@ -1120,7 +1162,9 @@ int main(int argc, char* argv[])
|
|||
// it was added through the directory monitor. It is used to
|
||||
// be able to remove torrents that were added via the directory
|
||||
// monitor when they're not in the directory anymore.
|
||||
std::vector<torrent_status> handles;
|
||||
boost::unordered_set<torrent_status> all_handles;
|
||||
std::vector<torrent_status const*> filtered_handles;
|
||||
|
||||
handles_t files;
|
||||
// torrents that were not added via the monitor dir
|
||||
std::set<torrent_handle> non_files;
|
||||
|
@ -1447,16 +1491,15 @@ int main(int argc, char* argv[])
|
|||
while (loop_limit > 1 || loop_limit == 0)
|
||||
{
|
||||
++tick;
|
||||
handles.clear();
|
||||
memset(counters, 0, sizeof(counters));
|
||||
ses.get_torrent_status(&handles, boost::bind(&show_torrent, _1, torrent_filter, (int*)counters));
|
||||
if (active_torrent >= int(handles.size())) active_torrent = handles.size() - 1;
|
||||
else if (active_torrent >= 0)
|
||||
ses.post_torrent_updates();
|
||||
if (active_torrent >= int(filtered_handles.size())) active_torrent = filtered_handles.size() - 1;
|
||||
if (active_torrent >= 0)
|
||||
{
|
||||
// ask for distributed copies for the selected torrent. Since this
|
||||
// is a somewhat expensive operation, don't do it by default for
|
||||
// all torrents
|
||||
handles[active_torrent] = handles[active_torrent].handle.status(
|
||||
torrent_status const& h = *filtered_handles[active_torrent];
|
||||
h.handle.status(
|
||||
torrent_handle::query_distributed_copies
|
||||
| torrent_handle::query_pieces
|
||||
| torrent_handle::query_verified_pieces);
|
||||
|
@ -1467,7 +1510,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
counters[torrents_feeds] = feeds.size();
|
||||
|
||||
std::sort(handles.begin(), handles.end(), &compare_torrent);
|
||||
std::sort(filtered_handles.begin(), filtered_handles.end(), &compare_torrent);
|
||||
|
||||
if (loop_limit > 1) --loop_limit;
|
||||
int c = 0;
|
||||
|
@ -1497,11 +1540,7 @@ int main(int argc, char* argv[])
|
|||
if (torrent_filter > 0)
|
||||
{
|
||||
--torrent_filter;
|
||||
handles.clear();
|
||||
memset(counters, 0, sizeof(counters));
|
||||
ses.get_torrent_status(&handles, boost::bind(&show_torrent, _1, torrent_filter, (int*)counters));
|
||||
if (active_torrent >= int(handles.size())) active_torrent = handles.size() - 1;
|
||||
std::sort(handles.begin(), handles.end(), &compare_torrent);
|
||||
update_filtered_torrents(all_handles, filtered_handles, counters);
|
||||
}
|
||||
}
|
||||
else if (c == 67)
|
||||
|
@ -1510,11 +1549,7 @@ int main(int argc, char* argv[])
|
|||
if (torrent_filter < torrents_max - 1)
|
||||
{
|
||||
++torrent_filter;
|
||||
handles.clear();
|
||||
memset(counters, 0, sizeof(counters));
|
||||
ses.get_torrent_status(&handles, boost::bind(&show_torrent, _1, torrent_filter, (int*)counters));
|
||||
if (active_torrent >= int(handles.size())) active_torrent = handles.size() - 1;
|
||||
std::sort(handles.begin(), handles.end(), &compare_torrent);
|
||||
update_filtered_torrents(all_handles, filtered_handles, counters);
|
||||
}
|
||||
}
|
||||
else if (c == 65)
|
||||
|
@ -1527,7 +1562,8 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
// arrow down
|
||||
++active_torrent;
|
||||
if (active_torrent >= int(handles.size())) active_torrent = handles.size() - 1;
|
||||
if (active_torrent >= int(filtered_handles.size()))
|
||||
active_torrent = filtered_handles.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1567,7 +1603,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (c == 'D')
|
||||
{
|
||||
torrent_handle h = get_active_torrent(handles).handle;
|
||||
torrent_handle h = get_active_torrent(filtered_handles).handle;
|
||||
if (h.is_valid())
|
||||
{
|
||||
printf("\n\nARE YOU SURE YOU WANT TO DELETE THE FILES FOR '%s'. THIS OPERATION CANNOT BE UNDONE. (y/N)"
|
||||
|
@ -1592,39 +1628,39 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (c == 'j' && !handles.empty())
|
||||
if (c == 'j' && !filtered_handles.empty())
|
||||
{
|
||||
get_active_torrent(handles).handle.force_recheck();
|
||||
get_active_torrent(filtered_handles).handle.force_recheck();
|
||||
}
|
||||
|
||||
if (c == 'r' && !handles.empty())
|
||||
if (c == 'r' && !filtered_handles.empty())
|
||||
{
|
||||
get_active_torrent(handles).handle.force_reannounce();
|
||||
get_active_torrent(filtered_handles).handle.force_reannounce();
|
||||
}
|
||||
|
||||
if (c == 's' && !handles.empty())
|
||||
if (c == 's' && !filtered_handles.empty())
|
||||
{
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
torrent_status const& ts = get_active_torrent(filtered_handles);
|
||||
ts.handle.set_sequential_download(!ts.sequential_download);
|
||||
}
|
||||
|
||||
if (c == 'R')
|
||||
{
|
||||
// save resume data for all torrents
|
||||
for (std::vector<torrent_status>::iterator i = handles.begin()
|
||||
, end(handles.end()); i != end; ++i)
|
||||
for (std::vector<torrent_status const*>::iterator i = filtered_handles.begin()
|
||||
, end(filtered_handles.end()); i != end; ++i)
|
||||
{
|
||||
if (i->need_save_resume)
|
||||
if ((*i)->need_save_resume)
|
||||
{
|
||||
i->handle.save_resume_data();
|
||||
(*i)->handle.save_resume_data();
|
||||
++num_outstanding_resume_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c == 'o' && !handles.empty())
|
||||
if (c == 'o' && !filtered_handles.empty())
|
||||
{
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
torrent_status const& ts = get_active_torrent(filtered_handles);
|
||||
int num_pieces = ts.num_pieces;
|
||||
if (num_pieces > 300) num_pieces = 300;
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
|
@ -1633,15 +1669,15 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (c == 'v' && !handles.empty())
|
||||
if (c == 'v' && !filtered_handles.empty())
|
||||
{
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
torrent_status const& ts = get_active_torrent(filtered_handles);
|
||||
ts.handle.scrape_tracker();
|
||||
}
|
||||
|
||||
if (c == 'p' && !handles.empty())
|
||||
if (c == 'p' && !filtered_handles.empty())
|
||||
{
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
torrent_status const& ts = get_active_torrent(filtered_handles);
|
||||
if (!ts.auto_managed && ts.paused)
|
||||
{
|
||||
ts.handle.auto_managed(true);
|
||||
|
@ -1654,16 +1690,16 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
// toggle force-start
|
||||
if (c == 'k' && !handles.empty())
|
||||
if (c == 'k' && !filtered_handles.empty())
|
||||
{
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
torrent_status const& ts = get_active_torrent(filtered_handles);
|
||||
ts.handle.auto_managed(!ts.auto_managed);
|
||||
if (ts.auto_managed && ts.paused) ts.handle.resume();
|
||||
}
|
||||
|
||||
if (c == 'c' && !handles.empty())
|
||||
if (c == 'c' && !filtered_handles.empty())
|
||||
{
|
||||
torrent_status const& ts = get_active_torrent(handles);
|
||||
torrent_status const& ts = get_active_torrent(filtered_handles);
|
||||
ts.handle.clear_error();
|
||||
}
|
||||
|
||||
|
@ -1731,16 +1767,26 @@ int main(int argc, char* argv[])
|
|||
for (std::deque<alert*>::iterator i = alerts.begin()
|
||||
, end(alerts.end()); i != end; ++i)
|
||||
{
|
||||
std::string event_string;
|
||||
|
||||
::print_alert(*i, event_string);
|
||||
bool need_resort = false;
|
||||
TORRENT_TRY
|
||||
{
|
||||
::handle_alert(ses, *i, files, non_files);
|
||||
if (!::handle_alert(ses, *i, files, non_files, counters
|
||||
, all_handles, filtered_handles, need_resort))
|
||||
{
|
||||
// if we didn't handle the alert, print it to the log
|
||||
std::string event_string;
|
||||
print_alert(*i, event_string);
|
||||
events.push_back(event_string);
|
||||
if (events.size() >= 20) events.pop_front();
|
||||
}
|
||||
} TORRENT_CATCH(std::exception& e) {}
|
||||
|
||||
events.push_back(event_string);
|
||||
if (events.size() >= 20) events.pop_front();
|
||||
if (need_resort)
|
||||
{
|
||||
std::sort(filtered_handles.begin(), filtered_handles.end()
|
||||
, &compare_torrent);
|
||||
}
|
||||
|
||||
delete *i;
|
||||
}
|
||||
alerts.clear();
|
||||
|
@ -1794,8 +1840,8 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
for (std::vector<torrent_status>::iterator i = handles.begin();
|
||||
i != handles.end(); ++torrent_index)
|
||||
for (std::vector<torrent_status const*>::iterator i = filtered_handles.begin();
|
||||
i != filtered_handles.end(); ++torrent_index)
|
||||
{
|
||||
if (lines_printed >= terminal_height - 15)
|
||||
{
|
||||
|
@ -1803,10 +1849,10 @@ int main(int argc, char* argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
torrent_status& s = *i;
|
||||
torrent_status const& s = **i;
|
||||
if (!s.handle.is_valid())
|
||||
{
|
||||
i = handles.erase(i);
|
||||
i = filtered_handles.erase(i);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -2037,7 +2083,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
torrent_status const* st = 0;
|
||||
if (!handles.empty()) st = &get_active_torrent(handles);
|
||||
if (!filtered_handles.empty()) st = &get_active_torrent(filtered_handles);
|
||||
if (st && st->handle.is_valid())
|
||||
{
|
||||
torrent_handle h = st->handle;
|
||||
|
|
|
@ -71,6 +71,8 @@ namespace libtorrent
|
|||
struct peer_list_entry;
|
||||
struct torrent_status;
|
||||
|
||||
std::size_t hash_value(torrent_status const& ts);
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
// for compatibility with 0.14
|
||||
typedef libtorrent_exception duplicate_torrent;
|
||||
|
@ -155,6 +157,7 @@ namespace libtorrent
|
|||
friend struct aux::session_impl;
|
||||
friend struct feed;
|
||||
friend class torrent;
|
||||
friend std::size_t hash_value(torrent_handle const& th);
|
||||
|
||||
torrent_handle() {}
|
||||
|
||||
|
@ -496,6 +499,9 @@ namespace libtorrent
|
|||
, listen_port(0)
|
||||
{}
|
||||
|
||||
bool operator==(torrent_status const& st) const
|
||||
{ return handle == st.handle; }
|
||||
|
||||
// handle to the torrent
|
||||
torrent_handle handle;
|
||||
|
||||
|
|
|
@ -899,5 +899,14 @@ namespace libtorrent
|
|||
TORRENT_ASYNC_CALL1(reset_piece_deadline, index);
|
||||
}
|
||||
|
||||
std::size_t hash_value(torrent_status const& ts)
|
||||
{
|
||||
return hash_value(ts.handle);
|
||||
}
|
||||
|
||||
std::size_t hash_value(torrent_handle const& th)
|
||||
{
|
||||
return std::size_t(th.m_torrent.lock().get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue