mirror of https://github.com/aria2/aria2
2009-03-19 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Reduced the number of calls to PeerStorage::calculateStat() and SegmentMan::calculateDownloadSpeed() to lower CPU usage on higher transfer rate. * src/DefaultBtInteractive.cc * src/DefaultBtMessageDispatcher.cc * src/DefaultPeerStorage.cc * src/DefaultPeerStorage.h * src/DownloadCommand.cc * src/DownloadEngine.cc * src/PeerStorage.h * src/SegmentMan.cc * src/SegmentMan.h * test/MockPeerStorage.hpull/1/head
parent
75a525b031
commit
e3ed6adf91
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2009-03-19 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Reduced the number of calls to PeerStorage::calculateStat() and
|
||||
SegmentMan::calculateDownloadSpeed() to lower CPU usage on higher
|
||||
transfer rate.
|
||||
* src/DefaultBtInteractive.cc
|
||||
* src/DefaultBtMessageDispatcher.cc
|
||||
* src/DefaultPeerStorage.cc
|
||||
* src/DefaultPeerStorage.h
|
||||
* src/DownloadCommand.cc
|
||||
* src/DownloadEngine.cc
|
||||
* src/PeerStorage.h
|
||||
* src/SegmentMan.cc
|
||||
* src/SegmentMan.h
|
||||
* test/MockPeerStorage.h
|
||||
|
||||
2009-03-13 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Prepended _dir+"/" after joining path elements in torrent file.
|
||||
|
|
|
@ -265,8 +265,10 @@ size_t DefaultBtInteractive::receiveMessages() {
|
|||
floodingStat.incChokeUnchokeCount();
|
||||
}
|
||||
break;
|
||||
case BtRequestMessage::ID:
|
||||
case BtPieceMessage::ID:
|
||||
_peerStorage->updateTransferStatFor(peer);
|
||||
// pass through
|
||||
case BtRequestMessage::ID:
|
||||
inactiveCheckPoint.reset();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,9 @@ void DefaultBtMessageDispatcher::sendMessages() {
|
|||
}
|
||||
}
|
||||
msg->send();
|
||||
if(msg->isUploading()) {
|
||||
_peerStorage->updateTransferStatFor(peer);
|
||||
}
|
||||
if(msg->isSendingInProgress()) {
|
||||
messageQueue.push_front(msg);
|
||||
break;
|
||||
|
|
|
@ -59,7 +59,8 @@ DefaultPeerStorage::DefaultPeerStorage(const BtContextHandle& btContext,
|
|||
removedPeerSessionDownloadLength(0),
|
||||
removedPeerSessionUploadLength(0),
|
||||
_seederStateChoke(new BtSeederStateChoke()),
|
||||
_leecherStateChoke(new BtLeecherStateChoke())
|
||||
_leecherStateChoke(new BtLeecherStateChoke()),
|
||||
_lastTransferStatMapUpdated(0)
|
||||
{}
|
||||
|
||||
DefaultPeerStorage::~DefaultPeerStorage()
|
||||
|
@ -191,31 +192,46 @@ void DefaultPeerStorage::getActivePeers(std::deque<SharedHandle<Peer> >& activeP
|
|||
std::for_each(peers.begin(), peers.end(), CollectActivePeer(activePeers));
|
||||
}
|
||||
|
||||
class CalculateStat {
|
||||
private:
|
||||
TransferStat _stat;
|
||||
struct timeval _now;
|
||||
public:
|
||||
CalculateStat()
|
||||
{
|
||||
gettimeofday(&_now, 0);
|
||||
}
|
||||
static TransferStat caluclateStatFor(const SharedHandle<Peer>& peer)
|
||||
{
|
||||
struct timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
TransferStat s;
|
||||
s.downloadSpeed = peer->calculateDownloadSpeed(now);
|
||||
s.uploadSpeed = peer->calculateUploadSpeed(now);
|
||||
s.sessionDownloadLength = peer->getSessionDownloadLength();
|
||||
s.sessionUploadLength = peer->getSessionUploadLength();
|
||||
return s;
|
||||
}
|
||||
|
||||
void operator()(const PeerHandle& peer)
|
||||
{
|
||||
if(peer->isActive()) {
|
||||
_stat.downloadSpeed += peer->calculateDownloadSpeed(_now);
|
||||
_stat.uploadSpeed += peer->calculateUploadSpeed(_now);
|
||||
_stat.sessionDownloadLength += peer->getSessionDownloadLength();
|
||||
_stat.sessionUploadLength += peer->getSessionUploadLength();
|
||||
TransferStat DefaultPeerStorage::calculateStat()
|
||||
{
|
||||
TransferStat stat;
|
||||
if(_lastTransferStatMapUpdated.elapsedInMillis(250)) {
|
||||
logger->debug("Updating TransferStat of PeerStorage");
|
||||
_lastTransferStatMapUpdated.reset();
|
||||
_peerTransferStatMap.clear();
|
||||
std::deque<SharedHandle<Peer> > activePeers;
|
||||
getActivePeers(activePeers);
|
||||
struct timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
for(std::deque<SharedHandle<Peer> >::const_iterator i = activePeers.begin();
|
||||
i != activePeers.end(); ++i) {
|
||||
TransferStat s;
|
||||
s.downloadSpeed = (*i)->calculateDownloadSpeed(now);
|
||||
s.uploadSpeed = (*i)->calculateUploadSpeed(now);
|
||||
s.sessionDownloadLength = (*i)->getSessionDownloadLength();
|
||||
s.sessionUploadLength = (*i)->getSessionUploadLength();
|
||||
|
||||
_peerTransferStatMap[(*i)->getID()] = caluclateStatFor(*i);
|
||||
stat = stat+s;
|
||||
}
|
||||
} else {
|
||||
for(std::map<std::string, TransferStat>::const_iterator i =
|
||||
_peerTransferStatMap.begin(); i != _peerTransferStatMap.end(); ++i) {
|
||||
stat = stat+(*i).second;
|
||||
}
|
||||
}
|
||||
|
||||
const TransferStat& getTransferStat() { return _stat; }
|
||||
};
|
||||
|
||||
TransferStat DefaultPeerStorage::calculateStat() {
|
||||
TransferStat stat = std::for_each(peers.begin(), peers.end(), CalculateStat()).getTransferStat();
|
||||
stat.sessionDownloadLength += removedPeerSessionDownloadLength;
|
||||
stat.sessionUploadLength += removedPeerSessionUploadLength;
|
||||
stat.setAllTimeUploadLength(_btRuntime->getUploadLengthAtStartup()+
|
||||
|
@ -223,6 +239,12 @@ TransferStat DefaultPeerStorage::calculateStat() {
|
|||
return stat;
|
||||
}
|
||||
|
||||
void DefaultPeerStorage::updateTransferStatFor(const SharedHandle<Peer>& peer)
|
||||
{
|
||||
logger->debug("Updating TransferStat for peer %s", peer->getID().c_str());
|
||||
_peerTransferStatMap[peer->getID()] = caluclateStatFor(peer);
|
||||
}
|
||||
|
||||
void DefaultPeerStorage::deleteUnusedPeer(size_t delSize) {
|
||||
Peers temp;
|
||||
for(Peers::reverse_iterator itr = peers.rbegin();
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
|
||||
#include "PeerStorage.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "TimeA2.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class BtContext;
|
||||
|
@ -61,6 +65,10 @@ private:
|
|||
BtSeederStateChoke* _seederStateChoke;
|
||||
BtLeecherStateChoke* _leecherStateChoke;
|
||||
|
||||
std::map<std::string, TransferStat> _peerTransferStatMap;
|
||||
|
||||
Time _lastTransferStatMapUpdated;
|
||||
|
||||
bool isPeerAlreadyAdded(const SharedHandle<Peer>& peer);
|
||||
public:
|
||||
DefaultPeerStorage(const SharedHandle<BtContext>& btContext,
|
||||
|
@ -86,6 +94,8 @@ public:
|
|||
|
||||
virtual TransferStat calculateStat();
|
||||
|
||||
virtual void updateTransferStatFor(const SharedHandle<Peer>& peer);
|
||||
|
||||
virtual void returnPeer(const SharedHandle<Peer>& peer);
|
||||
|
||||
virtual bool chokeRoundIntervalElapsed();
|
||||
|
|
|
@ -161,6 +161,8 @@ bool DownloadCommand::executeInternal() {
|
|||
|
||||
peerStat->updateDownloadLength(bufSize);
|
||||
|
||||
_requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
|
||||
|
||||
if(_requestGroup->getTotalLength() != 0 && bufSize == 0 &&
|
||||
!socket->wantRead() && !socket->wantWrite()) {
|
||||
throw DlRetryEx(EX_GOT_EOF);
|
||||
|
|
|
@ -204,6 +204,7 @@ void DownloadEngine::onEndOfRun()
|
|||
|
||||
void DownloadEngine::afterEachIteration()
|
||||
{
|
||||
_requestGroupMan->calculateStat();
|
||||
if(globalHaltRequested == 1) {
|
||||
logger->notice(_("Shutdown sequence commencing... Press Ctrl-C again for emergency shutdown."));
|
||||
requestHalt();
|
||||
|
|
|
@ -85,6 +85,8 @@ public:
|
|||
*/
|
||||
virtual TransferStat calculateStat() = 0;
|
||||
|
||||
virtual void updateTransferStatFor(const SharedHandle<Peer>& peer) = 0;
|
||||
|
||||
/**
|
||||
* Tells PeerStorage object that peer is no longer used in the session.
|
||||
*/
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
*/
|
||||
/* copyright --> */
|
||||
#include "SegmentMan.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#include "Util.h"
|
||||
#include "message.h"
|
||||
#include "prefs.h"
|
||||
|
@ -45,9 +50,6 @@
|
|||
#include "Option.h"
|
||||
#include "DownloadContext.h"
|
||||
#include "Piece.h"
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <cassert>
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -62,7 +64,8 @@ SegmentMan::SegmentMan(const Option* option,
|
|||
_option(option),
|
||||
logger(LogFactory::getInstance()),
|
||||
_downloadContext(downloadContext),
|
||||
_pieceStorage(pieceStorage)
|
||||
_pieceStorage(pieceStorage),
|
||||
_lastPeerStatDlspdMapUpdated(0)
|
||||
{}
|
||||
|
||||
SegmentMan::~SegmentMan() {}
|
||||
|
@ -296,17 +299,35 @@ const std::deque<SharedHandle<PeerStat> >& SegmentMan::getPeerStats() const
|
|||
return peerStats;
|
||||
}
|
||||
|
||||
unsigned int SegmentMan::calculateDownloadSpeed() const {
|
||||
unsigned int SegmentMan::calculateDownloadSpeed()
|
||||
{
|
||||
unsigned int speed = 0;
|
||||
for(std::deque<SharedHandle<PeerStat> >::const_iterator itr = peerStats.begin(); itr != peerStats.end(); itr++) {
|
||||
const PeerStatHandle& peerStat = *itr;
|
||||
if(peerStat->getStatus() == PeerStat::ACTIVE) {
|
||||
speed += peerStat->calculateDownloadSpeed();
|
||||
if(_lastPeerStatDlspdMapUpdated.elapsedInMillis(250)) {
|
||||
_lastPeerStatDlspdMapUpdated.reset();
|
||||
_peerStatDlspdMap.clear();
|
||||
for(std::deque<SharedHandle<PeerStat> >::const_iterator i =
|
||||
peerStats.begin(); i != peerStats.end(); ++i) {
|
||||
if((*i)->getStatus() == PeerStat::ACTIVE) {
|
||||
unsigned int s = (*i)->calculateDownloadSpeed();
|
||||
_peerStatDlspdMap[(*i)->getCuid()] = s;
|
||||
speed += s;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(std::map<int32_t, unsigned int>::const_iterator i =
|
||||
_peerStatDlspdMap.begin();
|
||||
i != _peerStatDlspdMap.end(); ++i) {
|
||||
speed += (*i).second;
|
||||
}
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
void SegmentMan::updateDownloadSpeedFor(const SharedHandle<PeerStat>& pstat)
|
||||
{
|
||||
_peerStatDlspdMap[pstat->getCuid()] = pstat->calculateDownloadSpeed();
|
||||
}
|
||||
|
||||
class PeerStatDownloadLengthOperator {
|
||||
public:
|
||||
uint64_t operator()(uint64_t total, const SharedHandle<PeerStat>& ps)
|
||||
|
|
|
@ -36,8 +36,13 @@
|
|||
#define _D_SEGMENT_MAN_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "SharedHandle.h"
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
#include "SharedHandle.h"
|
||||
#include "TimeA2.h"
|
||||
#include "Command.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -79,6 +84,11 @@ private:
|
|||
|
||||
std::deque<SharedHandle<PeerStat> > peerStats;
|
||||
|
||||
// key: PeerStat's cuid, value: its download speed
|
||||
std::map<int32_t, unsigned int> _peerStatDlspdMap;
|
||||
|
||||
Time _lastPeerStatDlspdMapUpdated;
|
||||
|
||||
SharedHandle<Segment> checkoutSegment(int32_t cuid,
|
||||
const SharedHandle<Piece>& piece);
|
||||
|
||||
|
@ -177,7 +187,9 @@ public:
|
|||
/**
|
||||
* Returns current download speed in bytes per sec.
|
||||
*/
|
||||
unsigned int calculateDownloadSpeed() const;
|
||||
unsigned int calculateDownloadSpeed();
|
||||
|
||||
void updateDownloadSpeedFor(const SharedHandle<PeerStat>& pstat);
|
||||
|
||||
/**
|
||||
* Returns the downloaded bytes in this session.
|
||||
|
|
|
@ -71,6 +71,8 @@ public:
|
|||
++_numChokeExecuted;
|
||||
}
|
||||
|
||||
virtual void updateTransferStatFor(const SharedHandle<Peer>& peer) {}
|
||||
|
||||
int getNumChokeExecuted() const
|
||||
{
|
||||
return _numChokeExecuted;
|
||||
|
|
Loading…
Reference in New Issue