From b1f1fbf114d7e68487537d2681b7b7a272a3d02f Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Tue, 21 Feb 2012 19:49:43 +0200 Subject: [PATCH] Optimize QTorrentHandle --- src/qtlibtorrent/qtorrenthandle.cpp | 130 +++++++++++++++------------- src/qtlibtorrent/qtorrenthandle.h | 21 +++-- 2 files changed, 80 insertions(+), 71 deletions(-) diff --git a/src/qtlibtorrent/qtorrenthandle.cpp b/src/qtlibtorrent/qtorrenthandle.cpp index 357111045..aec44fe75 100644 --- a/src/qtlibtorrent/qtorrenthandle.cpp +++ b/src/qtlibtorrent/qtorrenthandle.cpp @@ -69,7 +69,26 @@ static QString boostTimeToQString(const boost::posix_time::ptime &boostDate) { } #endif -QTorrentHandle::QTorrentHandle(torrent_handle h): torrent_handle(h) {} +static QPair 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 @@ -118,7 +137,7 @@ qlonglong QTorrentHandle::next_announce_s() const { #endif } -qreal QTorrentHandle::progress() const { +float QTorrentHandle::progress() const { #if LIBTORRENT_VERSION_MINOR > 15 torrent_status st = torrent_handle::status(query_accurate_download_counters); #else @@ -128,7 +147,7 @@ qreal QTorrentHandle::progress() const { return 0.; if (st.total_wanted_done == st.total_wanted) 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.); return progress; } @@ -180,32 +199,29 @@ int QTorrentHandle::num_pieces() 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; - for (index = 0; index < num_files(); ++index) { + for (index = 0; index < t.num_files(); ++index) { #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 - QString path = misc::toQStringU(get_torrent_info().file_at(index).path.string()); + QString path = misc::toQStringU(t.file_at(index).path.string()); #endif 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; - } - ++index; } - if (index >= torrent_handle::get_torrent_info().num_files()) 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); - 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()); - 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(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); + + if (index >= t.num_files()) // No media file + return false; + + + QPair extremities = get_file_extremity_pieces (t, index); + + return (torrent_handle::piece_priority(extremities.first) == 7) + && (torrent_handle::piece_priority(extremities.second) == 7); } size_type QTorrentHandle::total_wanted_done() const { @@ -305,9 +321,10 @@ size_type QTorrentHandle::actual_size() const { } bool QTorrentHandle::has_filtered_pieces() const { - std::vector piece_priorities = torrent_handle::piece_priorities(); - for (unsigned int i = 0; i piece_priorities = torrent_handle::piece_priorities(); + foreach (const int priority, piece_priorities) { + if (priority == 0) + return true; } return false; } @@ -480,7 +497,8 @@ bool QTorrentHandle::is_seed() const { // May suffer from approximation problems //return (progress() == 1.); // 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 { @@ -572,7 +590,7 @@ QString QTorrentHandle::error() const { void QTorrentHandle::downloading_pieces(bitfield &bf) const { std::vector queue; torrent_handle::get_download_queue(queue); - for (std::vector::iterator it=queue.begin(); it!= queue.end(); it++) { + for (std::vector::const_iterator it=queue.begin(); it!= queue.end(); it++) { bf.set_bit(it->piece_index); } return; @@ -609,7 +627,9 @@ void QTorrentHandle::pause() const { } void QTorrentHandle::resume() const { - if (has_error()) torrent_handle::clear_error(); + if (has_error()) + torrent_handle::clear_error(); + const QString torrent_hash = hash(); bool has_persistant_error = TorrentPersistentData::hasError(torrent_hash); 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()); } -void QTorrentHandle::add_url_seed(QString seed) const { +void QTorrentHandle::add_url_seed(const QString& seed) const { const std::string str_seed = seed.toStdString(); qDebug("calling torrent_handle::add_url_seed(%s)", str_seed.c_str()); 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())); } -void QTorrentHandle::move_storage(QString new_path) const { - if (QDir(save_path()) == QDir(new_path)) return; +void QTorrentHandle::move_storage(const QString& new_path) const { + if (QDir(save_path()) == QDir(new_path)) + return; + TorrentPersistentData::setPreviousSavePath(hash(), save_path()); // Create destination directory if necessary // 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()); } -bool QTorrentHandle::save_torrent_file(QString path) const { +bool QTorrentHandle::save_torrent_file(const QString& path) const { 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); torrent_entry["info"] = meta; if (!torrent_handle::trackers().empty()) @@ -692,7 +717,7 @@ void QTorrentHandle::prioritize_files(const vector &files) const { qDebug() << Q_FUNC_INFO << "Changing files priorities..."; torrent_handle::prioritize_files(files); qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder..."; - for (uint i=0; i &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 { // Determine the priority to set - int prio = 7; // MAX - if (!b) prio = torrent_handle::file_priority(file_index); - file_entry file = get_torrent_info().file_at(file_index); - // Determine the first and last piece of the file - int piece_size = torrent_handle::get_torrent_info().piece_length(); - 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); + int prio = b ? 7 : torrent_handle::file_priority(file_index); + + QPair extremities = get_file_extremity_pieces (get_torrent_info(), file_index); + piece_priority(extremities.first, prio); + piece_priority(extremities.second, prio); } void QTorrentHandle::prioritize_first_last_piece(bool b) const { if (!has_metadata()) return; // Download first and last pieces first for all media files in the torrent - int index = 0; - for (index = 0; index < num_files(); ++index) { + const uint nbfiles = num_files(); + for (uint index = 0; index < nbfiles; ++index) { const QString path = filepath_at(index); const QString ext = misc::file_extension(path); 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; 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 { - const QString hash = misc::toQString(torrent_handle::info_hash()); - return (hash == new_h.hash()); + return info_hash() == new_h.info_hash(); } diff --git a/src/qtlibtorrent/qtorrenthandle.h b/src/qtlibtorrent/qtorrenthandle.h index c592d563b..5a60a4d00 100644 --- a/src/qtlibtorrent/qtorrenthandle.h +++ b/src/qtlibtorrent/qtorrenthandle.h @@ -52,14 +52,14 @@ public: // QTorrentHandle() {} - explicit QTorrentHandle(libtorrent::torrent_handle h); + explicit QTorrentHandle(const libtorrent::torrent_handle& h); // // Getters // QString hash() const; QString name() const; - qreal progress() const; + float progress() const; libtorrent::bitfield pieces() const; QString current_tracker() const; bool is_paused() const; @@ -116,7 +116,7 @@ public: QString firstFileSavePath() const; bool has_error() const; QString error() const; - void downloading_pieces(libtorrent::bitfield &bf) const; + void downloading_pieces(libtorrent::bitfield& bf) const; bool has_metadata() const; float distributed_copies() const; void file_progress(std::vector& fp) const; @@ -126,15 +126,14 @@ public: // void pause() const; void resume() const; - void remove_url_seed(QString seed) const; - void add_url_seed(QString seed) const; - void set_tracker_login(QString username, QString password) const; - void move_storage(QString path) const; - void add_tracker(const libtorrent::announce_entry& url) const; + void remove_url_seed(const QString& seed) const; + void add_url_seed(const QString& seed) const; + void set_tracker_login(const QString& username, const QString& password) const; + void move_storage(const QString& path) const; void prioritize_first_last_piece(bool b) const; - void rename_file(int index, QString name) const; - bool save_torrent_file(QString path) const; - void prioritize_files(const std::vector &files) const; + void rename_file(int index, const QString& name) const; + bool save_torrent_file(const QString& path) const; + void prioritize_files(const std::vector& files) const; void file_priority(int index, int priority) const; //