From 51c9d358b4bde9eb1ecb3b75e4d67a12ac277ea8 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sun, 2 Nov 2014 19:29:14 +0300 Subject: [PATCH] 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); }