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