diff --git a/src/qtlibtorrent/torrentmodel.cpp b/src/qtlibtorrent/torrentmodel.cpp index 2dde082b0..435c62af7 100644 --- a/src/qtlibtorrent/torrentmodel.cpp +++ b/src/qtlibtorrent/torrentmodel.cpp @@ -172,7 +172,7 @@ QVariant TorrentModelItem::data(int column, int role) const return m_torrent.upload_payload_rate(); case TR_ETA: { // XXX: Is this correct? - if (m_torrent.is_seed() || m_torrent.is_paused() || m_torrent.is_queued()) return MAX_ETA; + if (m_torrent.is_paused() || m_torrent.is_queued()) return MAX_ETA; return QBtSession::instance()->getETA(m_torrent.hash()); } case TR_RATIO: diff --git a/src/qtlibtorrent/torrentspeedmonitor.cpp b/src/qtlibtorrent/torrentspeedmonitor.cpp index 56bbfde3e..fae0189e9 100644 --- a/src/qtlibtorrent/torrentspeedmonitor.cpp +++ b/src/qtlibtorrent/torrentspeedmonitor.cpp @@ -38,19 +38,25 @@ using namespace libtorrent; +template struct Sample { + Sample(const T down = 0, const T up = 0) : download(down), upload(up) {} + T download; + T upload; +}; + class SpeedSample { public: SpeedSample() {} - void addSample(int s); - qreal average() const; + void addSample(int speedDL, int speedUL); + Sample average() const; void clear(); private: static const int max_samples = 30; private: - QList m_speedSamples; + QList > m_speedSamples; }; TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session) : @@ -76,21 +82,28 @@ void TorrentSpeedMonitor::run() } while(!m_abort); } -void SpeedSample::addSample(int s) +void SpeedSample::addSample(int speedDL, int speedUL) { - m_speedSamples << s; + m_speedSamples << Sample(speedDL, speedUL); if (m_speedSamples.size() > max_samples) m_speedSamples.removeFirst(); } -qreal SpeedSample::average() const +Sample SpeedSample::average() const { - if (m_speedSamples.empty()) return 0; - qlonglong sum = 0; - foreach (int s, m_speedSamples) { - sum += s; + if (m_speedSamples.empty()) + return Sample(); + + qlonglong sumDL = 0; + qlonglong sumUL = 0; + + foreach (const Sample& s, m_speedSamples) { + sumDL += s.download; + sumUL += s.upload; } - return sum/static_cast(m_speedSamples.size()); + + const qreal numSamples = m_speedSamples.size(); + return Sample(sumDL/numSamples, sumUL/numSamples); } void SpeedSample::clear() @@ -113,10 +126,31 @@ qlonglong TorrentSpeedMonitor::getETA(const QString &hash) const { QMutexLocker locker(&m_mutex); QTorrentHandle h = m_session->getTorrentHandle(hash); - if (h.is_paused() || !m_samples.contains(hash)) return -1; - const qreal speed_average = m_samples.value(hash).average(); - if (speed_average == 0) return -1; - return (h.total_wanted() - h.total_done()) / speed_average; + if (h.is_paused() || !m_samples.contains(hash)) + return MAX_ETA; + + const Sample speed_average = m_samples[hash].average(); + + if (h.is_seed()) { + if (!speed_average.upload) + return MAX_ETA; + + bool _unused; + qreal max_ratio = m_session->getMaxRatioPerTorrent(hash, &_unused); + if (max_ratio < 0) + return MAX_ETA; + + libtorrent::size_type realDL = h.all_time_download(); + if (realDL <= 0) + realDL = h.total_wanted(); + + return (realDL * max_ratio - h.all_time_upload()) / speed_average.upload; + } + + if (!speed_average.download) + return MAX_ETA; + + return (h.total_wanted() - h.total_done()) / speed_average.download; } void TorrentSpeedMonitor::getSamples() @@ -129,12 +163,13 @@ void TorrentSpeedMonitor::getSamples() try { #if LIBTORRENT_VERSION_MINOR > 15 torrent_status st = it->status(0x0); - if (!st.paused) - m_samples[misc::toQString(it->info_hash())].addSample(st.download_payload_rate); + if (!st.paused) { #else - if (!it->is_paused()) - m_samples[misc::toQString(it->info_hash())].addSample(it->status().download_payload_rate); + if (!it->is_paused()) { + torrent_status st = it->status(); #endif + m_samples[misc::toQString(it->info_hash())].addSample(st.download_payload_rate, st.upload_payload_rate); + } } catch(invalid_handle&) {} } }