mirror of https://github.com/aria2/aria2
2008-07-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Now SegmentMan::findSlowerSegmentEntry() picks up the segment for which the transfer has not yet started. Rewritten SegmentMan::registerPeerStat() and SegmentMan::getPeerStat(). * src/SegmentMan.cc * src/SegmentMan.h * test/SegmentManTest.ccpull/1/head
parent
52979168f3
commit
ec395b6a9c
|
@ -1,3 +1,12 @@
|
|||
2008-07-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Now SegmentMan::findSlowerSegmentEntry() picks up the segment for which
|
||||
the transfer has not yet started.
|
||||
Rewritten SegmentMan::registerPeerStat() and SegmentMan::getPeerStat().
|
||||
* src/SegmentMan.cc
|
||||
* src/SegmentMan.h
|
||||
* test/SegmentManTest.cc
|
||||
|
||||
2008-07-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Cache last calculated average download/upload speed.
|
||||
|
|
|
@ -123,25 +123,36 @@ SegmentHandle SegmentMan::checkoutSegment(int32_t cuid,
|
|||
return segment;
|
||||
}
|
||||
|
||||
SegmentEntryHandle SegmentMan::findSlowerSegmentEntry(const PeerStatHandle& peerStat) const {
|
||||
SegmentEntryHandle SegmentMan::findSlowerSegmentEntry
|
||||
(const PeerStatHandle& peerStat)
|
||||
{
|
||||
unsigned int speed = peerStat->getAvgDownloadSpeed()*0.8;
|
||||
SegmentEntryHandle slowSegmentEntry;
|
||||
for(SegmentEntries::const_iterator itr = usedSegmentEntries.begin();
|
||||
itr != usedSegmentEntries.end(); ++itr) {
|
||||
const SegmentEntryHandle& segmentEntry = *itr;
|
||||
int startupIdleTime = _option->getAsInt(PREF_STARTUP_IDLE_TIME);
|
||||
for(std::deque<SharedHandle<SegmentEntry> >::const_iterator itr =
|
||||
usedSegmentEntries.begin(); itr != usedSegmentEntries.end(); ++itr) {
|
||||
const SharedHandle<SegmentEntry>& segmentEntry = *itr;
|
||||
if(segmentEntry->cuid == 0) {
|
||||
continue;
|
||||
}
|
||||
PeerStatHandle p = getPeerStat(segmentEntry->cuid);
|
||||
if(!p.get() || p->getCuid() == peerStat->getCuid() ||
|
||||
p->getStatus() != PeerStat::ACTIVE ||
|
||||
!p->getDownloadStartTime().elapsed(_option->getAsInt(PREF_STARTUP_IDLE_TIME))) {
|
||||
continue;
|
||||
}
|
||||
unsigned int pSpeed = p->calculateDownloadSpeed();
|
||||
if(pSpeed < speed) {
|
||||
speed = pSpeed;
|
||||
SharedHandle<PeerStat> p = getPeerStat(segmentEntry->cuid);
|
||||
if(p.isNull()) {
|
||||
// "p is null" means that it hasn't used DownloadCommand yet, i.e. waiting
|
||||
// response from HTTP server after sending HTTP request.
|
||||
p.reset(new PeerStat(segmentEntry->cuid));
|
||||
registerPeerStat(p);
|
||||
slowSegmentEntry = segmentEntry;
|
||||
} else {
|
||||
if(p->getCuid() == peerStat->getCuid() ||
|
||||
(p->getStatus() == PeerStat::ACTIVE &&
|
||||
!p->getDownloadStartTime().elapsed(startupIdleTime))) {
|
||||
continue;
|
||||
}
|
||||
unsigned int pSpeed = p->calculateDownloadSpeed();
|
||||
if(pSpeed < speed) {
|
||||
speed = pSpeed;
|
||||
slowSegmentEntry = segmentEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return slowSegmentEntry;
|
||||
|
@ -241,22 +252,36 @@ uint64_t SegmentMan::getDownloadLength() const {
|
|||
}
|
||||
}
|
||||
|
||||
void SegmentMan::registerPeerStat(const PeerStatHandle& peerStat) {
|
||||
PeerStatHandle temp = getPeerStat(peerStat->getCuid());
|
||||
if(!temp.get()) {
|
||||
peerStats.push_back(peerStat);
|
||||
class FindPeerStat {
|
||||
public:
|
||||
bool operator()(const SharedHandle<PeerStat>& peerStat, int32_t cuid) const
|
||||
{
|
||||
return peerStat->getCuid() < cuid;
|
||||
}
|
||||
};
|
||||
|
||||
bool SegmentMan::registerPeerStat(const SharedHandle<PeerStat>& peerStat)
|
||||
{
|
||||
std::deque<SharedHandle<PeerStat> >::iterator i =
|
||||
std::lower_bound(peerStats.begin(), peerStats.end(),peerStat->getCuid(),
|
||||
FindPeerStat());
|
||||
if(i == peerStats.end() || (*i)->getCuid() != peerStat->getCuid()) {
|
||||
peerStats.insert(i, peerStat);
|
||||
return true ;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PeerStatHandle SegmentMan::getPeerStat(int32_t cuid) const
|
||||
{
|
||||
for(std::deque<SharedHandle<PeerStat> >::const_iterator itr = peerStats.begin(); itr != peerStats.end(); ++itr) {
|
||||
const PeerStatHandle& peerStat = *itr;
|
||||
if(peerStat->getCuid() == cuid) {
|
||||
return peerStat;
|
||||
}
|
||||
std::deque<SharedHandle<PeerStat> >::const_iterator i =
|
||||
std::lower_bound(peerStats.begin(), peerStats.end(), cuid, FindPeerStat());
|
||||
if(i != peerStats.end() && (*i)->getCuid() == cuid) {
|
||||
return *i;
|
||||
} else {
|
||||
return SharedHandle<PeerStat>();
|
||||
}
|
||||
return SharedHandle<PeerStat>();
|
||||
}
|
||||
|
||||
unsigned int SegmentMan::calculateDownloadSpeed() const {
|
||||
|
|
|
@ -82,7 +82,8 @@ private:
|
|||
SharedHandle<Segment> checkoutSegment(int32_t cuid,
|
||||
const SharedHandle<Piece>& piece);
|
||||
|
||||
SegmentEntryHandle findSlowerSegmentEntry(const SharedHandle<PeerStat>& peerStat) const;
|
||||
SharedHandle<SegmentEntry> findSlowerSegmentEntry
|
||||
(const SharedHandle<PeerStat>& peerStat);
|
||||
public:
|
||||
SegmentMan(const Option* option,
|
||||
const SharedHandle<DownloadContext>& downloadContext,
|
||||
|
@ -159,10 +160,10 @@ public:
|
|||
uint64_t getDownloadLength() const;
|
||||
|
||||
/**
|
||||
* Registers given peerStat if it has not been registerd.
|
||||
* Otherwise does nothing.
|
||||
* Registers given peerStat if it has not been registerd and returns true.
|
||||
* Otherwise does nothing and returns false.
|
||||
*/
|
||||
void registerPeerStat(const SharedHandle<PeerStat>& peerStat);
|
||||
bool registerPeerStat(const SharedHandle<PeerStat>& peerStat);
|
||||
|
||||
/**
|
||||
* Returns peerStat whose cuid is given cuid. If it is not found, returns
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "Segment.h"
|
||||
#include "Option.h"
|
||||
#include "FileEntry.h"
|
||||
#include "MockPieceStorage.h"
|
||||
#include "PeerStat.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
namespace aria2 {
|
||||
|
@ -17,7 +19,7 @@ class SegmentManTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST_SUITE(SegmentManTest);
|
||||
CPPUNIT_TEST(testNullBitfield);
|
||||
CPPUNIT_TEST(testCompleteSegment);
|
||||
CPPUNIT_TEST(testMarkPieceDone_usedSegment);
|
||||
CPPUNIT_TEST(testGetPeerStat);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
|
@ -27,7 +29,7 @@ public:
|
|||
|
||||
void testNullBitfield();
|
||||
void testCompleteSegment();
|
||||
void testMarkPieceDone_usedSegment();
|
||||
void testGetPeerStat();
|
||||
};
|
||||
|
||||
|
||||
|
@ -82,30 +84,38 @@ void SegmentManTest::testCompleteSegment()
|
|||
CPPUNIT_ASSERT_EQUAL((size_t)2, segments[1]->getIndex());
|
||||
}
|
||||
|
||||
void SegmentManTest::testMarkPieceDone_usedSegment()
|
||||
void SegmentManTest::testGetPeerStat()
|
||||
{
|
||||
// TODO implement this later
|
||||
/*
|
||||
SegmentMan segmentMan;
|
||||
int32_t pieceLength = 1024*1024;
|
||||
int64_t totalLength = 10*pieceLength;
|
||||
segmentMan.initBitfield(pieceLength, totalLength);
|
||||
segmentMan.markPieceDone(5*pieceLength+100);
|
||||
Option op;
|
||||
size_t pieceLength = 1;
|
||||
uint64_t totalLength = 1;
|
||||
SharedHandle<SingleFileDownloadContext> dctx
|
||||
(new SingleFileDownloadContext(pieceLength, totalLength, "aria2.tar.bz2"));
|
||||
SharedHandle<PieceStorage> ps(new MockPieceStorage());
|
||||
SegmentMan segmentMan(&op, dctx, ps);
|
||||
|
||||
for(int32_t i = 0; i < 5; ++i) {
|
||||
CPPUNIT_ASSERT(segmentMan.hasSegment(i));
|
||||
CPPUNIT_ASSERT(segmentMan.getPeerStat(1).isNull());
|
||||
SharedHandle<PeerStat> ps1(new PeerStat(1));
|
||||
CPPUNIT_ASSERT(segmentMan.registerPeerStat(ps1));
|
||||
{
|
||||
SharedHandle<PeerStat> ps = segmentMan.getPeerStat(1);
|
||||
CPPUNIT_ASSERT(!ps.isNull());
|
||||
CPPUNIT_ASSERT_EQUAL(1, ps->getCuid());
|
||||
}
|
||||
for(int32_t i = 5; i < 10; ++i) {
|
||||
CPPUNIT_ASSERT(!segmentMan.hasSegment(i));
|
||||
// Duplicate registering is not allowed.
|
||||
SharedHandle<PeerStat> ps1d(new PeerStat(1));
|
||||
CPPUNIT_ASSERT(!segmentMan.registerPeerStat(ps1d));
|
||||
|
||||
// See whether it can work on several entries.
|
||||
SharedHandle<PeerStat> ps2(new PeerStat(2));
|
||||
SharedHandle<PeerStat> ps3(new PeerStat(3));
|
||||
CPPUNIT_ASSERT(segmentMan.registerPeerStat(ps3));
|
||||
CPPUNIT_ASSERT(segmentMan.registerPeerStat(ps2));
|
||||
{
|
||||
SharedHandle<PeerStat> ps = segmentMan.getPeerStat(2);
|
||||
CPPUNIT_ASSERT(!ps.isNull());
|
||||
CPPUNIT_ASSERT_EQUAL(2, ps->getCuid());
|
||||
}
|
||||
|
||||
SharedHandle<Segment> segment = segmentMan.getSegment(0, 5);
|
||||
CPPUNIT_ASSERT(!segment.isNull());
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)5, segment->index);
|
||||
CPPUNIT_ASSERT_EQUAL(pieceLength, (int32_t) segment->length);
|
||||
CPPUNIT_ASSERT_EQUAL(pieceLength, (int32_t) segment->segmentLength);
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)100, segment->writtenLength);
|
||||
*/
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
Loading…
Reference in New Issue