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 {
|
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;
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue