Managed user cuid in Piece.

Previous implementation does not store information which Command cuid
uses which Piece.  Mark Piece acquired by SegmentMan by setting
Piece::setUsedBySegment(true).
pull/1/head
Tatsuhiro Tsujikawa 2011-07-16 00:58:41 +09:00
parent ba710a7cb4
commit 5c4a52ad74
18 changed files with 313 additions and 153 deletions

View File

@ -353,10 +353,11 @@ void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) {
excludedIndexes.reserve(btRequestFactory_->countTargetPiece()); excludedIndexes.reserve(btRequestFactory_->countTargetPiece());
btRequestFactory_->getTargetPieceIndexes(excludedIndexes); btRequestFactory_->getTargetPieceIndexes(excludedIndexes);
pieceStorage_->getMissingFastPiece pieceStorage_->getMissingFastPiece
(pieces, diffMissingBlock, peer_, excludedIndexes); (pieces, diffMissingBlock, peer_, excludedIndexes, cuid_);
} else { } else {
pieces.reserve(diffMissingBlock); pieces.reserve(diffMissingBlock);
pieceStorage_->getMissingFastPiece(pieces, diffMissingBlock, peer_); pieceStorage_->getMissingFastPiece
(pieces, diffMissingBlock, peer_, cuid_);
} }
} }
} else { } else {
@ -365,10 +366,10 @@ void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) {
excludedIndexes.reserve(btRequestFactory_->countTargetPiece()); excludedIndexes.reserve(btRequestFactory_->countTargetPiece());
btRequestFactory_->getTargetPieceIndexes(excludedIndexes); btRequestFactory_->getTargetPieceIndexes(excludedIndexes);
pieceStorage_->getMissingPiece pieceStorage_->getMissingPiece
(pieces, diffMissingBlock, peer_, excludedIndexes); (pieces, diffMissingBlock, peer_, excludedIndexes, cuid_);
} else { } else {
pieces.reserve(diffMissingBlock); pieces.reserve(diffMissingBlock);
pieceStorage_->getMissingPiece(pieces, diffMissingBlock, peer_); pieceStorage_->getMissingPiece(pieces, diffMissingBlock, peer_, cuid_);
} }
} }
for(std::vector<SharedHandle<Piece> >::const_iterator i = for(std::vector<SharedHandle<Piece> >::const_iterator i =
@ -410,7 +411,7 @@ void DefaultBtInteractive::cancelAllPiece() {
eoi = metadataRequests.end(); i != eoi; ++i) { eoi = metadataRequests.end(); i != eoi; ++i) {
A2_LOG_DEBUG(fmt("Cancel metadata: piece=%lu", A2_LOG_DEBUG(fmt("Cancel metadata: piece=%lu",
static_cast<unsigned long>(*i))); static_cast<unsigned long>(*i)));
pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i)); pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i), cuid_);
} }
} }
} }
@ -524,7 +525,7 @@ void DefaultBtInteractive::doInteractionProcessing() {
utMetadataRequestTracker_->removeTimeoutEntry(); utMetadataRequestTracker_->removeTimeoutEntry();
for(std::vector<size_t>::const_iterator i = indexes.begin(), for(std::vector<size_t>::const_iterator i = indexes.begin(),
eoi = indexes.end(); i != eoi; ++i) { eoi = indexes.end(); i != eoi; ++i) {
pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i)); pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i), cuid_);
} }
} }
if(pieceStorage_->downloadFinished()) { if(pieceStorage_->downloadFinished()) {

View File

@ -53,7 +53,8 @@ namespace aria2 {
DefaultBtRequestFactory::DefaultBtRequestFactory() DefaultBtRequestFactory::DefaultBtRequestFactory()
: dispatcher_(0), : dispatcher_(0),
messageFactory_(0) messageFactory_(0),
cuid_(0)
{} {}
DefaultBtRequestFactory::~DefaultBtRequestFactory() {} DefaultBtRequestFactory::~DefaultBtRequestFactory() {}
@ -96,7 +97,7 @@ void DefaultBtRequestFactory::removeTargetPiece
derefEqual(piece)), derefEqual(piece)),
pieces_.end()); pieces_.end());
dispatcher_->doAbortOutstandingRequestAction(piece); dispatcher_->doAbortOutstandingRequestAction(piece);
pieceStorage_->cancelPiece(piece); pieceStorage_->cancelPiece(piece, cuid_);
} }
namespace { namespace {
@ -104,16 +105,20 @@ class ProcessChokedPiece {
private: private:
SharedHandle<Peer> peer_; SharedHandle<Peer> peer_;
SharedHandle<PieceStorage> pieceStorage_; SharedHandle<PieceStorage> pieceStorage_;
cuid_t cuid_;
public: public:
ProcessChokedPiece(const SharedHandle<Peer>& peer, ProcessChokedPiece(const SharedHandle<Peer>& peer,
const SharedHandle<PieceStorage>& pieceStorage): const SharedHandle<PieceStorage>& pieceStorage,
cuid_t cuid):
peer_(peer), peer_(peer),
pieceStorage_(pieceStorage) {} pieceStorage_(pieceStorage),
cuid_(cuid)
{}
void operator()(const SharedHandle<Piece>& piece) void operator()(const SharedHandle<Piece>& piece)
{ {
if(!peer_->isInPeerAllowedIndexSet(piece->getIndex())) { if(!peer_->isInPeerAllowedIndexSet(piece->getIndex())) {
pieceStorage_->cancelPiece(piece); pieceStorage_->cancelPiece(piece, cuid_);
} }
} }
}; };
@ -136,7 +141,7 @@ public:
void DefaultBtRequestFactory::doChokedAction() void DefaultBtRequestFactory::doChokedAction()
{ {
std::for_each(pieces_.begin(), pieces_.end(), std::for_each(pieces_.begin(), pieces_.end(),
ProcessChokedPiece(peer_, pieceStorage_)); ProcessChokedPiece(peer_, pieceStorage_, cuid_));
pieces_.erase(std::remove_if(pieces_.begin(), pieces_.end(), pieces_.erase(std::remove_if(pieces_.begin(), pieces_.end(),
FindChokedPiece(peer_)), FindChokedPiece(peer_)),
pieces_.end()); pieces_.end());
@ -146,7 +151,7 @@ void DefaultBtRequestFactory::removeAllTargetPiece() {
for(std::deque<SharedHandle<Piece> >::iterator itr = pieces_.begin(), for(std::deque<SharedHandle<Piece> >::iterator itr = pieces_.begin(),
eoi = pieces_.end(); itr != eoi; ++itr) { eoi = pieces_.end(); itr != eoi; ++itr) {
dispatcher_->doAbortOutstandingRequestAction(*itr); dispatcher_->doAbortOutstandingRequestAction(*itr);
pieceStorage_->cancelPiece(*itr); pieceStorage_->cancelPiece(*itr, cuid_);
} }
pieces_.clear(); pieces_.clear();
} }

View File

@ -56,6 +56,7 @@ private:
BtMessageDispatcher* dispatcher_; BtMessageDispatcher* dispatcher_;
BtMessageFactory* messageFactory_; BtMessageFactory* messageFactory_;
std::deque<SharedHandle<Piece> > pieces_; std::deque<SharedHandle<Piece> > pieces_;
cuid_t cuid_;
public: public:
DefaultBtRequestFactory(); DefaultBtRequestFactory();
@ -97,6 +98,11 @@ public:
void setBtMessageDispatcher(BtMessageDispatcher* dispatcher); void setBtMessageDispatcher(BtMessageDispatcher* dispatcher);
void setBtMessageFactory(BtMessageFactory* factory); void setBtMessageFactory(BtMessageFactory* factory);
void setCuid(cuid_t cuid)
{
cuid_ = cuid;
}
}; };
typedef SharedHandle<DefaultBtRequestFactory> DefaultBtRequestFactoryHandle; typedef SharedHandle<DefaultBtRequestFactory> DefaultBtRequestFactoryHandle;

View File

@ -96,14 +96,14 @@ DefaultPieceStorage::~DefaultPieceStorage()
delete bitfieldMan_; delete bitfieldMan_;
} }
SharedHandle<Piece> DefaultPieceStorage::checkOutPiece(size_t index) SharedHandle<Piece> DefaultPieceStorage::checkOutPiece
(size_t index, cuid_t cuid)
{ {
bitfieldMan_->setUseBit(index); bitfieldMan_->setUseBit(index);
SharedHandle<Piece> piece = findUsedPiece(index); SharedHandle<Piece> piece = findUsedPiece(index);
if(!piece) { if(!piece) {
piece.reset(new Piece(index, bitfieldMan_->getBlockLength(index))); piece.reset(new Piece(index, bitfieldMan_->getBlockLength(index)));
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
piece->setHashAlgo(downloadContext_->getPieceHashAlgo()); piece->setHashAlgo(downloadContext_->getPieceHashAlgo());
@ -111,10 +111,9 @@ SharedHandle<Piece> DefaultPieceStorage::checkOutPiece(size_t index)
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
addUsedPiece(piece); addUsedPiece(piece);
return piece;
} else {
return piece;
} }
piece->addUser(cuid);
return piece;
} }
/** /**
@ -174,7 +173,8 @@ void DefaultPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const unsigned char* bitfield, const unsigned char* bitfield,
size_t length) size_t length,
cuid_t cuid)
{ {
const size_t mislen = bitfieldMan_->getBitfieldLength(); const size_t mislen = bitfieldMan_->getBitfieldLength();
array_ptr<unsigned char> misbitfield(new unsigned char[mislen]); array_ptr<unsigned char> misbitfield(new unsigned char[mislen]);
@ -195,8 +195,14 @@ void DefaultPieceStorage::getMissingPiece
std::random_shuffle(indexes.begin(), indexes.end()); std::random_shuffle(indexes.begin(), indexes.end());
for(std::vector<size_t>::const_iterator i = indexes.begin(), for(std::vector<size_t>::const_iterator i = indexes.begin(),
eoi = indexes.end(); i != eoi && misBlock < minMissingBlocks; ++i) { eoi = indexes.end(); i != eoi && misBlock < minMissingBlocks; ++i) {
pieces.push_back(checkOutPiece(*i)); SharedHandle<Piece> piece = checkOutPiece(*i, cuid);
misBlock += pieces.back()->countMissingBlock(); if(piece->getUsedBySegment()) {
// We don't share piece downloaded via HTTP/FTP
piece->removeUser(cuid);
} else {
pieces.push_back(piece);
misBlock += piece->countMissingBlock();
}
} }
} else { } else {
bool r = bitfieldMan_->getAllMissingUnusedIndexes bool r = bitfieldMan_->getAllMissingUnusedIndexes
@ -207,7 +213,7 @@ void DefaultPieceStorage::getMissingPiece
while(misBlock < minMissingBlocks) { while(misBlock < minMissingBlocks) {
size_t index; size_t index;
if(pieceSelector_->select(index, misbitfield, blocks)) { if(pieceSelector_->select(index, misbitfield, blocks)) {
pieces.push_back(checkOutPiece(index)); pieces.push_back(checkOutPiece(index, cuid));
bitfield::flipBit(misbitfield, blocks, index); bitfield::flipBit(misbitfield, blocks, index);
misBlock += pieces.back()->countMissingBlock(); misBlock += pieces.back()->countMissingBlock();
} else { } else {
@ -241,10 +247,12 @@ void DefaultPieceStorage::createFastIndexBitfield
void DefaultPieceStorage::getMissingPiece void DefaultPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer) const SharedHandle<Peer>& peer,
cuid_t cuid)
{ {
getMissingPiece(pieces, minMissingBlocks, getMissingPiece(pieces, minMissingBlocks,
peer->getBitfield(), peer->getBitfieldLength()); peer->getBitfield(), peer->getBitfieldLength(),
cuid);
} }
@ -252,20 +260,23 @@ void DefaultPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) const std::vector<size_t>& excludedIndexes,
cuid_t cuid)
{ {
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);
getMissingPiece(pieces, minMissingBlocks, getMissingPiece(pieces, minMissingBlocks,
tempBitfield.getBitfield(), tempBitfield.getBitfieldLength()); tempBitfield.getBitfield(), tempBitfield.getBitfieldLength(),
cuid);
} }
void DefaultPieceStorage::getMissingFastPiece void DefaultPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer) const SharedHandle<Peer>& peer,
cuid_t cuid)
{ {
if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) { if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) {
BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(),
@ -273,7 +284,8 @@ void DefaultPieceStorage::getMissingFastPiece
createFastIndexBitfield(tempBitfield, peer); createFastIndexBitfield(tempBitfield, peer);
getMissingPiece(pieces, minMissingBlocks, getMissingPiece(pieces, minMissingBlocks,
tempBitfield.getBitfield(), tempBitfield.getBitfield(),
tempBitfield.getBitfieldLength()); tempBitfield.getBitfieldLength(),
cuid);
} }
} }
@ -281,7 +293,8 @@ void DefaultPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) const std::vector<size_t>& excludedIndexes,
cuid_t cuid)
{ {
if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) { if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) {
BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(),
@ -290,15 +303,18 @@ void DefaultPieceStorage::getMissingFastPiece
unsetExcludedIndexes(tempBitfield, excludedIndexes); unsetExcludedIndexes(tempBitfield, excludedIndexes);
getMissingPiece(pieces, minMissingBlocks, getMissingPiece(pieces, minMissingBlocks,
tempBitfield.getBitfield(), tempBitfield.getBitfield(),
tempBitfield.getBitfieldLength()); tempBitfield.getBitfieldLength(),
cuid);
} }
} }
SharedHandle<Piece> SharedHandle<Piece>
DefaultPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer) DefaultPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer,
cuid_t cuid)
{ {
std::vector<SharedHandle<Piece> > pieces; std::vector<SharedHandle<Piece> > pieces;
getMissingPiece(pieces, 1, peer); getMissingPiece(pieces, 1, peer, cuid);
if(pieces.empty()) { if(pieces.empty()) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} else { } else {
@ -307,10 +323,12 @@ DefaultPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer)
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes) (const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes,
cuid_t cuid)
{ {
std::vector<SharedHandle<Piece> > pieces; std::vector<SharedHandle<Piece> > pieces;
getMissingPiece(pieces, 1, peer, excludedIndexes); getMissingPiece(pieces, 1, peer, excludedIndexes, cuid);
if(pieces.empty()) { if(pieces.empty()) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} else { } else {
@ -319,10 +337,11 @@ SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer) (const SharedHandle<Peer>& peer,
cuid_t cuid)
{ {
std::vector<SharedHandle<Piece> > pieces; std::vector<SharedHandle<Piece> > pieces;
getMissingFastPiece(pieces, 1, peer); getMissingFastPiece(pieces, 1, peer, cuid);
if(pieces.empty()) { if(pieces.empty()) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} else { } else {
@ -331,10 +350,12 @@ SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes) (const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes,
cuid_t cuid)
{ {
std::vector<SharedHandle<Piece> > pieces; std::vector<SharedHandle<Piece> > pieces;
getMissingFastPiece(pieces, 1, peer, excludedIndexes); getMissingFastPiece(pieces, 1, peer, excludedIndexes, cuid);
if(pieces.empty()) { if(pieces.empty()) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} else { } else {
@ -351,23 +372,28 @@ bool DefaultPieceStorage::hasMissingUnusedPiece()
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(size_t minSplitSize, const unsigned char* ignoreBitfield, size_t length) (size_t minSplitSize,
const unsigned char* ignoreBitfield,
size_t length,
cuid_t cuid)
{ {
size_t index; size_t index;
if(streamPieceSelector_->select if(streamPieceSelector_->select
(index, minSplitSize, ignoreBitfield, length)) { (index, minSplitSize, ignoreBitfield, length)) {
return checkOutPiece(index); return checkOutPiece(index, cuid);
} else { } else {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} }
} }
SharedHandle<Piece> DefaultPieceStorage::getMissingPiece(size_t index) SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
(size_t index,
cuid_t cuid)
{ {
if(hasPiece(index) || isPieceUsed(index)) { if(hasPiece(index) || isPieceUsed(index)) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} else { } else {
return checkOutPiece(index); return checkOutPiece(index, cuid);
} }
} }
@ -464,12 +490,16 @@ bool DefaultPieceStorage::isSelectiveDownloadingMode()
} }
// not unittested // not unittested
void DefaultPieceStorage::cancelPiece(const SharedHandle<Piece>& piece) void DefaultPieceStorage::cancelPiece
(const SharedHandle<Piece>& piece, cuid_t cuid)
{ {
if(!piece) { if(!piece) {
return; return;
} }
bitfieldMan_->unsetUseBit(piece->getIndex()); piece->removeUser(cuid);
if(!piece->getUsed()) {
bitfieldMan_->unsetUseBit(piece->getIndex());
}
if(!isEndGame()) { if(!isEndGame()) {
if(piece->getCompletedLength() == 0) { if(piece->getCompletedLength() == 0) {
deleteUsedPiece(piece); deleteUsedPiece(piece);

View File

@ -92,13 +92,14 @@ private:
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const unsigned char* bitfield, const unsigned char* bitfield,
size_t length); size_t length,
cuid_t cuid);
void createFastIndexBitfield(BitfieldMan& bitfield, void createFastIndexBitfield(BitfieldMan& bitfield,
const SharedHandle<Peer>& peer); const SharedHandle<Peer>& peer);
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
SharedHandle<Piece> checkOutPiece(size_t index); SharedHandle<Piece> checkOutPiece(size_t index, cuid_t cuid);
// 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);
void deleteUsedPiece(const SharedHandle<Piece>& piece); void deleteUsedPiece(const SharedHandle<Piece>& piece);
@ -123,50 +124,64 @@ public:
virtual void getMissingPiece virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer); const SharedHandle<Peer>& peer,
cuid_t cuid);
virtual void getMissingPiece virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes); const std::vector<size_t>& excludedIndexes,
cuid_t cuid);
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
virtual void getMissingFastPiece virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes); cuid_t cuid);
virtual SharedHandle<Piece> getMissingPiece(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,
cuid_t cuid);
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer,
cuid_t cuid);
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,
cuid_t cuid);
SharedHandle<Piece> getMissingFastPiece SharedHandle<Piece> getMissingFastPiece
(const SharedHandle<Peer>& peer); (const SharedHandle<Peer>& peer,
cuid_t cuid);
SharedHandle<Piece> getMissingFastPiece SharedHandle<Piece> getMissingFastPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes); (const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes,
cuid_t cuid);
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
virtual bool hasMissingUnusedPiece(); virtual bool hasMissingUnusedPiece();
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(size_t minSplitSize, const unsigned char* ignoreBitfield, size_t length); (size_t minSplitSize,
const unsigned char* ignoreBitfield,
size_t length,
cuid_t cuid);
virtual SharedHandle<Piece> getMissingPiece(size_t index); virtual SharedHandle<Piece> getMissingPiece(size_t index, cuid_t cuid);
virtual SharedHandle<Piece> getPiece(size_t index); virtual SharedHandle<Piece> getPiece(size_t index);
virtual void completePiece(const SharedHandle<Piece>& piece); virtual void completePiece(const SharedHandle<Piece>& piece);
virtual void cancelPiece(const SharedHandle<Piece>& piece); virtual void cancelPiece(const SharedHandle<Piece>& piece, cuid_t cuid);
virtual bool hasPiece(size_t index); virtual bool hasPiece(size_t index);

View File

@ -194,6 +194,7 @@ PeerInteractionCommand::PeerInteractionCommand
reqFactory->setPieceStorage(pieceStorage); reqFactory->setPieceStorage(pieceStorage);
reqFactory->setBtMessageDispatcher(dispatcher.get()); reqFactory->setBtMessageDispatcher(dispatcher.get());
reqFactory->setBtMessageFactory(factory.get()); reqFactory->setBtMessageFactory(factory.get());
reqFactory->setCuid(cuid);
DefaultBtInteractiveHandle btInteractive DefaultBtInteractiveHandle btInteractive
(new DefaultBtInteractive(requestGroup_->getDownloadContext(), getPeer())); (new DefaultBtInteractive(requestGroup_->getDownloadContext(), getPeer()));
@ -248,6 +249,7 @@ PeerInteractionCommand::PeerInteractionCommand
extensionMessageFactory->setBtMessageFactory(factory.get()); extensionMessageFactory->setBtMessageFactory(factory.get());
if(metadataGetMode) { if(metadataGetMode) {
utMetadataRequestFactory->setCuid(cuid);
utMetadataRequestFactory->setDownloadContext utMetadataRequestFactory->setDownloadContext
(requestGroup_->getDownloadContext()); (requestGroup_->getDownloadContext());
utMetadataRequestFactory->setBtMessageDispatcher(dispatcher.get()); utMetadataRequestFactory->setBtMessageDispatcher(dispatcher.get());

View File

@ -44,7 +44,8 @@
namespace aria2 { namespace aria2 {
Piece::Piece():index_(0), length_(0), blockLength_(BLOCK_LENGTH), bitfield_(0) Piece::Piece():index_(0), length_(0), blockLength_(BLOCK_LENGTH), bitfield_(0),
usedBySegment_(false)
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
, nextBegin_(0) , nextBegin_(0)
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
@ -52,9 +53,10 @@ Piece::Piece():index_(0), length_(0), blockLength_(BLOCK_LENGTH), bitfield_(0)
Piece::Piece(size_t index, size_t length, size_t blockLength): Piece::Piece(size_t index, size_t length, size_t blockLength):
index_(index), length_(length), blockLength_(blockLength), index_(index), length_(length), blockLength_(blockLength),
bitfield_(new BitfieldMan(blockLength_, length)) bitfield_(new BitfieldMan(blockLength_, length)),
usedBySegment_(false)
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
, nextBegin_(0) , nextBegin_(0)
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
{} {}
@ -235,4 +237,21 @@ void Piece::destroyHashContext()
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
bool Piece::usedBy(cuid_t cuid) const
{
return std::find(users_.begin(), users_.end(), cuid) != users_.end();
}
void Piece::addUser(cuid_t cuid)
{
if(std::find(users_.begin(), users_.end(), cuid) == users_.end()) {
users_.push_back(cuid);
}
}
void Piece::removeUser(cuid_t cuid)
{
users_.erase(std::remove(users_.begin(), users_.end(), cuid), users_.end());
}
} // namespace aria2 } // namespace aria2

View File

@ -42,6 +42,7 @@
#include <string> #include <string>
#include "SharedHandle.h" #include "SharedHandle.h"
#include "Command.h"
namespace aria2 { namespace aria2 {
@ -59,7 +60,8 @@ private:
size_t length_; size_t length_;
size_t blockLength_; size_t blockLength_;
BitfieldMan* bitfield_; BitfieldMan* bitfield_;
std::vector<cuid_t> users_;
bool usedBySegment_;
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
size_t nextBegin_; size_t nextBegin_;
@ -176,6 +178,22 @@ public:
* Loses current bitfield state. * Loses current bitfield state.
*/ */
void reconfigure(size_t length); void reconfigure(size_t length);
void addUser(cuid_t cuid);
void removeUser(cuid_t cuid);
bool getUsed() const
{
return !users_.empty();
}
bool usedBy(cuid_t cuid) const;
bool getUsedBySegment() const
{
return usedBySegment_;
}
void setUsedBySegment(bool f)
{
usedBySegment_ = f;
}
}; };
} // namespace aria2 } // namespace aria2

View File

@ -74,7 +74,8 @@ public:
virtual void getMissingPiece virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer) = 0; const SharedHandle<Peer>& peer,
cuid_t cuid) = 0;
// Same as getMissingPiece(pieces, minMissingBlocks, peer), but the // Same as getMissingPiece(pieces, minMissingBlocks, peer), but the
// indexes in excludedIndexes are excluded. // indexes in excludedIndexes are excluded.
@ -82,7 +83,8 @@ public:
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) = 0; const std::vector<size_t>& excludedIndexes,
cuid_t cuid) = 0;
// Stores pieces that the peer has but localhost doesn't. Only // Stores pieces that the peer has but localhost doesn't. Only
// pieces that declared as "fast" are stored. Those pieces stored // pieces that declared as "fast" are stored. Those pieces stored
@ -96,7 +98,8 @@ public:
virtual void getMissingFastPiece virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer) = 0; const SharedHandle<Peer>& peer,
cuid_t cuid) = 0;
// Same as getMissingFastPiece(pieces, minMissingBlocks, peer), but // Same as getMissingFastPiece(pieces, minMissingBlocks, peer), but
// the indexes in excludedIndexes are excluded. // the indexes in excludedIndexes are excluded.
@ -104,7 +107,8 @@ public:
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) = 0; const std::vector<size_t>& excludedIndexes,
cuid_t cuid) = 0;
/** /**
* Returns a piece that the peer has but localhost doesn't. * Returns a piece that the peer has but localhost doesn't.
@ -113,7 +117,7 @@ public:
* to several commands. * to several commands.
*/ */
virtual SharedHandle<Piece> virtual SharedHandle<Piece>
getMissingPiece(const SharedHandle<Peer>& peer) = 0; getMissingPiece(const SharedHandle<Peer>& peer, cuid_t cuid) = 0;
/** /**
* Same as getMissingPiece(const SharedHandle<Peer>& peer), but the indexes in * Same as getMissingPiece(const SharedHandle<Peer>& peer), but the indexes in
@ -121,7 +125,8 @@ public:
*/ */
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer, (const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) = 0; const std::vector<size_t>& excludedIndexes,
cuid_t cuid) = 0;
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
// Returns true if there is at least one missing and unused piece. // Returns true if there is at least one missing and unused piece.
@ -132,7 +137,10 @@ public:
* If ignoreBitfield is set, indexes of true bit are excluded. * If ignoreBitfield is set, indexes of true bit are excluded.
*/ */
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(size_t minSplitSize, const unsigned char* ignoreBitfield, size_t length) = 0; (size_t minSplitSize,
const unsigned char* ignoreBitfield,
size_t length,
cuid_t cuid) = 0;
/** /**
* Returns a missing piece whose index is index. * Returns a missing piece whose index is index.
@ -140,7 +148,7 @@ public:
* then returns 0. * then returns 0.
* Also returns 0 if any of missing piece is not available. * Also returns 0 if any of missing piece is not available.
*/ */
virtual SharedHandle<Piece> getMissingPiece(size_t index) = 0; virtual SharedHandle<Piece> getMissingPiece(size_t index, cuid_t cuid) = 0;
/** /**
* Returns the piece denoted by index. * Returns the piece denoted by index.
@ -161,7 +169,7 @@ public:
/** /**
* Tells that the download of the specified piece is canceled. * Tells that the download of the specified piece is canceled.
*/ */
virtual void cancelPiece(const SharedHandle<Piece>& piece) = 0; virtual void cancelPiece(const SharedHandle<Piece>& piece, cuid_t cuid) = 0;
/** /**
* Returns true if the specified piece is already downloaded. * Returns true if the specified piece is already downloaded.

View File

@ -123,6 +123,7 @@ SharedHandle<Segment> SegmentMan::checkoutSegment
A2_LOG_DEBUG(fmt("Attach segment#%lu to CUID#%lld.", A2_LOG_DEBUG(fmt("Attach segment#%lu to CUID#%lld.",
static_cast<unsigned long>(piece->getIndex()), static_cast<unsigned long>(piece->getIndex()),
cuid)); cuid));
piece->setUsedBySegment(true);
SharedHandle<Segment> segment; SharedHandle<Segment> segment;
if(piece->getLength() == 0) { if(piece->getLength() == 0) {
segment.reset(new GrowSegment(piece)); segment.reset(new GrowSegment(piece));
@ -175,7 +176,8 @@ SharedHandle<Segment> SegmentMan::getSegment(cuid_t cuid, size_t minSplitSize)
SharedHandle<Piece> piece = SharedHandle<Piece> piece =
pieceStorage_->getMissingPiece pieceStorage_->getMissingPiece
(minSplitSize, (minSplitSize,
ignoreBitfield_.getFilterBitfield(), ignoreBitfield_.getBitfieldLength()); ignoreBitfield_.getFilterBitfield(), ignoreBitfield_.getBitfieldLength(),
cuid);
return checkoutSegment(cuid, piece); return checkoutSegment(cuid, piece);
} }
@ -195,7 +197,8 @@ void SegmentMan::getSegment
checkoutSegment(cuid, checkoutSegment(cuid,
pieceStorage_->getMissingPiece pieceStorage_->getMissingPiece
(minSplitSize, (minSplitSize,
filter.getFilterBitfield(), filter.getBitfieldLength())); filter.getFilterBitfield(), filter.getBitfieldLength(),
cuid));
if(!segment) { if(!segment) {
break; break;
} }
@ -217,7 +220,7 @@ SharedHandle<Segment> SegmentMan::getSegmentWithIndex
if(index > 0 && downloadContext_->getNumPieces() <= index) { if(index > 0 && downloadContext_->getNumPieces() <= index) {
return SharedHandle<Segment>(); return SharedHandle<Segment>();
} }
return checkoutSegment(cuid, pieceStorage_->getMissingPiece(index)); return checkoutSegment(cuid, pieceStorage_->getMissingPiece(index, cuid));
} }
SharedHandle<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle SharedHandle<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle
@ -249,11 +252,14 @@ SharedHandle<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle
return SharedHandle<Segment>(); return SharedHandle<Segment>();
} }
void SegmentMan::cancelSegment(const SharedHandle<Segment>& segment) void SegmentMan::cancelSegmentInternal
(cuid_t cuid,
const SharedHandle<Segment>& segment)
{ {
A2_LOG_DEBUG(fmt("Canceling segment#%lu", A2_LOG_DEBUG(fmt("Canceling segment#%lu",
static_cast<unsigned long>(segment->getIndex()))); static_cast<unsigned long>(segment->getIndex())));
pieceStorage_->cancelPiece(segment->getPiece()); segment->getPiece()->setUsedBySegment(false);
pieceStorage_->cancelPiece(segment->getPiece(), cuid);
segmentWrittenLengthMemo_[segment->getIndex()] = segment->getWrittenLength(); segmentWrittenLengthMemo_[segment->getIndex()] = segment->getWrittenLength();
A2_LOG_DEBUG(fmt("Memorized segment index=%lu, writtenLength=%lu", A2_LOG_DEBUG(fmt("Memorized segment index=%lu, writtenLength=%lu",
static_cast<unsigned long>(segment->getIndex()), static_cast<unsigned long>(segment->getIndex()),
@ -264,7 +270,7 @@ void SegmentMan::cancelSegment(cuid_t cuid) {
for(SegmentEntries::iterator itr = usedSegmentEntries_.begin(), for(SegmentEntries::iterator itr = usedSegmentEntries_.begin(),
eoi = usedSegmentEntries_.end(); itr != eoi;) { eoi = usedSegmentEntries_.end(); itr != eoi;) {
if((*itr)->cuid == cuid) { if((*itr)->cuid == cuid) {
cancelSegment((*itr)->segment); cancelSegmentInternal(cuid, (*itr)->segment);
itr = usedSegmentEntries_.erase(itr); itr = usedSegmentEntries_.erase(itr);
eoi = usedSegmentEntries_.end(); eoi = usedSegmentEntries_.end();
} else { } else {
@ -279,9 +285,8 @@ void SegmentMan::cancelSegment
for(SegmentEntries::iterator itr = usedSegmentEntries_.begin(), for(SegmentEntries::iterator itr = usedSegmentEntries_.begin(),
eoi = usedSegmentEntries_.end(); itr != eoi;) { eoi = usedSegmentEntries_.end(); itr != eoi;) {
if((*itr)->cuid == cuid && *(*itr)->segment == *segment) { if((*itr)->cuid == cuid && *(*itr)->segment == *segment) {
cancelSegment((*itr)->segment); cancelSegmentInternal(cuid, (*itr)->segment);
itr = usedSegmentEntries_.erase(itr); itr = usedSegmentEntries_.erase(itr);
//eoi = usedSegmentEntries_.end();
break; break;
} else { } else {
++itr; ++itr;
@ -294,7 +299,7 @@ void SegmentMan::cancelAllSegments()
for(std::deque<SharedHandle<SegmentEntry> >::iterator itr = for(std::deque<SharedHandle<SegmentEntry> >::iterator itr =
usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end(); usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end();
itr != eoi; ++itr) { itr != eoi; ++itr) {
cancelSegment((*itr)->segment); cancelSegmentInternal((*itr)->cuid, (*itr)->segment);
} }
usedSegmentEntries_.clear(); usedSegmentEntries_.clear();
} }

View File

@ -106,7 +106,7 @@ private:
SharedHandle<Segment> checkoutSegment(cuid_t cuid, SharedHandle<Segment> checkoutSegment(cuid_t cuid,
const SharedHandle<Piece>& piece); const SharedHandle<Piece>& piece);
void cancelSegment(const SharedHandle<Segment>& segment); void cancelSegmentInternal(cuid_t cuid, const SharedHandle<Segment>& segment);
public: public:
SegmentMan(const Option* option, SegmentMan(const Option* option,
const SharedHandle<DownloadContext>& downloadContext, const SharedHandle<DownloadContext>& downloadContext,

View File

@ -50,7 +50,8 @@ namespace aria2 {
UTMetadataRequestFactory::UTMetadataRequestFactory() UTMetadataRequestFactory::UTMetadataRequestFactory()
: dispatcher_(0), : dispatcher_(0),
messageFactory_(0), messageFactory_(0),
tracker_(0) tracker_(0),
cuid_(0)
{} {}
void UTMetadataRequestFactory::create void UTMetadataRequestFactory::create
@ -60,7 +61,7 @@ void UTMetadataRequestFactory::create
while(num) { while(num) {
std::vector<size_t> metadataRequests = tracker_->getAllTrackedIndex(); std::vector<size_t> metadataRequests = tracker_->getAllTrackedIndex();
SharedHandle<Piece> p = SharedHandle<Piece> p =
pieceStorage->getMissingPiece(peer_, metadataRequests); pieceStorage->getMissingPiece(peer_, metadataRequests, cuid_);
if(!p) { if(!p) {
A2_LOG_DEBUG("No ut_metadata piece is available to download."); A2_LOG_DEBUG("No ut_metadata piece is available to download.");
break; break;

View File

@ -40,6 +40,7 @@
#include <vector> #include <vector>
#include "SharedHandle.h" #include "SharedHandle.h"
#include "Command.h"
namespace aria2 { namespace aria2 {
@ -62,6 +63,7 @@ private:
BtMessageFactory* messageFactory_; BtMessageFactory* messageFactory_;
UTMetadataRequestTracker* tracker_; UTMetadataRequestTracker* tracker_;
cuid_t cuid_;
public: public:
UTMetadataRequestFactory(); UTMetadataRequestFactory();
@ -94,6 +96,11 @@ public:
{ {
tracker_ = tracker; tracker_ = tracker;
} }
void setCuid(cuid_t cuid)
{
cuid_ = cuid;
}
}; };
} // namespace aria2 } // namespace aria2

View File

@ -81,7 +81,8 @@ bool UnknownLengthPieceStorage::hasMissingPiece(const SharedHandle<Peer>& peer)
void UnknownLengthPieceStorage::getMissingPiece void UnknownLengthPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer) const SharedHandle<Peer>& peer,
cuid_t cuid)
{ {
abort(); abort();
} }
@ -90,15 +91,8 @@ void UnknownLengthPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) const std::vector<size_t>& excludedIndexes,
{ cuid_t cuid)
abort();
}
void UnknownLengthPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{ {
abort(); abort();
} }
@ -107,18 +101,32 @@ void UnknownLengthPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) cuid_t cuid)
{ {
abort(); abort();
} }
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer) void UnknownLengthPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes,
cuid_t cuid)
{ {
abort(); abort();
} }
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes) (const SharedHandle<Peer>& peer,
cuid_t cuid)
{
abort();
}
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes,
cuid_t cuid)
{ {
abort(); abort();
} }
@ -130,7 +138,10 @@ bool UnknownLengthPieceStorage::hasMissingUnusedPiece()
} }
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece
(size_t minSplitSize, const unsigned char* ignoreBitfield, size_t length) (size_t minSplitSize,
const unsigned char* ignoreBitfield,
size_t length,
cuid_t cuid)
{ {
if(downloadFinished_) { if(downloadFinished_) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
@ -143,10 +154,12 @@ SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece
} }
} }
SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece(size_t index) SharedHandle<Piece> UnknownLengthPieceStorage::getMissingPiece
(size_t index,
cuid_t cuid)
{ {
if(index == 0) { if(index == 0) {
return getMissingPiece(0, 0, 0); return getMissingPiece(0, 0, 0, cuid);
} else { } else {
return SharedHandle<Piece>(); return SharedHandle<Piece>();
} }
@ -175,7 +188,9 @@ void UnknownLengthPieceStorage::completePiece(const SharedHandle<Piece>& piece)
} }
} }
void UnknownLengthPieceStorage::cancelPiece(const SharedHandle<Piece>& piece) void UnknownLengthPieceStorage::cancelPiece
(const SharedHandle<Piece>& piece,
cuid_t cuid)
{ {
if(*piece_ == *piece) { if(*piece_ == *piece) {
piece_.reset(); piece_.reset();

View File

@ -76,29 +76,37 @@ public:
virtual void getMissingPiece virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer); const SharedHandle<Peer>& peer,
cuid_t cuid);
virtual void getMissingPiece virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes); const std::vector<size_t>& excludedIndexes,
cuid_t cuid);
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
virtual void getMissingFastPiece virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes); cuid_t cuid);
virtual SharedHandle<Piece> getMissingPiece(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,
cuid_t cuid);
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer, const std::vector<size_t>& excludedIndexes); (const SharedHandle<Peer>& peer,
cuid_t cuid);
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes,
cuid_t cuid);
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
virtual bool hasMissingUnusedPiece(); virtual bool hasMissingUnusedPiece();
@ -107,7 +115,10 @@ public:
* Returns a missing piece if available. Otherwise returns 0; * Returns a missing piece if available. Otherwise returns 0;
*/ */
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(size_t minSplitSize, const unsigned char* ignoreBitfield, size_t length); (size_t minSplitSize,
const unsigned char* ignoreBitfield,
size_t length,
cuid_t cuid);
/** /**
* Returns a missing piece whose index is index. * Returns a missing piece whose index is index.
@ -115,7 +126,7 @@ public:
* then returns 0. * then returns 0.
* Also returns 0 if any of missing piece is not available. * Also returns 0 if any of missing piece is not available.
*/ */
virtual SharedHandle<Piece> getMissingPiece(size_t index); virtual SharedHandle<Piece> getMissingPiece(size_t index, cuid_t cuid);
/** /**
* Returns the piece denoted by index. * Returns the piece denoted by index.
@ -131,7 +142,7 @@ public:
/** /**
* Tells that the download of the specified piece is canceled. * Tells that the download of the specified piece is canceled.
*/ */
virtual void cancelPiece(const SharedHandle<Piece>& piece); virtual void cancelPiece(const SharedHandle<Piece>& piece, cuid_t cuid);
/** /**
* Returns true if the specified piece is already downloaded. * Returns true if the specified piece is already downloaded.

View File

@ -88,16 +88,17 @@ void DefaultPieceStorageTest::testGetMissingPiece() {
pss.setPieceSelector(pieceSelector_); pss.setPieceSelector(pieceSelector_);
peer->setAllBitfield(); peer->setAllBitfield();
SharedHandle<Piece> piece = pss.getMissingPiece(peer); SharedHandle<Piece> piece = pss.getMissingPiece(peer, 1);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
piece->toString()); piece->toString());
piece = pss.getMissingPiece(peer); CPPUNIT_ASSERT(piece->usedBy(1));
piece = pss.getMissingPiece(peer, 1);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"),
piece->toString()); piece->toString());
piece = pss.getMissingPiece(peer); piece = pss.getMissingPiece(peer, 1);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
piece->toString()); piece->toString());
piece = pss.getMissingPiece(peer); piece = pss.getMissingPiece(peer, 1);
CPPUNIT_ASSERT(!piece); CPPUNIT_ASSERT(!piece);
} }
@ -106,14 +107,15 @@ void DefaultPieceStorageTest::testGetMissingPiece_many() {
pss.setPieceSelector(pieceSelector_); pss.setPieceSelector(pieceSelector_);
peer->setAllBitfield(); peer->setAllBitfield();
std::vector<SharedHandle<Piece> > pieces; std::vector<SharedHandle<Piece> > pieces;
pss.getMissingPiece(pieces, 2, peer); pss.getMissingPiece(pieces, 2, peer, 1);
CPPUNIT_ASSERT_EQUAL((size_t)2, pieces.size()); CPPUNIT_ASSERT_EQUAL((size_t)2, pieces.size());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
pieces[0]->toString()); pieces[0]->toString());
CPPUNIT_ASSERT(pieces[0]->usedBy(1));
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"),
pieces[1]->toString()); pieces[1]->toString());
pieces.clear(); pieces.clear();
pss.getMissingPiece(pieces, 2, peer); pss.getMissingPiece(pieces, 2, peer, 1);
CPPUNIT_ASSERT_EQUAL((size_t)1, pieces.size()); CPPUNIT_ASSERT_EQUAL((size_t)1, pieces.size());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
pieces[0]->toString()); pieces[0]->toString());
@ -130,15 +132,15 @@ void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes()
std::vector<size_t> excludedIndexes; std::vector<size_t> excludedIndexes;
excludedIndexes.push_back(1); excludedIndexes.push_back(1);
SharedHandle<Piece> piece = pss.getMissingPiece(peer, excludedIndexes); SharedHandle<Piece> piece = pss.getMissingPiece(peer, excludedIndexes, 1);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
piece->toString()); piece->toString());
piece = pss.getMissingPiece(peer, excludedIndexes); piece = pss.getMissingPiece(peer, excludedIndexes, 1);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
piece->toString()); piece->toString());
piece = pss.getMissingPiece(peer, excludedIndexes); piece = pss.getMissingPiece(peer, excludedIndexes, 1);
CPPUNIT_ASSERT(!piece); CPPUNIT_ASSERT(!piece);
} }
@ -149,14 +151,14 @@ void DefaultPieceStorageTest::testGetMissingPiece_manyWithExcludedIndexes() {
std::vector<size_t> excludedIndexes; std::vector<size_t> excludedIndexes;
excludedIndexes.push_back(1); excludedIndexes.push_back(1);
std::vector<SharedHandle<Piece> > pieces; std::vector<SharedHandle<Piece> > pieces;
pss.getMissingPiece(pieces, 2, peer, excludedIndexes); pss.getMissingPiece(pieces, 2, peer, excludedIndexes, 1);
CPPUNIT_ASSERT_EQUAL((size_t)2, pieces.size()); CPPUNIT_ASSERT_EQUAL((size_t)2, pieces.size());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
pieces[0]->toString()); pieces[0]->toString());
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"),
pieces[1]->toString()); pieces[1]->toString());
pieces.clear(); pieces.clear();
pss.getMissingPiece(pieces, 2, peer, excludedIndexes); pss.getMissingPiece(pieces, 2, peer, excludedIndexes, 1);
CPPUNIT_ASSERT(pieces.empty()); CPPUNIT_ASSERT(pieces.empty());
} }
@ -169,11 +171,11 @@ void DefaultPieceStorageTest::testGetMissingFastPiece() {
peer->setFastExtensionEnabled(true); peer->setFastExtensionEnabled(true);
peer->addPeerAllowedIndex(2); peer->addPeerAllowedIndex(2);
SharedHandle<Piece> piece = pss.getMissingFastPiece(peer); SharedHandle<Piece> piece = pss.getMissingFastPiece(peer, 1);
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)); CPPUNIT_ASSERT(!pss.getMissingFastPiece(peer, 1));
} }
void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes() void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes()
@ -190,11 +192,11 @@ void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes()
std::vector<size_t> excludedIndexes; std::vector<size_t> excludedIndexes;
excludedIndexes.push_back(2); excludedIndexes.push_back(2);
SharedHandle<Piece> piece = pss.getMissingFastPiece(peer, excludedIndexes); SharedHandle<Piece> piece = pss.getMissingFastPiece(peer, excludedIndexes, 1);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"),
piece->toString()); piece->toString());
CPPUNIT_ASSERT(!pss.getMissingFastPiece(peer, excludedIndexes)); CPPUNIT_ASSERT(!pss.getMissingFastPiece(peer, excludedIndexes, 1));
} }
void DefaultPieceStorageTest::testHasMissingPiece() { void DefaultPieceStorageTest::testHasMissingPiece() {
@ -214,7 +216,7 @@ void DefaultPieceStorageTest::testCompletePiece() {
peer->setAllBitfield(); peer->setAllBitfield();
SharedHandle<Piece> piece = pss.getMissingPiece(peer); SharedHandle<Piece> piece = pss.getMissingPiece(peer, 1);
CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"),
piece->toString()); piece->toString());
@ -224,7 +226,7 @@ void DefaultPieceStorageTest::testCompletePiece() {
CPPUNIT_ASSERT_EQUAL((uint64_t)128ULL, pss.getCompletedLength()); CPPUNIT_ASSERT_EQUAL((uint64_t)128ULL, pss.getCompletedLength());
SharedHandle<Piece> incompletePiece = pss.getMissingPiece(peer); SharedHandle<Piece> incompletePiece = pss.getMissingPiece(peer, 1);
incompletePiece->completeBlock(0); incompletePiece->completeBlock(0);
CPPUNIT_ASSERT_EQUAL((uint64_t)256ULL, pss.getCompletedLength()); CPPUNIT_ASSERT_EQUAL((uint64_t)256ULL, pss.getCompletedLength());
} }
@ -272,14 +274,16 @@ void DefaultPieceStorageTest::testCancelPiece()
SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, option_.get())); SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, option_.get()));
SharedHandle<Piece> p = ps->getMissingPiece(0); SharedHandle<Piece> p = ps->getMissingPiece(0, 1);
p->completeBlock(0); p->completeBlock(0);
ps->cancelPiece(p); ps->cancelPiece(p, 1);
SharedHandle<Piece> p2 = ps->getMissingPiece(0); SharedHandle<Piece> p2 = ps->getMissingPiece(0, 2);
CPPUNIT_ASSERT(p2->hasBlock(0)); CPPUNIT_ASSERT(p2->hasBlock(0));
CPPUNIT_ASSERT(p2->usedBy(2));
CPPUNIT_ASSERT(!p2->usedBy(1));
} }
void DefaultPieceStorageTest::testMarkPiecesDone() void DefaultPieceStorageTest::testMarkPiecesDone()
@ -345,11 +349,11 @@ void DefaultPieceStorageTest::testGetNextUsedIndex()
{ {
DefaultPieceStorage pss(dctx_, option_.get()); DefaultPieceStorage pss(dctx_, option_.get());
CPPUNIT_ASSERT_EQUAL((size_t)3, pss.getNextUsedIndex(0)); CPPUNIT_ASSERT_EQUAL((size_t)3, pss.getNextUsedIndex(0));
SharedHandle<Piece> piece = pss.getMissingPiece(2); SharedHandle<Piece> piece = pss.getMissingPiece(2, 1);
CPPUNIT_ASSERT_EQUAL((size_t)2, pss.getNextUsedIndex(0)); CPPUNIT_ASSERT_EQUAL((size_t)2, pss.getNextUsedIndex(0));
pss.completePiece(piece); pss.completePiece(piece);
CPPUNIT_ASSERT_EQUAL((size_t)2, pss.getNextUsedIndex(0)); CPPUNIT_ASSERT_EQUAL((size_t)2, pss.getNextUsedIndex(0));
piece = pss.getMissingPiece(0); piece = pss.getMissingPiece(0, 1);
CPPUNIT_ASSERT_EQUAL((size_t)2, pss.getNextUsedIndex(0)); CPPUNIT_ASSERT_EQUAL((size_t)2, pss.getNextUsedIndex(0));
} }

View File

@ -47,35 +47,44 @@ public:
virtual void getMissingPiece virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer) const SharedHandle<Peer>& peer,
cuid_t cuid)
{} {}
virtual void getMissingPiece virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) const std::vector<size_t>& excludedIndexes,
{} cuid_t cuid)
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
{} {}
virtual void getMissingFastPiece virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces, (std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks, size_t minMissingBlocks,
const SharedHandle<Peer>& peer, const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) cuid_t cuid)
{} {}
virtual SharedHandle<Piece> getMissingPiece(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,
cuid_t cuid)
{}
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer,
cuid_t cuid)
{
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());
} }
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,
cuid_t cuid)
{ {
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());
} }
@ -88,12 +97,15 @@ public:
} }
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(size_t minSplitSize, const unsigned char* ignoreBitfield, size_t length) (size_t minSplitSize,
const unsigned char* ignoreBitfield,
size_t length,
cuid_t cuid)
{ {
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());
} }
virtual SharedHandle<Piece> getMissingPiece(size_t index) virtual SharedHandle<Piece> getMissingPiece(size_t index, cuid_t cuid)
{ {
return SharedHandle<Piece>(new Piece()); return SharedHandle<Piece>(new Piece());
} }
@ -113,7 +125,7 @@ public:
virtual void completePiece(const SharedHandle<Piece>& piece) {} virtual void completePiece(const SharedHandle<Piece>& piece) {}
virtual void cancelPiece(const SharedHandle<Piece>& piece) {} virtual void cancelPiece(const SharedHandle<Piece>& piece, cuid_t cuid) {}
virtual bool hasPiece(size_t index) { virtual bool hasPiece(size_t index) {
return false; return false;

View File

@ -30,7 +30,8 @@ public:
virtual SharedHandle<Piece> getMissingPiece virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer, (const SharedHandle<Peer>& peer,
const std::vector<size_t>& exlucdedIndexes) const std::vector<size_t>& exlucdedIndexes,
cuid_t cuid)
{ {
if(missingIndexes.empty()) { if(missingIndexes.empty()) {
return SharedHandle<Piece>(); return SharedHandle<Piece>();