From 80f61880b7c50a345ee95722b8d307b97873815d Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Fri, 29 Jun 2007 15:23:15 +0000 Subject: [PATCH] made ETA calculation more reliable --- Changelog | 1 + TODO | 3 ++- src/GUI.cpp | 8 ++++---- src/bittorrent.cpp | 46 +++++++++++++++++++++++++++++++++++++++++----- src/bittorrent.h | 6 ++++++ 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/Changelog b/Changelog index 2ac90a82c..01e8394b8 100644 --- a/Changelog +++ b/Changelog @@ -20,6 +20,7 @@ - FEATURE: Added a way to link against static libtorrent (useful for deb packages) - BUGFIX: Progress of paused torrents is now correct on restart - BUGFIX: Progress column gets sorted on restart it is was during last execution + - BUGFIX: Made ETA more reliable using stats instead of instant values - COSMETIC: Redesigned torrent properties a little - COSMETIC: Redesigned options a little - COSMETIC: Display more logs messages concerning features diff --git a/TODO b/TODO index ee31c41ae..9a48b3c9c 100644 --- a/TODO +++ b/TODO @@ -45,4 +45,5 @@ - Allow the user to see when peers were blocked thanks to IPFilter. Maybe in a file in order not to spam the GUI. - Allow to scan multiple directories - Fix all (or almost all) opened bugs in bug tracker -- Fix sorting with Qt 4.3 - Reported to Trolltech, waiting for fix \ No newline at end of file +- Fix sorting with Qt 4.3 - Reported to Trolltech, waiting for fix +- update sorting when a new torrent is added \ No newline at end of file diff --git a/src/GUI.cpp b/src/GUI.cpp index 24686ddf5..482fc80b1 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -534,7 +534,7 @@ void GUI::updateDlList(bool force){ if(torrentStatus.download_payload_rate > 0){ // Display "Downloading" status when connecting if download speed > 0 DLListModel->setData(DLListModel->index(row, STATUS), QVariant(tr("Downloading..."))); - DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)((ti.total_size()-torrentStatus.total_done)/(double)torrentStatus.download_payload_rate))); + DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession.getETA(fileHash))); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(":/Icons/skin/downloading.png")), Qt::DecorationRole); setRowColor(row, "green"); }else{ @@ -552,7 +552,7 @@ void GUI::updateDlList(bool force){ if(torrentStatus.download_payload_rate > 0){ DLListModel->setData(DLListModel->index(row, STATUS), QVariant(tr("Downloading..."))); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(":/Icons/skin/downloading.png")), Qt::DecorationRole); - DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)((ti.total_size()-torrentStatus.total_done)/(double)torrentStatus.download_payload_rate))); + DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession.getETA(fileHash))); setRowColor(row, "green"); }else{ DLListModel->setData(DLListModel->index(row, STATUS), QVariant(tr("Stalled", "i.e: State of a torrent whose download speed is 0kb/s"))); @@ -694,8 +694,8 @@ void GUI::sortDownloadList(int index, Qt::SortOrder startSortOrder, bool fromLoa default: sortDownloadListString(index, sortOrder); } - QSettings settings("qBittorrent", "qBittorrent"); - settings.setValue("DownloadListSortedCol", QString(misc::toString(index).c_str())+sortOrderLetter); + QSettings settings("qBittorrent", "qBittorrent"); + settings.setValue("DownloadListSortedCol", QString(misc::toString(index).c_str())+sortOrderLetter); } // Toggle Main window visibility diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index df3219c70..669bfb4f1 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -28,6 +28,8 @@ #include "misc.h" #include "downloadThread.h" +#define ETAS_MAX_VALUES 5 + // Main constructor bittorrent::bittorrent(){ // To avoid some exceptions @@ -51,11 +53,6 @@ bittorrent::bittorrent(){ connect(downloader, SIGNAL(downloadFinished(const QString&, const QString&, int, const QString&)), this, SLOT(processDownloadedFile(const QString&, const QString&, int, const QString&))); } -void bittorrent::resumeUnfinishedTorrents(){ - // Resume unfinished torrents - resumeUnfinished(); -} - // Main destructor bittorrent::~bittorrent(){ disableDirectoryScanning(); @@ -64,6 +61,40 @@ bittorrent::~bittorrent(){ delete s; } +void bittorrent::resumeUnfinishedTorrents(){ + // Resume unfinished torrents + resumeUnfinished(); +} + +void bittorrent::updateETAs(){ + std::vector handles = s->get_torrents(); + for(unsigned int i=0; i listEtas = ETAstats.value(hash, QList()); + if(listEtas.size() == ETAS_MAX_VALUES){ + long moy = 0; + long val; + foreach(val, listEtas){ + moy += val; + } + ETAs[hash] = (long) ((double)moy/(double)ETAS_MAX_VALUES); + ETAstats[hash] = QList(); + }else{ + torrent_status torrentStatus = h.status(); + torrent_info ti = h.get_torrent_info(); + listEtas << (long)((ti.total_size()-torrentStatus.total_done)/(double)torrentStatus.download_payload_rate); + ETAstats[hash] = listEtas; + } + } + } +} + +long bittorrent::getETA(QString hash) const{ + return ETAs.value(hash, -1); +} + // Return the torrent handle, given its hash torrent_handle bittorrent::getTorrentHandle(const QString& hash) const{ return s->find_torrent(misc::fromString((hash.toStdString()))); @@ -101,6 +132,9 @@ void bittorrent::deleteTorrent(const QString& hash, bool permanent){ torrentBackup.remove(hash+".priorities"); torrentBackup.remove(hash+".savepath"); torrentBackup.remove(hash+".trackers"); + // Remove it fro ETAs hash tables + ETAstats.take(hash); + ETAs.take(hash); if(permanent){ // Remove from Hard drive qDebug("Removing this on hard drive: %s", qPrintable(savePath+QDir::separator()+fileName)); @@ -674,6 +708,8 @@ void bittorrent::readAlerts(){ } a = s->pop_alert(); } + // ETAs + updateETAs(); } void bittorrent::reloadTorrent(const torrent_handle &h, bool compact_mode){ diff --git a/src/bittorrent.h b/src/bittorrent.h index dee7a480e..b5b4bc595 100644 --- a/src/bittorrent.h +++ b/src/bittorrent.h @@ -21,6 +21,8 @@ #ifndef __BITTORRENT_H__ #define __BITTORRENT_H__ +#include + #include #include #include @@ -59,6 +61,8 @@ class bittorrent : public QObject{ QString defaultSavePath; QStringList torrentsToPauseAfterChecking; QStringList torrentsUnchecked; + QHash > ETAstats; + QHash ETAs; protected: QString getSavePath(const QString& hash); @@ -80,6 +84,7 @@ class bittorrent : public QObject{ int getListenPort() const; QStringList getTorrentsToPauseAfterChecking() const; QStringList getUncheckedTorrentsList() const; + long getETA(QString hash) const; public slots: void addTorrent(const QString& path, bool fromScanDir = false, bool onStartup = false, const QString& from_url = QString()); @@ -102,6 +107,7 @@ class bittorrent : public QObject{ void reloadTorrent(const torrent_handle &h, bool compact_mode = true); void setTorrentFinishedChecking(QString hash); void resumeUnfinishedTorrents(); + void updateETAs(); // Session configuration - Setters void setListeningPortsRange(std::pair ports); void setMaxConnections(int maxConnec);