added async_add_torrent for increased performance when adding many torrents (no documentation yet though)

This commit is contained in:
Arvid Norberg 2011-10-12 10:27:17 +00:00
parent 268ea59876
commit 01405f32ee
10 changed files with 100 additions and 19 deletions

View File

@ -661,7 +661,7 @@ using boost::bind;
// is, it should be remembered so that it can be removed
// if it's no longer in that directory.
void add_torrent(libtorrent::session& ses
, handles_t& handles
, handles_t& files
, std::set<libtorrent::torrent_handle>& non_files
, std::string const& torrent
, float preferred_ratio
@ -702,22 +702,16 @@ void add_torrent(libtorrent::session& ses
p.paused = true;
p.duplicate_is_error = false;
p.auto_managed = true;
torrent_handle h = ses.add_torrent(p, ec);
if (ec)
if (monitored_dir)
{
fprintf(stderr, "failed to add torrent: %s\n", ec.message().c_str());
p.userdata = (void*)strdup(torrent.c_str());
ses.async_add_torrent(p);
return;
}
if (monitored_dir)
{
handles.insert(std::pair<const std::string, torrent_handle>(
torrent, h));
}
else
{
non_files.insert(h);
}
torrent_handle h = ses.add_torrent(p, ec);
non_files.insert(h);
h.set_max_connections(max_connections_per_torrent);
h.set_max_uploads(-1);
@ -846,7 +840,7 @@ int save_file(std::string const& filename, std::vector<char>& v)
}
void handle_alert(libtorrent::session& ses, libtorrent::alert* a
, handles_t const& files, std::set<libtorrent::torrent_handle> const& non_files)
, handles_t& files, std::set<libtorrent::torrent_handle> const& non_files)
{
using namespace libtorrent;
@ -884,7 +878,33 @@ void handle_alert(libtorrent::session& ses, libtorrent::alert* a
}
#endif
if (torrent_finished_alert* p = alert_cast<torrent_finished_alert>(a))
if (add_torrent_alert* p = alert_cast<add_torrent_alert>(a))
{
std::string filename = (char*)p->params.userdata;
free(p->params.userdata);
if (p->error)
{
fprintf(stderr, "failed to add torrent: %s %s\n", filename.c_str(), p->error.message().c_str());
}
else
{
torrent_handle h = p->handle;
files.insert(std::pair<const std::string, torrent_handle>(filename, h));
h.set_max_connections(max_connections_per_torrent);
h.set_max_uploads(-1);
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
h.use_interface(outgoing_interface.c_str());
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
h.resolve_countries(true);
#endif
}
}
else if (torrent_finished_alert* p = alert_cast<torrent_finished_alert>(a))
{
p->handle.set_max_connections(max_connections_per_torrent / 2);

View File

@ -1294,6 +1294,23 @@ namespace libtorrent
tcp::endpoint ip;
};
struct TORRENT_EXPORT add_torrent_alert : torrent_alert
{
add_torrent_alert(torrent_handle h, add_torrent_params const& p, error_code ec)
: torrent_alert(h)
, params(p)
, error(ec)
{}
TORRENT_DEFINE_ALERT(add_torrent_alert);
const static int static_category = alert::status_notification;
virtual std::string message() const;
virtual bool discardable() const { return false; }
add_torrent_params params;
error_code error;
};
}

View File

@ -310,6 +310,7 @@ namespace libtorrent
bool is_listening() const;
torrent_handle add_torrent(add_torrent_params const&, error_code& ec);
void async_add_torrent(add_torrent_params* params);
void remove_torrent(torrent_handle const& h, int options);
void remove_torrent_impl(boost::shared_ptr<torrent> tptr, int options);

View File

@ -250,6 +250,7 @@ namespace libtorrent
size_type file_base(internal_file_entry const& fe) const;
void set_file_base(internal_file_entry const& fe, size_type off);
std::string file_path(internal_file_entry const& fe) const;
size_type file_size(internal_file_entry const& fe) const;
#if !defined TORRENT_VERBOSE_LOGGING \
&& !defined TORRENT_LOGGING \

View File

@ -198,6 +198,7 @@ namespace libtorrent
torrent_handle add_torrent(add_torrent_params const& params);
#endif
torrent_handle add_torrent(add_torrent_params const& params, error_code& ec);
void async_add_torrent(add_torrent_params const& params);
#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE

View File

@ -587,5 +587,19 @@ namespace libtorrent {
return msg;
}
std::string add_torrent_alert::message() const
{
char msg[600];
if (error)
{
snprintf(msg, sizeof(msg), "failed to add torrent: %s", error.message().c_str());
}
else
{
snprintf(msg, sizeof(msg), "added torrent: %s", !params.url.empty() ? params.url.c_str() : params.ti->name().c_str());
}
return msg;
}
} // namespace libtorrent

View File

@ -275,6 +275,11 @@ namespace libtorrent
return combine_path(m_paths[fe.path_index], fe.filename());
}
size_type file_storage::file_size(internal_file_entry const& fe) const
{
return fe.size;
}
peer_request file_storage::map_file(int file_index, size_type file_offset
, int size) const
{

View File

@ -610,6 +610,15 @@ namespace libtorrent
return r;
}
void session::async_add_torrent(add_torrent_params const& params)
{
add_torrent_params* p = new add_torrent_params(params);
if (params.resume_data) p->resume_data = new std::vector<char>(*params.resume_data);
if (params.tracker_url) p->tracker_url = strdup(params.tracker_url);
if (params.name) p->name = strdup(params.name);
TORRENT_ASYNC_CALL1(async_add_torrent, p);
}
#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE
// if the torrent already exists, this will throw duplicate_torrent

View File

@ -4251,6 +4251,17 @@ namespace aux {
return torrent_handle(find_torrent(info_hash));
}
void session_impl::async_add_torrent(add_torrent_params* params)
{
error_code ec;
torrent_handle handle = add_torrent(*params, ec);
m_alerts.post_alert(add_torrent_alert(handle, *params, ec));
delete params->resume_data;
free((char*)params->tracker_url);
free((char*)params->name);
delete params;
}
torrent_handle session_impl::add_torrent(add_torrent_params const& params
, error_code& ec)
{

View File

@ -3936,13 +3936,15 @@ ctx->set_verify_callback(verify_function, ec);
// initialize the piece priorities to 0, then only allow
// setting higher priorities
std::vector<int> pieces(m_torrent_file->num_pieces(), 0);
for (int i = 0; i < int(m_file_priority.size()); ++i)
int index = 0;
for (file_storage::iterator i = m_torrent_file->files().begin()
, end(m_torrent_file->files().end()); i != end; ++i, ++index)
{
size_type start = position;
size_type size = m_torrent_file->files().at(i).size;
size_type size = m_torrent_file->files().file_size(*i);
if (size == 0) continue;
position += size;
if (m_file_priority[i] == 0) continue;
if (m_file_priority[index] == 0) continue;
// mark all pieces of the file with this file's priority
// but only if the priority is higher than the pieces
@ -3954,7 +3956,7 @@ ctx->set_verify_callback(verify_function, ec);
// come here several times with the same start_piece, end_piece
std::for_each(pieces.begin() + start_piece
, pieces.begin() + last_piece + 1
, boost::bind(&set_if_greater, _1, m_file_priority[i]));
, boost::bind(&set_if_greater, _1, m_file_priority[index]));
}
prioritize_pieces(pieces);
}