mirror of https://github.com/aria2/aria2
Made HTTP/FTP download speed limiter more accurate
We have to do the same thing for BitTorrent.pull/31/head
parent
ea456001d3
commit
46bdaf0e8d
|
@ -177,7 +177,6 @@ bool DownloadCommand::executeInternal() {
|
||||||
getSocketRecvBuffer()->shiftBuffer(bufSize);
|
getSocketRecvBuffer()->shiftBuffer(bufSize);
|
||||||
peerStat_->updateDownloadLength(bufSize);
|
peerStat_->updateDownloadLength(bufSize);
|
||||||
}
|
}
|
||||||
getSegmentMan()->updateDownloadSpeedFor(peerStat_);
|
|
||||||
bool segmentPartComplete = false;
|
bool segmentPartComplete = false;
|
||||||
// Note that GrowSegment::complete() always returns false.
|
// Note that GrowSegment::complete() always returns false.
|
||||||
if(sinkFilterOnly_) {
|
if(sinkFilterOnly_) {
|
||||||
|
|
|
@ -130,4 +130,9 @@ void PeerStat::downloadStop()
|
||||||
status_ = PeerStat::IDLE;
|
status_ = PeerStat::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PeerStat::affectsOverallSpeed() const
|
||||||
|
{
|
||||||
|
return !downloadSpeed_.isIntervalOver();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -149,6 +149,10 @@ public:
|
||||||
{
|
{
|
||||||
sessionDownloadLength_ += length;
|
sessionDownloadLength_ += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if the download speed of this object still affects
|
||||||
|
// overall download speed statistics.
|
||||||
|
bool affectsOverallSpeed() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -69,8 +69,6 @@ SegmentMan::SegmentMan
|
||||||
: option_(option),
|
: option_(option),
|
||||||
downloadContext_(downloadContext),
|
downloadContext_(downloadContext),
|
||||||
pieceStorage_(pieceStorage),
|
pieceStorage_(pieceStorage),
|
||||||
lastPeerStatDlspdMapUpdated_(0),
|
|
||||||
cachedDlspd_(0),
|
|
||||||
ignoreBitfield_(downloadContext->getPieceLength(),
|
ignoreBitfield_(downloadContext->getPieceLength(),
|
||||||
downloadContext->getTotalLength())
|
downloadContext->getTotalLength())
|
||||||
{
|
{
|
||||||
|
@ -350,13 +348,6 @@ int64_t SegmentMan::getDownloadLength() const {
|
||||||
|
|
||||||
void SegmentMan::registerPeerStat(const SharedHandle<PeerStat>& peerStat)
|
void SegmentMan::registerPeerStat(const SharedHandle<PeerStat>& peerStat)
|
||||||
{
|
{
|
||||||
for(std::vector<SharedHandle<PeerStat> >::iterator i = peerStats_.begin(),
|
|
||||||
eoi = peerStats_.end(); i != eoi; ++i) {
|
|
||||||
if((*i)->getStatus() == PeerStat::IDLE) {
|
|
||||||
*i = peerStat;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
peerStats_.push_back(peerStat);
|
peerStats_.push_back(peerStat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,38 +398,17 @@ void SegmentMan::updateFastestPeerStat(const SharedHandle<PeerStat>& peerStat)
|
||||||
int SegmentMan::calculateDownloadSpeed()
|
int SegmentMan::calculateDownloadSpeed()
|
||||||
{
|
{
|
||||||
int speed = 0;
|
int speed = 0;
|
||||||
if(lastPeerStatDlspdMapUpdated_.differenceInMillis(global::wallclock())+
|
for(std::vector<SharedHandle<PeerStat> >::const_iterator i =
|
||||||
A2_DELTA_MILLIS >= 250){
|
peerStats_.begin(), eoi = peerStats_.end(); i != eoi; ++i) {
|
||||||
lastPeerStatDlspdMapUpdated_ = global::wallclock();
|
// PeerStat which is IDLE but its last download speed calculation
|
||||||
peerStatDlspdMap_.clear();
|
// interval is not over must be added to the result.
|
||||||
for(std::vector<SharedHandle<PeerStat> >::const_iterator i =
|
if((*i)->getStatus() == PeerStat::ACTIVE || (*i)->affectsOverallSpeed()) {
|
||||||
peerStats_.begin(), eoi = peerStats_.end(); i != eoi; ++i) {
|
speed += (*i)->calculateDownloadSpeed();
|
||||||
if((*i)->getStatus() == PeerStat::ACTIVE) {
|
|
||||||
int s = (*i)->calculateDownloadSpeed();
|
|
||||||
peerStatDlspdMap_[(*i)->getCuid()] = s;
|
|
||||||
speed += s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cachedDlspd_ = speed;
|
|
||||||
} else {
|
|
||||||
speed = cachedDlspd_;
|
|
||||||
}
|
}
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SegmentMan::updateDownloadSpeedFor(const SharedHandle<PeerStat>& pstat)
|
|
||||||
{
|
|
||||||
int newspd = pstat->calculateDownloadSpeed();
|
|
||||||
int oldSpd = peerStatDlspdMap_[pstat->getCuid()];
|
|
||||||
if(cachedDlspd_ > oldSpd) {
|
|
||||||
cachedDlspd_ -= oldSpd;
|
|
||||||
cachedDlspd_ += newspd;
|
|
||||||
} else {
|
|
||||||
cachedDlspd_ = newspd;
|
|
||||||
}
|
|
||||||
peerStatDlspdMap_[pstat->getCuid()] = newspd;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class PeerStatDownloadLengthOperator {
|
class PeerStatDownloadLengthOperator {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -93,13 +93,6 @@ private:
|
||||||
// Keep track of fastest PeerStat for each server
|
// Keep track of fastest PeerStat for each server
|
||||||
std::vector<SharedHandle<PeerStat> > fastestPeerStats_;
|
std::vector<SharedHandle<PeerStat> > fastestPeerStats_;
|
||||||
|
|
||||||
// key: PeerStat's cuid, value: its download speed
|
|
||||||
std::map<cuid_t, int> peerStatDlspdMap_;
|
|
||||||
|
|
||||||
Timer lastPeerStatDlspdMapUpdated_;
|
|
||||||
|
|
||||||
int cachedDlspd_;
|
|
||||||
|
|
||||||
BitfieldMan ignoreBitfield_;
|
BitfieldMan ignoreBitfield_;
|
||||||
|
|
||||||
SharedHandle<Segment> checkoutSegment(cuid_t cuid,
|
SharedHandle<Segment> checkoutSegment(cuid_t cuid,
|
||||||
|
@ -232,8 +225,6 @@ public:
|
||||||
*/
|
*/
|
||||||
int calculateDownloadSpeed();
|
int calculateDownloadSpeed();
|
||||||
|
|
||||||
void updateDownloadSpeedFor(const SharedHandle<PeerStat>& pstat);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the downloaded bytes in this session.
|
* Returns the downloaded bytes in this session.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -51,14 +51,14 @@ private:
|
||||||
int64_t accumulatedLength_;
|
int64_t accumulatedLength_;
|
||||||
time_t nextInterval_;
|
time_t nextInterval_;
|
||||||
|
|
||||||
bool isIntervalOver() const;
|
|
||||||
|
|
||||||
bool isIntervalOver(int64_t milliElapsed) const;
|
bool isIntervalOver(int64_t milliElapsed) const;
|
||||||
|
|
||||||
void changeSw();
|
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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -157,9 +157,6 @@ void SegmentManTest::testRegisterPeerStat()
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, segman.getPeerStats().size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, segman.getPeerStats().size());
|
||||||
SharedHandle<PeerStat> p2(new PeerStat(0, "host2", "http"));
|
SharedHandle<PeerStat> p2(new PeerStat(0, "host2", "http"));
|
||||||
segman.registerPeerStat(p2);
|
segman.registerPeerStat(p2);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, segman.getPeerStats().size());
|
|
||||||
p2->downloadStart();
|
|
||||||
segman.registerPeerStat(p1);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, segman.getPeerStats().size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, segman.getPeerStats().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue