From 0d311062f34d6f9a29e256d8154f1a2d00e9a2f8 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sun, 2 Nov 2014 18:20:28 +0300 Subject: [PATCH 1/3] Unused function --- src/qtlibtorrent/torrentspeedmonitor.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/qtlibtorrent/torrentspeedmonitor.cpp b/src/qtlibtorrent/torrentspeedmonitor.cpp index f898e4acc..6eed6642e 100644 --- a/src/qtlibtorrent/torrentspeedmonitor.cpp +++ b/src/qtlibtorrent/torrentspeedmonitor.cpp @@ -48,7 +48,6 @@ public: SpeedSample() {} void addSample(int speedDL, int speedUL); Sample average() const; - void clear(); private: static const int max_samples = 30; @@ -92,11 +91,6 @@ Sample SpeedSample::average() const return Sample(sumDL/numSamples, sumUL/numSamples); } -void SpeedSample::clear() -{ - m_speedSamples.clear(); -} - void TorrentSpeedMonitor::removeSamples(const QString &hash) { m_samples.remove(hash); From 4ff08ff6919578ebd58777e1fb5e1a290e129e1e Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sun, 2 Nov 2014 19:27:46 +0300 Subject: [PATCH 2/3] New improved Sample in TorrentSpeedMonitor --- src/qtlibtorrent/torrentspeedmonitor.cpp | 76 ++++++++++++++++++++---- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/src/qtlibtorrent/torrentspeedmonitor.cpp b/src/qtlibtorrent/torrentspeedmonitor.cpp index 6eed6642e..87d63a2f6 100644 --- a/src/qtlibtorrent/torrentspeedmonitor.cpp +++ b/src/qtlibtorrent/torrentspeedmonitor.cpp @@ -36,11 +36,68 @@ using namespace libtorrent; -template struct Sample { - Sample(const T down = 0, const T up = 0) : download(down), upload(up) {} - T download; - T upload; -}; +namespace { + + template struct Sample { + Sample() + : download() + , upload() + {} + + Sample(T download, T upload) + : download(download) + , upload(upload) + {} + + template + explicit Sample(Sample other) + : download(static_cast(other.download)) + , upload(static_cast(other.upload)) + {} + + T download; + T upload; + }; + + template + Sample& operator+=(Sample& lhs, Sample const& rhs) { + lhs.download += rhs.download; + lhs.upload += rhs.upload; + return lhs; + } + + template + Sample& operator-=(Sample& lhs, Sample const& rhs) { + lhs.download -= rhs.download; + lhs.upload -= rhs.upload; + return lhs; + } + + template + Sample operator+(Sample const& lhs, Sample const& rhs) { + return Sample(lhs.download + rhs.download, lhs.upload + rhs.upload); + } + + template + Sample operator-(Sample const& lhs, Sample const& rhs) { + return Sample(lhs.download - rhs.download, lhs.upload - rhs.upload); + } + + template + Sample operator*(Sample const& lhs, T rhs) { + return Sample(lhs.download * rhs, lhs.upload * rhs); + } + + template + Sample operator*(T lhs,Sample const& rhs) { + return Sample(lhs * rhs.download, lhs * rhs.upload); + } + + template + Sample operator/(Sample const& lhs, T rhs) { + return Sample(lhs.download / rhs, lhs.upload / rhs); + } +} class SpeedSample { @@ -79,16 +136,13 @@ Sample SpeedSample::average() const if (m_speedSamples.empty()) return Sample(); - qlonglong sumDL = 0; - qlonglong sumUL = 0; + Sample sum; foreach (const Sample& s, m_speedSamples) { - sumDL += s.download; - sumUL += s.upload; + sum += Sample(s); } - const qreal numSamples = m_speedSamples.size(); - return Sample(sumDL/numSamples, sumUL/numSamples); + return Sample(sum) * (1. / m_speedSamples.size()); } void TorrentSpeedMonitor::removeSamples(const QString &hash) From 51c9d358b4bde9eb1ecb3b75e4d67a12ac277ea8 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sun, 2 Nov 2014 19:29:14 +0300 Subject: [PATCH 3/3] Implement O(1) SpeedSample::average() instead of O(N) --- src/qtlibtorrent/torrentspeedmonitor.cpp | 38 +++++++++++++----------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/qtlibtorrent/torrentspeedmonitor.cpp b/src/qtlibtorrent/torrentspeedmonitor.cpp index 87d63a2f6..5cdb62d30 100644 --- a/src/qtlibtorrent/torrentspeedmonitor.cpp +++ b/src/qtlibtorrent/torrentspeedmonitor.cpp @@ -103,7 +103,7 @@ class SpeedSample { public: SpeedSample() {} - void addSample(int speedDL, int speedUL); + void addSample(Sample const& item); Sample average() const; private: @@ -111,6 +111,7 @@ private: private: QList > m_speedSamples; + Sample m_sum; }; TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session) @@ -124,11 +125,14 @@ TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session) TorrentSpeedMonitor::~TorrentSpeedMonitor() {} -void SpeedSample::addSample(int speedDL, int speedUL) +void SpeedSample::addSample(Sample const& item) { - m_speedSamples << Sample(speedDL, speedUL); - if (m_speedSamples.size() > max_samples) - m_speedSamples.removeFirst(); + m_speedSamples.push_back(item); + m_sum += Sample(item); + if (m_speedSamples.size() > max_samples) { + m_sum -= Sample(m_speedSamples.front()); + m_speedSamples.pop_front(); + } } Sample SpeedSample::average() const @@ -136,13 +140,7 @@ Sample SpeedSample::average() const if (m_speedSamples.empty()) return Sample(); - Sample sum; - - foreach (const Sample& s, m_speedSamples) { - sum += Sample(s); - } - - return Sample(sum) * (1. / m_speedSamples.size()); + return Sample(m_sum) * (1. / m_speedSamples.size()); } void TorrentSpeedMonitor::removeSamples(const QString &hash) @@ -158,10 +156,14 @@ void TorrentSpeedMonitor::removeSamples(const QTorrentHandle& h) { qlonglong TorrentSpeedMonitor::getETA(const QString &hash, const libtorrent::torrent_status &status) const { - if (QTorrentHandle::is_paused(status) || !m_samples.contains(hash)) + if (QTorrentHandle::is_paused(status)) return MAX_ETA; - const Sample speed_average = m_samples[hash].average(); + QHash::const_iterator i = m_samples.find(hash); + if (i == m_samples.end()) + return MAX_ETA; + + const Sample speed_average = i->average(); if (QTorrentHandle::is_seed(status)) { if (!speed_average.upload) @@ -189,8 +191,10 @@ void TorrentSpeedMonitor::statsReceived(const stats_alert &stats) { Q_ASSERT(stats.interval >= 1000); - int speedDL = static_cast(static_cast(stats.transferred[stats_alert::download_payload]) * 1000 / stats.interval); - int speedUL = static_cast(static_cast(stats.transferred[stats_alert::upload_payload]) * 1000 / stats.interval); + Sample transferred(stats.transferred[stats_alert::download_payload], + stats.transferred[stats_alert::upload_payload]); + + Sample normalized = Sample(Sample(transferred) * 1000LL / static_cast(stats.interval)); - m_samples[misc::toQString(stats.handle.info_hash())].addSample(speedDL, speedUL); + m_samples[misc::toQString(stats.handle.info_hash())].addSample(normalized); }