2008-09-19 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Fixed the bug that a block in a piece is requested when same 
block is
	already requested to the same peer in end game mode.
	* src/BtRequestFactory.h
	* src/DefaultBtInteractive.cc
	* src/DefaultBtRequestFactory.cc
	* src/DefaultBtRequestFactory.h
	* src/DefaultPieceStorage.cc
	* src/DefaultPieceStorage.h
	* src/PieceStorage.h
	* src/UnknownLengthPieceStorage.cc
	* src/UnknownLengthPieceStorage.h
	* test/DefaultBtRequestFactoryTest.cc
	* test/DefaultPieceStorageTest.cc
	* test/MockBtRequestFactory.h
	* test/MockPieceStorage.h
pull/1/head
Tatsuhiro Tsujikawa 2008-09-19 14:11:41 +00:00
parent cdaafd8c8c
commit 67767e2f61
14 changed files with 242 additions and 36 deletions

View File

@ -1,3 +1,21 @@
2008-09-19 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Fixed the bug that a block in a piece is requested when same block is
already requested to the same peer in end game mode.
* src/BtRequestFactory.h
* src/DefaultBtInteractive.cc
* src/DefaultBtRequestFactory.cc
* src/DefaultBtRequestFactory.h
* src/DefaultPieceStorage.cc
* src/DefaultPieceStorage.h
* src/PieceStorage.h
* src/UnknownLengthPieceStorage.cc
* src/UnknownLengthPieceStorage.h
* test/DefaultBtRequestFactoryTest.cc
* test/DefaultPieceStorageTest.cc
* test/MockBtRequestFactory.h
* test/MockPieceStorage.h
2008-09-19 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2008-09-19 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Removed _uploadLength and _downloadLength from PeerSessionResource Removed _uploadLength and _downloadLength from PeerSessionResource

View File

@ -76,6 +76,13 @@ public:
*/ */
virtual void createRequestMessagesOnEndGame virtual void createRequestMessagesOnEndGame
(std::deque<SharedHandle<BtMessage> >& requests, size_t max) = 0; (std::deque<SharedHandle<BtMessage> >& requests, size_t max) = 0;
/**
* Stores the list of index of pieces added using addTargetPiece() into
* indexes.
*/
virtual void getTargetPieceIndexes(std::deque<size_t>& indexes) const = 0;
}; };
typedef SharedHandle<BtRequestFactory> BtRequestFactoryHandle; typedef SharedHandle<BtRequestFactory> BtRequestFactoryHandle;

View File

@ -295,25 +295,32 @@ void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) {
if(peer->peerChoking()) { if(peer->peerChoking()) {
if(peer->isFastExtensionEnabled()) { if(peer->isFastExtensionEnabled()) {
std::deque<size_t> excludedIndexes;
btRequestFactory->getTargetPieceIndexes(excludedIndexes);
while(numMissingBlock < maxMissingBlock) { while(numMissingBlock < maxMissingBlock) {
PieceHandle piece = pieceStorage->getMissingFastPiece(peer); SharedHandle<Piece> piece =
pieceStorage->getMissingFastPiece(peer, excludedIndexes);
if(piece.isNull()) { if(piece.isNull()) {
break; break;
} else { } else {
btRequestFactory->addTargetPiece(piece); btRequestFactory->addTargetPiece(piece);
numMissingBlock += piece->countMissingBlock(); numMissingBlock += piece->countMissingBlock();
excludedIndexes.push_back(piece->getIndex());
} }
} }
} }
} else { } else {
std::deque<size_t> excludedIndexes;
btRequestFactory->getTargetPieceIndexes(excludedIndexes);
while(numMissingBlock < maxMissingBlock) { while(numMissingBlock < maxMissingBlock) {
PieceHandle piece = pieceStorage->getMissingPiece(peer); SharedHandle<Piece> piece =
pieceStorage->getMissingPiece(peer, excludedIndexes);
if(piece.isNull()) { if(piece.isNull()) {
break; break;
} else { } else {
btRequestFactory->addTargetPiece(piece); btRequestFactory->addTargetPiece(piece);
numMissingBlock += piece->countMissingBlock(); numMissingBlock += piece->countMissingBlock();
excludedIndexes.push_back(piece->getIndex());
} }
} }
} }

View File

@ -210,6 +210,13 @@ size_t DefaultBtRequestFactory::countMissingBlock()
CountMissingBlock()).getNumMissingBlock(); CountMissingBlock()).getNumMissingBlock();
} }
void DefaultBtRequestFactory::getTargetPieceIndexes
(std::deque<size_t>& indexes) const
{
std::transform(pieces.begin(), pieces.end(), std::back_inserter(indexes),
mem_fun_sh(&Piece::getIndex));
}
std::deque<SharedHandle<Piece> >& DefaultBtRequestFactory::getTargetPieces() std::deque<SharedHandle<Piece> >& DefaultBtRequestFactory::getTargetPieces()
{ {
return pieces; return pieces;

View File

@ -84,6 +84,8 @@ public:
virtual void createRequestMessagesOnEndGame virtual void createRequestMessagesOnEndGame
(std::deque<SharedHandle<BtMessage> >& requests, size_t max); (std::deque<SharedHandle<BtMessage> >& requests, size_t max);
virtual void getTargetPieceIndexes(std::deque<size_t>& indexes) const;
std::deque<SharedHandle<Piece> >& getTargetPieces(); std::deque<SharedHandle<Piece> >& getTargetPieces();
void setCuid(int32_t cuid) void setCuid(int32_t cuid)

View File

@ -87,22 +87,20 @@ bool DefaultPieceStorage::isEndGame()
return bitfieldMan->countMissingBlock() <= endGamePieceNum; return bitfieldMan->countMissingBlock() <= endGamePieceNum;
} }
bool DefaultPieceStorage::getMissingPieceIndex(size_t& index, const PeerHandle& peer) bool DefaultPieceStorage::getMissingPieceIndex(size_t& index,
const unsigned char* bitfield,
size_t& length)
{ {
std::deque<size_t> indexes; std::deque<size_t> indexes;
bool r; bool r;
if(isEndGame()) { if(isEndGame()) {
r = bitfieldMan->getAllMissingIndexes(indexes, peer->getBitfield(), r = bitfieldMan->getAllMissingIndexes(indexes, bitfield, length);
peer->getBitfieldLength());
} else { } else {
r = bitfieldMan->getAllMissingUnusedIndexes(indexes, r = bitfieldMan->getAllMissingUnusedIndexes(indexes, bitfield, length);
peer->getBitfield(),
peer->getBitfieldLength());
} }
if(r) { if(r) {
// We assume indexes is sorted using comparator less. // We assume indexes is sorted using comparator less.
_pieceSelector->select(index, indexes); return _pieceSelector->select(index, indexes);
return true;
} else { } else {
return false; return false;
} }
@ -171,45 +169,81 @@ PieceHandle DefaultPieceStorage::findUsedPiece(size_t index) const
} }
} }
PieceHandle DefaultPieceStorage::getMissingPiece(const PeerHandle& peer) SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(const unsigned char* bitfield, size_t length)
{ {
size_t index; size_t index;
if(getMissingPieceIndex(index, peer)) { if(getMissingPieceIndex(index, bitfield, length)) {
return checkOutPiece(index); return checkOutPiece(index);
} else { } else {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} }
} }
bool DefaultPieceStorage::getMissingFastPieceIndex(size_t& index, SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
const PeerHandle& peer) (const BitfieldMan& bitfield)
{
return getMissingPiece(bitfield.getBitfield(), bitfield.getBitfieldLength());
}
PieceHandle DefaultPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer)
{
return getMissingPiece(peer->getBitfield(), peer->getBitfieldLength());
}
void DefaultPieceStorage::createFastIndexBitfield
(BitfieldMan& bitfield, const SharedHandle<Peer>& peer)
{
for(std::deque<size_t>::const_iterator itr =
peer->getPeerAllowedIndexSet().begin();
itr != peer->getPeerAllowedIndexSet().end(); ++itr) {
if(!bitfieldMan->isBitSet(*itr) && peer->hasPiece(*itr)) {
bitfield.setBit(*itr);
}
}
}
PieceHandle DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer)
{ {
if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) { if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) {
BitfieldMan tempBitfield(bitfieldMan->getBlockLength(), BitfieldMan tempBitfield(bitfieldMan->getBlockLength(),
bitfieldMan->getTotalLength()); bitfieldMan->getTotalLength());
for(std::deque<size_t>::const_iterator itr = peer->getPeerAllowedIndexSet().begin(); createFastIndexBitfield(tempBitfield, peer);
itr != peer->getPeerAllowedIndexSet().end(); itr++) { return getMissingPiece(tempBitfield);
if(!bitfieldMan->isBitSet(*itr) && peer->hasPiece(*itr)) { } else {
tempBitfield.setBit(*itr); return SharedHandle<Piece>();
}
}
if(isEndGame()) {
return bitfieldMan->getMissingIndex(index, tempBitfield.getBitfield(),
tempBitfield.getBitfieldLength());
} else {
return bitfieldMan->getMissingUnusedIndex(index,
tempBitfield.getBitfield(),
tempBitfield.getBitfieldLength());
}
} }
return false;
} }
PieceHandle DefaultPieceStorage::getMissingFastPiece(const PeerHandle& peer) static void unsetExcludedIndexes(BitfieldMan& bitfield,
const std::deque<size_t>& excludedIndexes)
{ {
size_t index; for(std::deque<size_t>::const_iterator i = excludedIndexes.begin();
if(getMissingFastPieceIndex(index, peer)) { i != excludedIndexes.end(); ++i) {
return checkOutPiece(index); bitfield.unsetBit(*i);
}
}
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes)
{
BitfieldMan tempBitfield(bitfieldMan->getBlockLength(),
bitfieldMan->getTotalLength());
tempBitfield.setBitfield(peer->getBitfield(), peer->getBitfieldLength());
unsetExcludedIndexes(tempBitfield, excludedIndexes);
return getMissingPiece(tempBitfield);
}
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes)
{
if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) {
BitfieldMan tempBitfield(bitfieldMan->getBlockLength(),
bitfieldMan->getTotalLength());
createFastIndexBitfield(tempBitfield, peer);
unsetExcludedIndexes(tempBitfield, excludedIndexes);
return getMissingPiece(tempBitfield);
} else { } else {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} }

View File

@ -83,8 +83,17 @@ private:
SharedHandle<RarestPieceSelector> _pieceSelector; SharedHandle<RarestPieceSelector> _pieceSelector;
bool getMissingPieceIndex(size_t& index, const SharedHandle<Peer>& peer); bool getMissingPieceIndex(size_t& index,
bool getMissingFastPieceIndex(size_t& index, const SharedHandle<Peer>& peer); const unsigned char* bitfield, size_t& length);
SharedHandle<Piece> getMissingPiece(const unsigned char* bitfield,
size_t length);
SharedHandle<Piece> getMissingPiece(const BitfieldMan& bitfield);
void createFastIndexBitfield(BitfieldMan& bitfield,
const SharedHandle<Peer>& peer);
SharedHandle<Piece> checkOutPiece(size_t index); SharedHandle<Piece> checkOutPiece(size_t index);
// size_t deleteUsedPiecesByFillRate(int fillRate, size_t toDelete); // size_t deleteUsedPiecesByFillRate(int fillRate, size_t toDelete);
// void reduceUsedPieces(size_t upperBound); // void reduceUsedPieces(size_t upperBound);
@ -109,6 +118,12 @@ public:
virtual SharedHandle<Piece> getMissingFastPiece(const SharedHandle<Peer>& peer); virtual SharedHandle<Piece> getMissingFastPiece(const SharedHandle<Peer>& peer);
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes);
virtual SharedHandle<Piece> getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes);
virtual SharedHandle<Piece> getMissingPiece(); virtual SharedHandle<Piece> getMissingPiece();
virtual SharedHandle<Piece> getMissingPiece(size_t index); virtual SharedHandle<Piece> getMissingPiece(size_t index);

View File

@ -67,6 +67,14 @@ public:
virtual SharedHandle<Piece> virtual SharedHandle<Piece>
getMissingPiece(const SharedHandle<Peer>& peer) = 0; getMissingPiece(const SharedHandle<Peer>& peer) = 0;
/**
* Same as getMissingPiece(const SharedHandle<Peer>& peer), but the indexes in
* excludedIndexes are excluded.
*/
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer,
const std::deque<size_t>& excludedIndexes) = 0;
/** /**
* Returns a piece that the peer has but localhost doesn't. * Returns a piece that the peer has but localhost doesn't.
* Only pieces that declared as "fast" are returned. * Only pieces that declared as "fast" are returned.
@ -76,6 +84,14 @@ public:
*/ */
virtual SharedHandle<Piece> virtual SharedHandle<Piece>
getMissingFastPiece(const SharedHandle<Peer>& peer) = 0; getMissingFastPiece(const SharedHandle<Peer>& peer) = 0;
/**
* Same as getMissingFastPiece(const SharedHandle<Peer>& peer), but the
* indexes in excludedIndexes are excluded.
*/
virtual SharedHandle<Piece> getMissingFastPiece
(const SharedHandle<Peer>& peer,
const std::deque<size_t>& excludedIndexes) = 0;
/** /**
* Returns a missing piece if available. Otherwise returns 0; * Returns a missing piece if available. Otherwise returns 0;

View File

@ -79,11 +79,23 @@ SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece(const SharedHandl
abort(); abort();
} }
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes)
{
abort();
}
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingFastPiece(const SharedHandle<Peer>& peer) SharedHandle<Piece> UnknownLengthPieceStorage::getMissingFastPiece(const SharedHandle<Peer>& peer)
{ {
abort(); abort();
} }
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes)
{
abort();
}
PieceHandle UnknownLengthPieceStorage::getMissingPiece() PieceHandle UnknownLengthPieceStorage::getMissingPiece()
{ {
if(_downloadFinished) { if(_downloadFinished) {

View File

@ -79,6 +79,9 @@ public:
*/ */
virtual SharedHandle<Piece> getMissingPiece(const SharedHandle<Peer>& peer); virtual SharedHandle<Piece> getMissingPiece(const SharedHandle<Peer>& peer);
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes);
/** /**
* Returns a piece that the peer has but localhost doesn't. * Returns a piece that the peer has but localhost doesn't.
* Only pieces that declared as "fast" are returned. * Only pieces that declared as "fast" are returned.
@ -88,6 +91,9 @@ public:
*/ */
virtual SharedHandle<Piece> getMissingFastPiece(const SharedHandle<Peer>& peer); virtual SharedHandle<Piece> getMissingFastPiece(const SharedHandle<Peer>& peer);
virtual SharedHandle<Piece> getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes);
/** /**
* Returns a missing piece if available. Otherwise returns 0; * Returns a missing piece if available. Otherwise returns 0;
*/ */

View File

@ -25,6 +25,7 @@ class DefaultBtRequestFactoryTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreateRequestMessages); CPPUNIT_TEST(testCreateRequestMessages);
CPPUNIT_TEST(testCreateRequestMessages_onEndGame); CPPUNIT_TEST(testCreateRequestMessages_onEndGame);
CPPUNIT_TEST(testRemoveTargetPiece); CPPUNIT_TEST(testRemoveTargetPiece);
CPPUNIT_TEST(testGetTargetPieceIndexes);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
SharedHandle<DefaultBtRequestFactory> btRequestFactory; SharedHandle<DefaultBtRequestFactory> btRequestFactory;
@ -35,6 +36,7 @@ public:
void testCreateRequestMessages(); void testCreateRequestMessages();
void testCreateRequestMessages_onEndGame(); void testCreateRequestMessages_onEndGame();
void testRemoveTargetPiece(); void testRemoveTargetPiece();
void testGetTargetPieceIndexes();
class MockBtRequestMessage : public MockBtMessage { class MockBtRequestMessage : public MockBtMessage {
public: public:
@ -234,4 +236,22 @@ void DefaultBtRequestFactoryTest::testRemoveTargetPiece() {
piece1) == btRequestFactory->getTargetPieces().end()); piece1) == btRequestFactory->getTargetPieces().end());
} }
void DefaultBtRequestFactoryTest::testGetTargetPieceIndexes()
{
SharedHandle<Piece> piece1(new Piece(1, btContext->getPieceLength()));
SharedHandle<Piece> piece3(new Piece(3, btContext->getPieceLength()));
SharedHandle<Piece> piece5(new Piece(5, btContext->getPieceLength()));
btRequestFactory->addTargetPiece(piece3);
btRequestFactory->addTargetPiece(piece1);
btRequestFactory->addTargetPiece(piece5);
std::deque<size_t> indexes;
btRequestFactory->getTargetPieceIndexes(indexes);
CPPUNIT_ASSERT_EQUAL((size_t)3, indexes.size());
CPPUNIT_ASSERT_EQUAL((size_t)3, indexes[0]);
CPPUNIT_ASSERT_EQUAL((size_t)1, indexes[1]);
CPPUNIT_ASSERT_EQUAL((size_t)5, indexes[2]);
}
} // namespace aria2 } // namespace aria2

View File

@ -18,7 +18,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_excludedIndexes);
CPPUNIT_TEST(testGetMissingFastPiece); CPPUNIT_TEST(testGetMissingFastPiece);
CPPUNIT_TEST(testGetMissingFastPiece_excludedIndexes);
CPPUNIT_TEST(testHasMissingPiece); CPPUNIT_TEST(testHasMissingPiece);
CPPUNIT_TEST(testCompletePiece); CPPUNIT_TEST(testCompletePiece);
CPPUNIT_TEST(testGetPiece); CPPUNIT_TEST(testGetPiece);
@ -56,7 +58,9 @@ public:
void testGetTotalLength(); void testGetTotalLength();
void testGetMissingPiece(); void testGetMissingPiece();
void testGetMissingPiece_excludedIndexes();
void testGetMissingFastPiece(); void testGetMissingFastPiece();
void testGetMissingFastPiece_excludedIndexes();
void testHasMissingPiece(); void testHasMissingPiece();
void testCompletePiece(); void testCompletePiece();
void testGetPiece(); void testGetPiece();
@ -94,6 +98,28 @@ void DefaultPieceStorageTest::testGetMissingPiece() {
CPPUNIT_ASSERT(piece.isNull()); CPPUNIT_ASSERT(piece.isNull());
} }
void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes()
{
DefaultPieceStorage pss(btContext, option, false);
pss.setEndGamePieceNum(0);
peer->setAllBitfield();
std::deque<size_t> excludedIndexes;
excludedIndexes.push_back(1);
SharedHandle<Piece> piece = pss.getMissingPiece(peer, excludedIndexes);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
piece->toString());
piece = pss.getMissingPiece(peer, excludedIndexes);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
piece->toString());
piece = pss.getMissingPiece(peer, excludedIndexes);
CPPUNIT_ASSERT(piece.isNull());
}
void DefaultPieceStorageTest::testGetMissingFastPiece() { void DefaultPieceStorageTest::testGetMissingFastPiece() {
DefaultPieceStorage pss(btContext, option, false); DefaultPieceStorage pss(btContext, option, false);
pss.setEndGamePieceNum(0); pss.setEndGamePieceNum(0);
@ -105,6 +131,28 @@ void DefaultPieceStorageTest::testGetMissingFastPiece() {
SharedHandle<Piece> piece = pss.getMissingFastPiece(peer); SharedHandle<Piece> piece = pss.getMissingFastPiece(peer);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
piece->toString()); piece->toString());
CPPUNIT_ASSERT(pss.getMissingFastPiece(peer).isNull());
}
void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes()
{
DefaultPieceStorage pss(btContext, option, false);
pss.setEndGamePieceNum(0);
peer->setAllBitfield();
peer->setFastExtensionEnabled(true);
peer->addPeerAllowedIndex(1);
peer->addPeerAllowedIndex(2);
std::deque<size_t> excludedIndexes;
excludedIndexes.push_back(2);
SharedHandle<Piece> piece = pss.getMissingFastPiece(peer, excludedIndexes);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"),
piece->toString());
CPPUNIT_ASSERT(pss.getMissingFastPiece(peer, excludedIndexes).isNull());
} }
void DefaultPieceStorageTest::testHasMissingPiece() { void DefaultPieceStorageTest::testHasMissingPiece() {

View File

@ -28,6 +28,8 @@ public:
virtual void createRequestMessagesOnEndGame virtual void createRequestMessagesOnEndGame
(std::deque<SharedHandle<BtMessage> >& requests, size_t max) {} (std::deque<SharedHandle<BtMessage> >& requests, size_t max) {}
virtual void getTargetPieceIndexes(std::deque<size_t>& indexes) const {}
}; };
} // namespace aria2 } // namespace aria2

View File

@ -42,10 +42,22 @@ public:
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());
} }
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes)
{
return SharedHandle<Piece>(new Piece());
}
virtual SharedHandle<Piece> getMissingFastPiece(const SharedHandle<Peer>& peer) { virtual SharedHandle<Piece> getMissingFastPiece(const SharedHandle<Peer>& peer) {
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());
} }
virtual SharedHandle<Piece> getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::deque<size_t>& excludedIndexes)
{
return SharedHandle<Piece>(new Piece());
}
virtual SharedHandle<Piece> getMissingPiece() virtual SharedHandle<Piece> getMissingPiece()
{ {
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());