|
|
|
@ -38,19 +38,25 @@
@@ -38,19 +38,25 @@
|
|
|
|
|
|
|
|
|
|
using namespace libtorrent; |
|
|
|
|
|
|
|
|
|
template<class T> 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<qreal> average() const; |
|
|
|
|
void clear(); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
static const int max_samples = 30; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
QList<int> m_speedSamples; |
|
|
|
|
QList<Sample<int> > m_speedSamples; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session) : |
|
|
|
@ -76,21 +82,28 @@ void TorrentSpeedMonitor::run()
@@ -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<int>(speedDL, speedUL); |
|
|
|
|
if (m_speedSamples.size() > max_samples) |
|
|
|
|
m_speedSamples.removeFirst(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
qreal SpeedSample::average() const |
|
|
|
|
Sample<qreal> 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<qreal>(); |
|
|
|
|
|
|
|
|
|
qlonglong sumDL = 0; |
|
|
|
|
qlonglong sumUL = 0; |
|
|
|
|
|
|
|
|
|
foreach (const Sample<int>& s, m_speedSamples) { |
|
|
|
|
sumDL += s.download; |
|
|
|
|
sumUL += s.upload; |
|
|
|
|
} |
|
|
|
|
return sum/static_cast<float>(m_speedSamples.size()); |
|
|
|
|
|
|
|
|
|
const qreal numSamples = m_speedSamples.size(); |
|
|
|
|
return Sample<qreal>(sumDL/numSamples, sumUL/numSamples); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SpeedSample::clear() |
|
|
|
@ -113,10 +126,31 @@ qlonglong TorrentSpeedMonitor::getETA(const QString &hash) const
@@ -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<qreal> 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()
@@ -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&) {} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|