Browse Source

Optimize QTorrentHandle

adaptive-webui-19844
Christophe Dumez 13 years ago
parent
commit
b1f1fbf114
  1. 130
      src/qtlibtorrent/qtorrenthandle.cpp
  2. 21
      src/qtlibtorrent/qtorrenthandle.h

130
src/qtlibtorrent/qtorrenthandle.cpp

@ -69,7 +69,26 @@ static QString boostTimeToQString(const boost::posix_time::ptime &boostDate) {
} }
#endif #endif
QTorrentHandle::QTorrentHandle(torrent_handle h): torrent_handle(h) {} static QPair<int, int> get_file_extremity_pieces(const torrent_info& t, int file_index)
{
const int num_pieces = t.num_pieces();
const int piece_size = t.piece_length();
const file_entry& file = t.file_at(file_index);
// Determine the first and last piece of the file
int first_piece = floor((file.offset + 1) / (float) piece_size);
Q_ASSERT(first_piece >= 0 && first_piece < num_pieces);
qDebug("First piece of the file is %d/%d", first_piece, num_pieces - 1);
int num_pieces_in_file = ceil(file.size / (float) piece_size);
int last_piece = first_piece + num_pieces_in_file - 1;
Q_ASSERT(last_piece >= 0 && last_piece < num_pieces);
qDebug("last piece of the file is %d/%d", last_piece, num_pieces - 1);
return qMakePair(first_piece, last_piece);
}
QTorrentHandle::QTorrentHandle(const torrent_handle& h): torrent_handle(h) {}
// //
// Getters // Getters
@ -118,7 +137,7 @@ qlonglong QTorrentHandle::next_announce_s() const {
#endif #endif
} }
qreal QTorrentHandle::progress() const { float QTorrentHandle::progress() const {
#if LIBTORRENT_VERSION_MINOR > 15 #if LIBTORRENT_VERSION_MINOR > 15
torrent_status st = torrent_handle::status(query_accurate_download_counters); torrent_status st = torrent_handle::status(query_accurate_download_counters);
#else #else
@ -128,7 +147,7 @@ qreal QTorrentHandle::progress() const {
return 0.; return 0.;
if (st.total_wanted_done == st.total_wanted) if (st.total_wanted_done == st.total_wanted)
return 1.; return 1.;
qreal progress = (float)st.total_wanted_done/(float)st.total_wanted; float progress = (float) st.total_wanted_done / (float) st.total_wanted;
Q_ASSERT(progress >= 0. && progress <= 1.); Q_ASSERT(progress >= 0. && progress <= 1.);
return progress; return progress;
} }
@ -180,32 +199,29 @@ int QTorrentHandle::num_pieces() const {
} }
bool QTorrentHandle::first_last_piece_first() const { bool QTorrentHandle::first_last_piece_first() const {
// Detect first media file const torrent_info& t = get_torrent_info();
// Get int first media file
int index = 0; int index = 0;
for (index = 0; index < num_files(); ++index) { for (index = 0; index < t.num_files(); ++index) {
#if LIBTORRENT_VERSION_MINOR > 15 #if LIBTORRENT_VERSION_MINOR > 15
QString path = misc::toQStringU(get_torrent_info().file_at(index).path); QString path = misc::toQStringU(t.file_at(index).path);
#else #else
QString path = misc::toQStringU(get_torrent_info().file_at(index).path.string()); QString path = misc::toQStringU(t.file_at(index).path.string());
#endif #endif
const QString ext = misc::file_extension(path); const QString ext = misc::file_extension(path);
if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) { if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0)
break; break;
} }
++index;
} if (index >= t.num_files()) // No media file
if (index >= torrent_handle::get_torrent_info().num_files()) return false; return false;
file_entry media_file = torrent_handle::get_torrent_info().file_at(index);
int piece_size = torrent_handle::get_torrent_info().piece_length();
Q_ASSERT(piece_size>0); QPair<int, int> extremities = get_file_extremity_pieces (t, index);
int first_piece = floor((media_file.offset+1)/(double)piece_size);
Q_ASSERT(first_piece >= 0 && first_piece < torrent_handle::get_torrent_info().num_pieces()); return (torrent_handle::piece_priority(extremities.first) == 7)
qDebug("First piece of the file is %d/%d", first_piece, torrent_handle::get_torrent_info().num_pieces()-1); && (torrent_handle::piece_priority(extremities.second) == 7);
int num_pieces_in_file = ceil(media_file.size/(double)piece_size);
int last_piece = first_piece+num_pieces_in_file-1;
Q_ASSERT(last_piece >= 0 && last_piece < torrent_handle::get_torrent_info().num_pieces());
qDebug("last piece of the file is %d/%d", last_piece, torrent_handle::get_torrent_info().num_pieces()-1);
return (torrent_handle::piece_priority(first_piece) == 7) && (torrent_handle::piece_priority(last_piece) == 7);
} }
size_type QTorrentHandle::total_wanted_done() const { size_type QTorrentHandle::total_wanted_done() const {
@ -305,9 +321,10 @@ size_type QTorrentHandle::actual_size() const {
} }
bool QTorrentHandle::has_filtered_pieces() const { bool QTorrentHandle::has_filtered_pieces() const {
std::vector<int> piece_priorities = torrent_handle::piece_priorities(); const std::vector<int> piece_priorities = torrent_handle::piece_priorities();
for (unsigned int i = 0; i<piece_priorities.size(); ++i) { foreach (const int priority, piece_priorities) {
if (!piece_priorities[i]) return true; if (priority == 0)
return true;
} }
return false; return false;
} }
@ -480,7 +497,8 @@ bool QTorrentHandle::is_seed() const {
// May suffer from approximation problems // May suffer from approximation problems
//return (progress() == 1.); //return (progress() == 1.);
// This looks safe // This looks safe
return (state() == torrent_status::finished || state() == torrent_status::seeding); torrent_status::state_t st = state();
return (st == torrent_status::finished || st == torrent_status::seeding);
} }
bool QTorrentHandle::is_auto_managed() const { bool QTorrentHandle::is_auto_managed() const {
@ -572,7 +590,7 @@ QString QTorrentHandle::error() const {
void QTorrentHandle::downloading_pieces(bitfield &bf) const { void QTorrentHandle::downloading_pieces(bitfield &bf) const {
std::vector<partial_piece_info> queue; std::vector<partial_piece_info> queue;
torrent_handle::get_download_queue(queue); torrent_handle::get_download_queue(queue);
for (std::vector<partial_piece_info>::iterator it=queue.begin(); it!= queue.end(); it++) { for (std::vector<partial_piece_info>::const_iterator it=queue.begin(); it!= queue.end(); it++) {
bf.set_bit(it->piece_index); bf.set_bit(it->piece_index);
} }
return; return;
@ -609,7 +627,9 @@ void QTorrentHandle::pause() const {
} }
void QTorrentHandle::resume() const { void QTorrentHandle::resume() const {
if (has_error()) torrent_handle::clear_error(); if (has_error())
torrent_handle::clear_error();
const QString torrent_hash = hash(); const QString torrent_hash = hash();
bool has_persistant_error = TorrentPersistentData::hasError(torrent_hash); bool has_persistant_error = TorrentPersistentData::hasError(torrent_hash);
TorrentPersistentData::setErrorState(torrent_hash, false); TorrentPersistentData::setErrorState(torrent_hash, false);
@ -630,22 +650,24 @@ void QTorrentHandle::resume() const {
} }
} }
void QTorrentHandle::remove_url_seed(QString seed) const { void QTorrentHandle::remove_url_seed(const QString& seed) const {
torrent_handle::remove_url_seed(seed.toStdString()); torrent_handle::remove_url_seed(seed.toStdString());
} }
void QTorrentHandle::add_url_seed(QString seed) const { void QTorrentHandle::add_url_seed(const QString& seed) const {
const std::string str_seed = seed.toStdString(); const std::string str_seed = seed.toStdString();
qDebug("calling torrent_handle::add_url_seed(%s)", str_seed.c_str()); qDebug("calling torrent_handle::add_url_seed(%s)", str_seed.c_str());
torrent_handle::add_url_seed(str_seed); torrent_handle::add_url_seed(str_seed);
} }
void QTorrentHandle::set_tracker_login(QString username, QString password) const { void QTorrentHandle::set_tracker_login(const QString& username, const QString& password) const {
torrent_handle::set_tracker_login(std::string(username.toLocal8Bit().constData()), std::string(password.toLocal8Bit().constData())); torrent_handle::set_tracker_login(std::string(username.toLocal8Bit().constData()), std::string(password.toLocal8Bit().constData()));
} }
void QTorrentHandle::move_storage(QString new_path) const { void QTorrentHandle::move_storage(const QString& new_path) const {
if (QDir(save_path()) == QDir(new_path)) return; if (QDir(save_path()) == QDir(new_path))
return;
TorrentPersistentData::setPreviousSavePath(hash(), save_path()); TorrentPersistentData::setPreviousSavePath(hash(), save_path());
// Create destination directory if necessary // Create destination directory if necessary
// or move_storage() will fail... // or move_storage() will fail...
@ -654,10 +676,13 @@ void QTorrentHandle::move_storage(QString new_path) const {
torrent_handle::move_storage(new_path.toUtf8().constData()); torrent_handle::move_storage(new_path.toUtf8().constData());
} }
bool QTorrentHandle::save_torrent_file(QString path) const { bool QTorrentHandle::save_torrent_file(const QString& path) const {
if (!has_metadata()) return false; if (!has_metadata()) return false;
entry meta = bdecode(torrent_handle::get_torrent_info().metadata().get(), torrent_handle::get_torrent_info().metadata().get()+torrent_handle::get_torrent_info().metadata_size()); const torrent_info& t = torrent_handle::get_torrent_info();
entry meta = bdecode(t.metadata().get(),
t.metadata().get() + t.metadata_size());
entry torrent_entry(entry::dictionary_t); entry torrent_entry(entry::dictionary_t);
torrent_entry["info"] = meta; torrent_entry["info"] = meta;
if (!torrent_handle::trackers().empty()) if (!torrent_handle::trackers().empty())
@ -692,7 +717,7 @@ void QTorrentHandle::prioritize_files(const vector<int> &files) const {
qDebug() << Q_FUNC_INFO << "Changing files priorities..."; qDebug() << Q_FUNC_INFO << "Changing files priorities...";
torrent_handle::prioritize_files(files); torrent_handle::prioritize_files(files);
qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder..."; qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder...";
for (uint i=0; i<files.size(); ++i) { for (uint i = 0; i < files.size(); ++i) {
// Move unwanted files to a .unwanted subfolder // Move unwanted files to a .unwanted subfolder
if (files[i] == 0 && progress[i] < filesize_at(i)) { if (files[i] == 0 && progress[i] < filesize_at(i)) {
QString old_path = filepath_at(i); QString old_path = filepath_at(i);
@ -761,34 +786,20 @@ void QTorrentHandle::prioritize_files(const vector<int> &files) const {
} }
} }
void QTorrentHandle::add_tracker(const announce_entry& url) const {
torrent_handle::add_tracker(url);
}
void QTorrentHandle::prioritize_first_last_piece(int file_index, bool b) const { void QTorrentHandle::prioritize_first_last_piece(int file_index, bool b) const {
// Determine the priority to set // Determine the priority to set
int prio = 7; // MAX int prio = b ? 7 : torrent_handle::file_priority(file_index);
if (!b) prio = torrent_handle::file_priority(file_index);
file_entry file = get_torrent_info().file_at(file_index); QPair<int, int> extremities = get_file_extremity_pieces (get_torrent_info(), file_index);
// Determine the first and last piece of the file piece_priority(extremities.first, prio);
int piece_size = torrent_handle::get_torrent_info().piece_length(); piece_priority(extremities.second, prio);
Q_ASSERT(piece_size>0);
int first_piece = floor((file.offset+1)/(double)piece_size);
Q_ASSERT(first_piece >= 0 && first_piece < torrent_handle::get_torrent_info().num_pieces());
qDebug("First piece of the file is %d/%d", first_piece, torrent_handle::get_torrent_info().num_pieces()-1);
int num_pieces_in_file = ceil(file.size/(double)piece_size);
int last_piece = first_piece+num_pieces_in_file-1;
Q_ASSERT(last_piece >= 0 && last_piece < torrent_handle::get_torrent_info().num_pieces());
qDebug("last piece of the file is %d/%d", last_piece, torrent_handle::get_torrent_info().num_pieces()-1);
torrent_handle::piece_priority(first_piece, prio);
torrent_handle::piece_priority(last_piece, prio);
} }
void QTorrentHandle::prioritize_first_last_piece(bool b) const { void QTorrentHandle::prioritize_first_last_piece(bool b) const {
if (!has_metadata()) return; if (!has_metadata()) return;
// Download first and last pieces first for all media files in the torrent // Download first and last pieces first for all media files in the torrent
int index = 0; const uint nbfiles = num_files();
for (index = 0; index < num_files(); ++index) { for (uint index = 0; index < nbfiles; ++index) {
const QString path = filepath_at(index); const QString path = filepath_at(index);
const QString ext = misc::file_extension(path); const QString ext = misc::file_extension(path);
if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) { if (misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) {
@ -798,7 +809,7 @@ void QTorrentHandle::prioritize_first_last_piece(bool b) const {
} }
} }
void QTorrentHandle::rename_file(int index, QString name) const { void QTorrentHandle::rename_file(int index, const QString& name) const {
qDebug() << Q_FUNC_INFO << index << name; qDebug() << Q_FUNC_INFO << index << name;
torrent_handle::rename_file(index, std::string(name.toUtf8().constData())); torrent_handle::rename_file(index, std::string(name.toUtf8().constData()));
} }
@ -808,6 +819,5 @@ void QTorrentHandle::rename_file(int index, QString name) const {
// //
bool QTorrentHandle::operator ==(const QTorrentHandle& new_h) const { bool QTorrentHandle::operator ==(const QTorrentHandle& new_h) const {
const QString hash = misc::toQString(torrent_handle::info_hash()); return info_hash() == new_h.info_hash();
return (hash == new_h.hash());
} }

21
src/qtlibtorrent/qtorrenthandle.h

@ -52,14 +52,14 @@ public:
// //
QTorrentHandle() {} QTorrentHandle() {}
explicit QTorrentHandle(libtorrent::torrent_handle h); explicit QTorrentHandle(const libtorrent::torrent_handle& h);
// //
// Getters // Getters
// //
QString hash() const; QString hash() const;
QString name() const; QString name() const;
qreal progress() const; float progress() const;
libtorrent::bitfield pieces() const; libtorrent::bitfield pieces() const;
QString current_tracker() const; QString current_tracker() const;
bool is_paused() const; bool is_paused() const;
@ -116,7 +116,7 @@ public:
QString firstFileSavePath() const; QString firstFileSavePath() const;
bool has_error() const; bool has_error() const;
QString error() const; QString error() const;
void downloading_pieces(libtorrent::bitfield &bf) const; void downloading_pieces(libtorrent::bitfield& bf) const;
bool has_metadata() const; bool has_metadata() const;
float distributed_copies() const; float distributed_copies() const;
void file_progress(std::vector<libtorrent::size_type>& fp) const; void file_progress(std::vector<libtorrent::size_type>& fp) const;
@ -126,15 +126,14 @@ public:
// //
void pause() const; void pause() const;
void resume() const; void resume() const;
void remove_url_seed(QString seed) const; void remove_url_seed(const QString& seed) const;
void add_url_seed(QString seed) const; void add_url_seed(const QString& seed) const;
void set_tracker_login(QString username, QString password) const; void set_tracker_login(const QString& username, const QString& password) const;
void move_storage(QString path) const; void move_storage(const QString& path) const;
void add_tracker(const libtorrent::announce_entry& url) const;
void prioritize_first_last_piece(bool b) const; void prioritize_first_last_piece(bool b) const;
void rename_file(int index, QString name) const; void rename_file(int index, const QString& name) const;
bool save_torrent_file(QString path) const; bool save_torrent_file(const QString& path) const;
void prioritize_files(const std::vector<int> &files) const; void prioritize_files(const std::vector<int>& files) const;
void file_priority(int index, int priority) const; void file_priority(int index, int priority) const;
// //

Loading…
Cancel
Save