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 { namespace aria2 {
#define CHANGE_INTERVAL_SEC 15 #define WINDOW_MSEC 15000
SpeedCalc::SpeedCalc():sw_(0), maxSpeed_(0), prevSpeed_(0), SpeedCalc::SpeedCalc()
accumulatedLength_(0), : accumulatedLength_(0),
nextInterval_(CHANGE_INTERVAL_SEC) bytesWindow_(0),
maxSpeed_(0)
{}
void SpeedCalc::reset()
{ {
std::fill(&lengthArray_[0], &lengthArray_[2], 0); timeSlots_.clear();
}
void SpeedCalc::reset() {
std::fill(&lengthArray_[0], &lengthArray_[2], 0);
std::fill(&cpArray_[0], &cpArray_[2], global::wallclock());
sw_ = 0;
maxSpeed_ = 0;
prevSpeed_ = 0;
start_ = global::wallclock(); start_ = global::wallclock();
accumulatedLength_ = 0; accumulatedLength_ = 0;
nextInterval_ = CHANGE_INTERVAL_SEC; bytesWindow_ = 0;
maxSpeed_ = 0;
} }
int SpeedCalc::calculateSpeed() { void SpeedCalc::removeStaleTimeSlot(int64_t now)
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
{ {
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() { int SpeedCalc::calculateSpeed()
lengthArray_[sw_] = 0; {
cpArray_[sw_] = global::wallclock(); int64_t now = global::wallclock().getTimeInMillis();
sw_ ^= 0x01u; removeStaleTimeSlot(now);
nextInterval_ = if(timeSlots_.empty()) {
cpArray_[sw_].difference(global::wallclock())+CHANGE_INTERVAL_SEC; 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()); int64_t milliElapsed = start_.differenceInMillis(global::wallclock());
// if milliElapsed is too small, the average speed is rubish, better
// if milliElapsed is too small, the average speed is rubish, better return 0 // return 0
if(milliElapsed > 4) { if(milliElapsed > 4) {
int speed = accumulatedLength_*1000/milliElapsed; int speed = accumulatedLength_*1000/milliElapsed;
return speed; return speed;

View File

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