2010-08-29 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Added a sets of overloaded functions for
	PieceStorage::getMissingPiece() and getMissingFastPiece() to get
	multiple pieces more efficiently.
	* src/DefaultBtInteractive.cc
	* src/DefaultPieceStorage.cc
	* src/DefaultPieceStorage.h
	* src/PieceStorage.h
	* src/UnknownLengthPieceStorage.cc
	* src/UnknownLengthPieceStorage.h
	* test/DefaultPieceStorageTest.cc
	* test/MockPieceStorage.h
pull/1/head
Tatsuhiro Tsujikawa 2010-08-29 08:53:19 +00:00
parent b49081340d
commit e997903e5d
9 changed files with 351 additions and 104 deletions

View File

@ -1,3 +1,17 @@
2010-08-29 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added a sets of overloaded functions for
PieceStorage::getMissingPiece() and getMissingFastPiece() to get
multiple pieces more efficiently.
* src/DefaultBtInteractive.cc
* src/DefaultPieceStorage.cc
* src/DefaultPieceStorage.h
* src/PieceStorage.h
* src/UnknownLengthPieceStorage.cc
* src/UnknownLengthPieceStorage.h
* test/DefaultPieceStorageTest.cc
* test/MockPieceStorage.h
2010-08-28 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> 2010-08-28 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Changed signature of util::executeHook(). Changed signature of util::executeHook().

View File

@ -355,42 +355,41 @@ void DefaultBtInteractive::decideInterest() {
void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) { void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) {
if(pieceStorage_->hasMissingPiece(peer_)) { if(pieceStorage_->hasMissingPiece(peer_)) {
size_t numMissingBlock = btRequestFactory_->countMissingBlock(); size_t numMissingBlock = btRequestFactory_->countMissingBlock();
if(numMissingBlock >= maxMissingBlock) {
return;
}
size_t diffMissingBlock = maxMissingBlock-numMissingBlock;
std::vector<SharedHandle<Piece> > pieces;
if(peer_->peerChoking()) { if(peer_->peerChoking()) {
if(peer_->isFastExtensionEnabled()) { if(peer_->isFastExtensionEnabled()) {
std::vector<size_t> excludedIndexes; if(pieceStorage_->isEndGame()) {
excludedIndexes.reserve(btRequestFactory_->countTargetPiece()); std::vector<size_t> excludedIndexes;
btRequestFactory_->getTargetPieceIndexes(excludedIndexes); excludedIndexes.reserve(btRequestFactory_->countTargetPiece());
while(numMissingBlock < maxMissingBlock) { btRequestFactory_->getTargetPieceIndexes(excludedIndexes);
SharedHandle<Piece> piece = pieceStorage_->getMissingFastPiece
pieceStorage_->getMissingFastPiece(peer_, excludedIndexes); (pieces, diffMissingBlock, peer_, excludedIndexes);
if(piece.isNull()) { } else {
break; pieces.reserve(diffMissingBlock);
} else { pieceStorage_->getMissingFastPiece(pieces, diffMissingBlock, peer_);
btRequestFactory_->addTargetPiece(piece);
numMissingBlock += piece->countMissingBlock();
excludedIndexes.push_back(piece->getIndex());
}
} }
} }
} else { } else {
std::vector<size_t> excludedIndexes; if(pieceStorage_->isEndGame()) {
excludedIndexes.reserve(btRequestFactory_->countTargetPiece()); std::vector<size_t> excludedIndexes;
btRequestFactory_->getTargetPieceIndexes(excludedIndexes); excludedIndexes.reserve(btRequestFactory_->countTargetPiece());
while(numMissingBlock < maxMissingBlock) { btRequestFactory_->getTargetPieceIndexes(excludedIndexes);
SharedHandle<Piece> piece = pieceStorage_->getMissingPiece
pieceStorage_->getMissingPiece(peer_, excludedIndexes); (pieces, diffMissingBlock, peer_, excludedIndexes);
if(piece.isNull()) { } else {
break; pieces.reserve(diffMissingBlock);
} else { pieceStorage_->getMissingPiece(pieces, diffMissingBlock, peer_);
btRequestFactory_->addTargetPiece(piece);
numMissingBlock += piece->countMissingBlock();
excludedIndexes.push_back(piece->getIndex());
}
} }
} }
for(std::vector<SharedHandle<Piece> >::const_iterator i =
pieces.begin(), eoi = pieces.end(); i != eoi; ++i) {
btRequestFactory_->addTargetPiece(*i);
}
} }
} }

View File

@ -59,6 +59,7 @@
#include "array_fun.h" #include "array_fun.h"
#include "PieceStatMan.h" #include "PieceStatMan.h"
#include "wallclock.h" #include "wallclock.h"
#include "bitfield.h"
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
# include "bittorrent_helper.h" # include "bittorrent_helper.h"
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
@ -83,29 +84,6 @@ DefaultPieceStorage::~DefaultPieceStorage() {
delete bitfieldMan_; delete bitfieldMan_;
} }
bool DefaultPieceStorage::getMissingPieceIndex(size_t& index,
const unsigned char* bitfield,
size_t length)
{
const size_t mislen = bitfieldMan_->getBitfieldLength();
array_ptr<unsigned char> misbitfield(new unsigned char[mislen]);
bool r;
if(isEndGame()) {
r = bitfieldMan_->getAllMissingIndexes(misbitfield, mislen,
bitfield, length);
} else {
r = bitfieldMan_->getAllMissingUnusedIndexes(misbitfield, mislen,
bitfield, length);
}
if(r) {
// We assume indexes is sorted using comparator less.
return
pieceSelector_->select(index, misbitfield,bitfieldMan_->countBlock());
} else {
return false;
}
}
SharedHandle<Piece> DefaultPieceStorage::checkOutPiece(size_t index) SharedHandle<Piece> DefaultPieceStorage::checkOutPiece(size_t index)
{ {
bitfieldMan_->setUseBit(index); bitfieldMan_->setUseBit(index);
@ -172,23 +150,6 @@ SharedHandle<Piece> DefaultPieceStorage::findUsedPiece(size_t index) const
} }
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(const unsigned char* bitfield, size_t length)
{
size_t index;
if(getMissingPieceIndex(index, bitfield, length)) {
return checkOutPiece(index);
} else {
return SharedHandle<Piece>();
}
}
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(const BitfieldMan& bitfield)
{
return getMissingPiece(bitfield.getBitfield(), bitfield.getBitfieldLength());
}
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
bool DefaultPieceStorage::hasMissingPiece(const SharedHandle<Peer>& peer) bool DefaultPieceStorage::hasMissingPiece(const SharedHandle<Peer>& peer)
@ -197,10 +158,58 @@ bool DefaultPieceStorage::hasMissingPiece(const SharedHandle<Peer>& peer)
peer->getBitfieldLength()); peer->getBitfieldLength());
} }
SharedHandle<Piece> void DefaultPieceStorage::getMissingPiece
DefaultPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer) (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const unsigned char* bitfield,
size_t length)
{ {
return getMissingPiece(peer->getBitfield(), peer->getBitfieldLength()); const size_t mislen = bitfieldMan_->getBitfieldLength();
array_ptr<unsigned char> misbitfield(new unsigned char[mislen]);
size_t blocks = bitfieldMan_->countBlock();
size_t misBlock = 0;
if(isEndGame()) {
bool r = bitfieldMan_->getAllMissingIndexes
(misbitfield, mislen, bitfield, length);
if(!r) {
return;
}
std::vector<size_t> indexes;
for(size_t i = 0; i < blocks; ++i) {
if(bitfield::test(misbitfield, blocks, i)) {
indexes.push_back(i);
}
}
std::random_shuffle(indexes.begin(), indexes.end());
for(std::vector<size_t>::const_iterator i = indexes.begin(),
eoi = indexes.end(); i != eoi && misBlock < minMissingBlocks; ++i) {
pieces.push_back(checkOutPiece(*i));
misBlock += pieces.back()->countMissingBlock();
}
} else {
bool r = bitfieldMan_->getAllMissingUnusedIndexes
(misbitfield, mislen, bitfield, length);
if(!r) {
return;
}
while(misBlock < minMissingBlocks) {
size_t index;
if(pieceSelector_->select(index, misbitfield, blocks)) {
pieces.push_back(checkOutPiece(index));
bitfield::flipBit(misbitfield, blocks, index);
misBlock += pieces.back()->countMissingBlock();
} else {
break;
}
}
}
}
static void unsetExcludedIndexes(BitfieldMan& bitfield,
const std::vector<size_t>& excludedIndexes)
{
std::for_each(excludedIndexes.begin(), excludedIndexes.end(),
std::bind1st(std::mem_fun(&BitfieldMan::unsetBit), &bitfield));
} }
void DefaultPieceStorage::createFastIndexBitfield void DefaultPieceStorage::createFastIndexBitfield
@ -215,47 +224,107 @@ void DefaultPieceStorage::createFastIndexBitfield
} }
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece void DefaultPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer) (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{ {
if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) { getMissingPiece(pieces, minMissingBlocks,
BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), peer->getBitfield(), peer->getBitfieldLength());
bitfieldMan_->getTotalLength());
createFastIndexBitfield(tempBitfield, peer);
return getMissingPiece(tempBitfield);
} else {
return SharedHandle<Piece>();
}
} }
static void unsetExcludedIndexes(BitfieldMan& bitfield,
const std::vector<size_t>& excludedIndexes)
{
std::for_each(excludedIndexes.begin(), excludedIndexes.end(),
std::bind1st(std::mem_fun(&BitfieldMan::unsetBit), &bitfield));
}
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece void DefaultPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes) (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
{ {
BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(),
bitfieldMan_->getTotalLength()); bitfieldMan_->getTotalLength());
tempBitfield.setBitfield(peer->getBitfield(), peer->getBitfieldLength()); tempBitfield.setBitfield(peer->getBitfield(), peer->getBitfieldLength());
unsetExcludedIndexes(tempBitfield, excludedIndexes); unsetExcludedIndexes(tempBitfield, excludedIndexes);
return getMissingPiece(tempBitfield); getMissingPiece(pieces, minMissingBlocks,
tempBitfield.getBitfield(), tempBitfield.getBitfieldLength());
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece void DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes) (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{
if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) {
BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(),
bitfieldMan_->getTotalLength());
createFastIndexBitfield(tempBitfield, peer);
getMissingPiece(pieces, minMissingBlocks,
tempBitfield.getBitfield(),
tempBitfield.getBitfieldLength());
}
}
void DefaultPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
{ {
if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) { if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) {
BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(),
bitfieldMan_->getTotalLength()); bitfieldMan_->getTotalLength());
createFastIndexBitfield(tempBitfield, peer); createFastIndexBitfield(tempBitfield, peer);
unsetExcludedIndexes(tempBitfield, excludedIndexes); unsetExcludedIndexes(tempBitfield, excludedIndexes);
return getMissingPiece(tempBitfield); getMissingPiece(pieces, minMissingBlocks,
} else { tempBitfield.getBitfield(),
tempBitfield.getBitfieldLength());
}
}
SharedHandle<Piece>
DefaultPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer)
{
std::vector<SharedHandle<Piece> > pieces;
getMissingPiece(pieces, 1, peer);
if(pieces.empty()) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} else {
return pieces.front();
}
}
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes)
{
std::vector<SharedHandle<Piece> > pieces;
getMissingPiece(pieces, 1, peer, excludedIndexes);
if(pieces.empty()) {
return SharedHandle<Piece>();
} else {
return pieces.front();
}
}
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer)
{
std::vector<SharedHandle<Piece> > pieces;
getMissingFastPiece(pieces, 1, peer);
if(pieces.empty()) {
return SharedHandle<Piece>();
} else {
return pieces.front();
}
}
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes)
{
std::vector<SharedHandle<Piece> > pieces;
getMissingFastPiece(pieces, 1, peer, excludedIndexes);
if(pieces.empty()) {
return SharedHandle<Piece>();
} else {
return pieces.front();
} }
} }

View File

@ -88,15 +88,13 @@ private:
SharedHandle<PieceSelector> pieceSelector_; SharedHandle<PieceSelector> pieceSelector_;
bool getMissingPieceIndex(size_t& index,
const unsigned char* bitfield, size_t length);
SharedHandle<Piece> getMissingPiece(const unsigned char* bitfield,
size_t length);
SharedHandle<Piece> getMissingPiece(const BitfieldMan& bitfield);
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const unsigned char* bitfield,
size_t length);
void createFastIndexBitfield(BitfieldMan& bitfield, void createFastIndexBitfield(BitfieldMan& bitfield,
const SharedHandle<Peer>& peer); const SharedHandle<Peer>& peer);
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
@ -123,6 +121,28 @@ public:
virtual bool hasMissingPiece(const SharedHandle<Peer>& peer); virtual bool hasMissingPiece(const SharedHandle<Peer>& peer);
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes);
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes);
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
virtual SharedHandle<Piece> getMissingPiece(const SharedHandle<Peer>& peer); virtual SharedHandle<Piece> getMissingPiece(const SharedHandle<Peer>& peer);
virtual SharedHandle<Piece> getMissingFastPiece virtual SharedHandle<Piece> getMissingFastPiece

View File

@ -63,6 +63,28 @@ public:
*/ */
virtual bool hasMissingPiece(const SharedHandle<Peer>& peer) = 0; virtual bool hasMissingPiece(const SharedHandle<Peer>& peer) = 0;
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) = 0;
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer) = 0;
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) = 0;
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer) = 0;
/** /**
* Returns a piece that the peer has but localhost doesn't. * Returns a piece that the peer has but localhost doesn't.
* The piece will be marked "used" status in order to prevent other command * The piece will be marked "used" status in order to prevent other command

View File

@ -78,6 +78,40 @@ bool UnknownLengthPieceStorage::hasMissingPiece(const SharedHandle<Peer>& peer)
abort(); abort();
} }
void UnknownLengthPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
{
abort();
}
void UnknownLengthPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{
abort();
}
void UnknownLengthPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
{
abort();
}
void UnknownLengthPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{
abort();
}
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer) SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer)
{ {
abort(); abort();

View File

@ -73,6 +73,28 @@ public:
*/ */
virtual bool hasMissingPiece(const SharedHandle<Peer>& peer); virtual bool hasMissingPiece(const SharedHandle<Peer>& peer);
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes);
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes);
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
/** /**
* Returns a piece that the peer has but localhost doesn't. * Returns a piece that the peer has but localhost doesn't.
* The piece will be marked "used" status in order to prevent other command * The piece will be marked "used" status in order to prevent other command

View File

@ -12,6 +12,9 @@
#include "InOrderPieceSelector.h" #include "InOrderPieceSelector.h"
#include "DownloadContext.h" #include "DownloadContext.h"
#include "bittorrent_helper.h" #include "bittorrent_helper.h"
#include "DiskAdaptor.h"
#include "DiskWriterFactory.h"
#include "PieceStatMan.h"
namespace aria2 { namespace aria2 {
@ -20,7 +23,9 @@ class DefaultPieceStorageTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DefaultPieceStorageTest); CPPUNIT_TEST_SUITE(DefaultPieceStorageTest);
CPPUNIT_TEST(testGetTotalLength); CPPUNIT_TEST(testGetTotalLength);
CPPUNIT_TEST(testGetMissingPiece); CPPUNIT_TEST(testGetMissingPiece);
CPPUNIT_TEST(testGetMissingPiece_many);
CPPUNIT_TEST(testGetMissingPiece_excludedIndexes); CPPUNIT_TEST(testGetMissingPiece_excludedIndexes);
CPPUNIT_TEST(testGetMissingPiece_manyWithExcludedIndexes);
CPPUNIT_TEST(testGetMissingFastPiece); CPPUNIT_TEST(testGetMissingFastPiece);
CPPUNIT_TEST(testGetMissingFastPiece_excludedIndexes); CPPUNIT_TEST(testGetMissingFastPiece_excludedIndexes);
CPPUNIT_TEST(testHasMissingPiece); CPPUNIT_TEST(testHasMissingPiece);
@ -57,7 +62,9 @@ public:
void testGetTotalLength(); void testGetTotalLength();
void testGetMissingPiece(); void testGetMissingPiece();
void testGetMissingPiece_many();
void testGetMissingPiece_excludedIndexes(); void testGetMissingPiece_excludedIndexes();
void testGetMissingPiece_manyWithExcludedIndexes();
void testGetMissingFastPiece(); void testGetMissingFastPiece();
void testGetMissingFastPiece_excludedIndexes(); void testGetMissingFastPiece_excludedIndexes();
void testHasMissingPiece(); void testHasMissingPiece();
@ -83,8 +90,6 @@ void DefaultPieceStorageTest::testGetTotalLength() {
void DefaultPieceStorageTest::testGetMissingPiece() { void DefaultPieceStorageTest::testGetMissingPiece() {
DefaultPieceStorage pss(dctx_, option); DefaultPieceStorage pss(dctx_, option);
pss.setPieceSelector(pieceSelector_); pss.setPieceSelector(pieceSelector_);
pss.setEndGamePieceNum(0);
peer->setAllBitfield(); peer->setAllBitfield();
SharedHandle<Piece> piece = pss.getMissingPiece(peer); SharedHandle<Piece> piece = pss.getMissingPiece(peer);
@ -100,6 +105,24 @@ void DefaultPieceStorageTest::testGetMissingPiece() {
CPPUNIT_ASSERT(piece.isNull()); CPPUNIT_ASSERT(piece.isNull());
} }
void DefaultPieceStorageTest::testGetMissingPiece_many() {
DefaultPieceStorage pss(dctx_, option);
pss.setPieceSelector(pieceSelector_);
peer->setAllBitfield();
std::vector<SharedHandle<Piece> > pieces;
pss.getMissingPiece(pieces, 2, peer);
CPPUNIT_ASSERT_EQUAL((size_t)2, pieces.size());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
pieces[0]->toString());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"),
pieces[1]->toString());
pieces.clear();
pss.getMissingPiece(pieces, 2, peer);
CPPUNIT_ASSERT_EQUAL((size_t)1, pieces.size());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
pieces[0]->toString());
}
void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes() void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes()
{ {
DefaultPieceStorage pss(dctx_, option); DefaultPieceStorage pss(dctx_, option);
@ -123,6 +146,24 @@ void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes()
CPPUNIT_ASSERT(piece.isNull()); CPPUNIT_ASSERT(piece.isNull());
} }
void DefaultPieceStorageTest::testGetMissingPiece_manyWithExcludedIndexes() {
DefaultPieceStorage pss(dctx_, option);
pss.setPieceSelector(pieceSelector_);
peer->setAllBitfield();
std::vector<size_t> excludedIndexes;
excludedIndexes.push_back(1);
std::vector<SharedHandle<Piece> > pieces;
pss.getMissingPiece(pieces, 2, peer, excludedIndexes);
CPPUNIT_ASSERT_EQUAL((size_t)2, pieces.size());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
pieces[0]->toString());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
pieces[1]->toString());
pieces.clear();
pss.getMissingPiece(pieces, 2, peer, excludedIndexes);
CPPUNIT_ASSERT(pieces.empty());
}
void DefaultPieceStorageTest::testGetMissingFastPiece() { void DefaultPieceStorageTest::testGetMissingFastPiece() {
DefaultPieceStorage pss(dctx_, option); DefaultPieceStorage pss(dctx_, option);
pss.setPieceSelector(pieceSelector_); pss.setPieceSelector(pieceSelector_);

View File

@ -48,6 +48,32 @@ public:
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());
} }
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
{}
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{}
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
{}
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{}
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes) (const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes)
{ {