mirror of https://github.com/aria2/aria2
Rewritten SpeedCalc
parent
c893d82867
commit
1ad815061b
104
src/SpeedCalc.cc
104
src/SpeedCalc.cc
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue