Rewritten SpeedCalc

pull/43/head
Tatsuhiro Tsujikawa 2013-01-11 23:29:58 +09:00
parent c893d82867
commit 1ad815061b
2 changed files with 58 additions and 64 deletions

View File

@ -41,71 +41,69 @@
namespace aria2 {
#define CHANGE_INTERVAL_SEC 15
#define WINDOW_MSEC 15000
SpeedCalc::SpeedCalc():sw_(0), maxSpeed_(0), prevSpeed_(0),
accumulatedLength_(0),
nextInterval_(CHANGE_INTERVAL_SEC)
SpeedCalc::SpeedCalc()
: accumulatedLength_(0),
bytesWindow_(0),
maxSpeed_(0)
{}
void SpeedCalc::reset()
{
std::fill(&lengthArray_[0], &lengthArray_[2], 0);
}
void SpeedCalc::reset() {
std::fill(&lengthArray_[0], &lengthArray_[2], 0);
std::fill(&cpArray_[0], &cpArray_[2], global::wallclock());
sw_ = 0;
maxSpeed_ = 0;
prevSpeed_ = 0;
timeSlots_.clear();
start_ = global::wallclock();
accumulatedLength_ = 0;
nextInterval_ = CHANGE_INTERVAL_SEC;
bytesWindow_ = 0;
maxSpeed_ = 0;
}
int SpeedCalc::calculateSpeed() {
int64_t milliElapsed = cpArray_[sw_].differenceInMillis(global::wallclock());
if(milliElapsed) {
int speed = lengthArray_[sw_]*1000/milliElapsed;
prevSpeed_ = speed;
maxSpeed_ = std::max(speed, maxSpeed_);
if(isIntervalOver(milliElapsed)) {
changeSw();
}
return speed;
} else {
return prevSpeed_;
}
}
void SpeedCalc::update(size_t bytes) {
accumulatedLength_ += bytes;
std::transform(&lengthArray_[0], &lengthArray_[2], &lengthArray_[0],
std::bind1st(std::plus<int64_t>(), (int64_t)bytes));
if(isIntervalOver()) {
changeSw();
}
}
bool SpeedCalc::isIntervalOver() const {
return nextInterval_ <= cpArray_[sw_].difference(global::wallclock());
}
bool SpeedCalc::isIntervalOver(int64_t milliElapsed) const
void SpeedCalc::removeStaleTimeSlot(int64_t now)
{
return nextInterval_ <= milliElapsed/1000;
while(!timeSlots_.empty()) {
if(now - timeSlots_[0].first <= WINDOW_MSEC) {
break;
} else {
bytesWindow_ -= timeSlots_[0].second;
timeSlots_.pop_front();
}
}
}
void SpeedCalc::changeSw() {
lengthArray_[sw_] = 0;
cpArray_[sw_] = global::wallclock();
sw_ ^= 0x01u;
nextInterval_ =
cpArray_[sw_].difference(global::wallclock())+CHANGE_INTERVAL_SEC;
int SpeedCalc::calculateSpeed()
{
int64_t now = global::wallclock().getTimeInMillis();
removeStaleTimeSlot(now);
if(timeSlots_.empty()) {
return 0;
}
int64_t elapsed = now - timeSlots_[0].first;
if(elapsed <= 0) {
elapsed = 1;
}
int speed = bytesWindow_*1000/elapsed;
maxSpeed_ = std::max(speed, maxSpeed_);
return speed;
}
int SpeedCalc::calculateAvgSpeed() const {
void SpeedCalc::update(size_t bytes)
{
int64_t now = global::wallclock().getTimeInMillis();
removeStaleTimeSlot(now);
if(timeSlots_.empty() || now/1000 != timeSlots_.back().first/1000) {
timeSlots_.push_back(std::make_pair(now, bytes));
} else {
timeSlots_.back().second += bytes;
}
bytesWindow_ += bytes;
accumulatedLength_ += bytes;
}
int SpeedCalc::calculateAvgSpeed() const
{
int64_t milliElapsed = start_.differenceInMillis(global::wallclock());
// if milliElapsed is too small, the average speed is rubish, better return 0
// if milliElapsed is too small, the average speed is rubish, better
// return 0
if(milliElapsed > 4) {
int speed = accumulatedLength_*1000/milliElapsed;
return speed;

View File

@ -36,29 +36,25 @@
#define D_SPEED_CALC_H
#include "common.h"
#include <deque>
#include "TimerA2.h"
namespace aria2 {
class SpeedCalc {
private:
int64_t lengthArray_[2];
int sw_;
Timer cpArray_[2];
int maxSpeed_;
int prevSpeed_;
std::deque<std::pair<int64_t, size_t> > timeSlots_;
Timer start_;
int64_t accumulatedLength_;
time_t nextInterval_;
int64_t bytesWindow_;
int maxSpeed_;
bool isIntervalOver(int64_t milliElapsed) const;
void changeSw();
void removeStaleTimeSlot(int64_t now);
public:
SpeedCalc();
bool isIntervalOver() const;
/**
* Returns download/upload speed in byte per sec
*/