From 5c4a52ad741c66b4aa263a542da2c1e5546ca6bf Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 16 Jul 2011 00:58:41 +0900 Subject: [PATCH] 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). --- src/DefaultBtInteractive.cc | 13 ++-- src/DefaultBtRequestFactory.cc | 19 +++--- src/DefaultBtRequestFactory.h | 6 ++ src/DefaultPieceStorage.cc | 92 ++++++++++++++++++---------- src/DefaultPieceStorage.h | 49 ++++++++++----- src/PeerInteractionCommand.cc | 2 + src/Piece.cc | 25 +++++++- src/Piece.h | 20 +++++- src/PieceStorage.h | 26 +++++--- src/SegmentMan.cc | 23 ++++--- src/SegmentMan.h | 2 +- src/UTMetadataRequestFactory.cc | 5 +- src/UTMetadataRequestFactory.h | 7 +++ src/UnknownLengthPieceStorage.cc | 49 ++++++++++----- src/UnknownLengthPieceStorage.h | 37 +++++++---- test/DefaultPieceStorageTest.cc | 48 ++++++++------- test/MockPieceStorage.h | 40 +++++++----- test/UTMetadataRequestFactoryTest.cc | 3 +- 18 files changed, 313 insertions(+), 153 deletions(-) diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc index 01d8b73f..0bd1723f 100644 --- a/src/DefaultBtInteractive.cc +++ b/src/DefaultBtInteractive.cc @@ -353,10 +353,11 @@ void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) { excludedIndexes.reserve(btRequestFactory_->countTargetPiece()); btRequestFactory_->getTargetPieceIndexes(excludedIndexes); pieceStorage_->getMissingFastPiece - (pieces, diffMissingBlock, peer_, excludedIndexes); + (pieces, diffMissingBlock, peer_, excludedIndexes, cuid_); } else { pieces.reserve(diffMissingBlock); - pieceStorage_->getMissingFastPiece(pieces, diffMissingBlock, peer_); + pieceStorage_->getMissingFastPiece + (pieces, diffMissingBlock, peer_, cuid_); } } } else { @@ -365,10 +366,10 @@ void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) { excludedIndexes.reserve(btRequestFactory_->countTargetPiece()); btRequestFactory_->getTargetPieceIndexes(excludedIndexes); pieceStorage_->getMissingPiece - (pieces, diffMissingBlock, peer_, excludedIndexes); + (pieces, diffMissingBlock, peer_, excludedIndexes, cuid_); } else { pieces.reserve(diffMissingBlock); - pieceStorage_->getMissingPiece(pieces, diffMissingBlock, peer_); + pieceStorage_->getMissingPiece(pieces, diffMissingBlock, peer_, cuid_); } } for(std::vector >::const_iterator i = @@ -410,7 +411,7 @@ void DefaultBtInteractive::cancelAllPiece() { eoi = metadataRequests.end(); i != eoi; ++i) { A2_LOG_DEBUG(fmt("Cancel metadata: piece=%lu", static_cast(*i))); - pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i)); + pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i), cuid_); } } } @@ -524,7 +525,7 @@ void DefaultBtInteractive::doInteractionProcessing() { utMetadataRequestTracker_->removeTimeoutEntry(); for(std::vector::const_iterator i = indexes.begin(), eoi = indexes.end(); i != eoi; ++i) { - pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i)); + pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i), cuid_); } } if(pieceStorage_->downloadFinished()) { diff --git a/src/DefaultBtRequestFactory.cc b/src/DefaultBtRequestFactory.cc index 73d39cef..e10b2e60 100644 --- a/src/DefaultBtRequestFactory.cc +++ b/src/DefaultBtRequestFactory.cc @@ -53,7 +53,8 @@ namespace aria2 { DefaultBtRequestFactory::DefaultBtRequestFactory() : dispatcher_(0), - messageFactory_(0) + messageFactory_(0), + cuid_(0) {} DefaultBtRequestFactory::~DefaultBtRequestFactory() {} @@ -96,7 +97,7 @@ void DefaultBtRequestFactory::removeTargetPiece derefEqual(piece)), pieces_.end()); dispatcher_->doAbortOutstandingRequestAction(piece); - pieceStorage_->cancelPiece(piece); + pieceStorage_->cancelPiece(piece, cuid_); } namespace { @@ -104,16 +105,20 @@ class ProcessChokedPiece { private: SharedHandle peer_; SharedHandle pieceStorage_; + cuid_t cuid_; public: ProcessChokedPiece(const SharedHandle& peer, - const SharedHandle& pieceStorage): + const SharedHandle& pieceStorage, + cuid_t cuid): peer_(peer), - pieceStorage_(pieceStorage) {} + pieceStorage_(pieceStorage), + cuid_(cuid) + {} void operator()(const SharedHandle& piece) { if(!peer_->isInPeerAllowedIndexSet(piece->getIndex())) { - pieceStorage_->cancelPiece(piece); + pieceStorage_->cancelPiece(piece, cuid_); } } }; @@ -136,7 +141,7 @@ public: void DefaultBtRequestFactory::doChokedAction() { std::for_each(pieces_.begin(), pieces_.end(), - ProcessChokedPiece(peer_, pieceStorage_)); + ProcessChokedPiece(peer_, pieceStorage_, cuid_)); pieces_.erase(std::remove_if(pieces_.begin(), pieces_.end(), FindChokedPiece(peer_)), pieces_.end()); @@ -146,7 +151,7 @@ void DefaultBtRequestFactory::removeAllTargetPiece() { for(std::deque >::iterator itr = pieces_.begin(), eoi = pieces_.end(); itr != eoi; ++itr) { dispatcher_->doAbortOutstandingRequestAction(*itr); - pieceStorage_->cancelPiece(*itr); + pieceStorage_->cancelPiece(*itr, cuid_); } pieces_.clear(); } diff --git a/src/DefaultBtRequestFactory.h b/src/DefaultBtRequestFactory.h index 33016dcb..8d7d5983 100644 --- a/src/DefaultBtRequestFactory.h +++ b/src/DefaultBtRequestFactory.h @@ -56,6 +56,7 @@ private: BtMessageDispatcher* dispatcher_; BtMessageFactory* messageFactory_; std::deque > pieces_; + cuid_t cuid_; public: DefaultBtRequestFactory(); @@ -97,6 +98,11 @@ public: void setBtMessageDispatcher(BtMessageDispatcher* dispatcher); void setBtMessageFactory(BtMessageFactory* factory); + + void setCuid(cuid_t cuid) + { + cuid_ = cuid; + } }; typedef SharedHandle DefaultBtRequestFactoryHandle; diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc index 1681c714..4f331d13 100644 --- a/src/DefaultPieceStorage.cc +++ b/src/DefaultPieceStorage.cc @@ -96,14 +96,14 @@ DefaultPieceStorage::~DefaultPieceStorage() delete bitfieldMan_; } -SharedHandle DefaultPieceStorage::checkOutPiece(size_t index) +SharedHandle DefaultPieceStorage::checkOutPiece +(size_t index, cuid_t cuid) { bitfieldMan_->setUseBit(index); SharedHandle piece = findUsedPiece(index); if(!piece) { piece.reset(new Piece(index, bitfieldMan_->getBlockLength(index))); - #ifdef ENABLE_MESSAGE_DIGEST piece->setHashAlgo(downloadContext_->getPieceHashAlgo()); @@ -111,10 +111,9 @@ SharedHandle DefaultPieceStorage::checkOutPiece(size_t index) #endif // ENABLE_MESSAGE_DIGEST addUsedPiece(piece); - return piece; - } else { - return piece; } + piece->addUser(cuid); + return piece; } /** @@ -174,7 +173,8 @@ void DefaultPieceStorage::getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, const unsigned char* bitfield, - size_t length) + size_t length, + cuid_t cuid) { const size_t mislen = bitfieldMan_->getBitfieldLength(); array_ptr misbitfield(new unsigned char[mislen]); @@ -195,8 +195,14 @@ void DefaultPieceStorage::getMissingPiece std::random_shuffle(indexes.begin(), indexes.end()); for(std::vector::const_iterator i = indexes.begin(), eoi = indexes.end(); i != eoi && misBlock < minMissingBlocks; ++i) { - pieces.push_back(checkOutPiece(*i)); - misBlock += pieces.back()->countMissingBlock(); + SharedHandle piece = checkOutPiece(*i, cuid); + if(piece->getUsedBySegment()) { + // We don't share piece downloaded via HTTP/FTP + piece->removeUser(cuid); + } else { + pieces.push_back(piece); + misBlock += piece->countMissingBlock(); + } } } else { bool r = bitfieldMan_->getAllMissingUnusedIndexes @@ -207,7 +213,7 @@ void DefaultPieceStorage::getMissingPiece while(misBlock < minMissingBlocks) { size_t index; if(pieceSelector_->select(index, misbitfield, blocks)) { - pieces.push_back(checkOutPiece(index)); + pieces.push_back(checkOutPiece(index, cuid)); bitfield::flipBit(misbitfield, blocks, index); misBlock += pieces.back()->countMissingBlock(); } else { @@ -241,10 +247,12 @@ void DefaultPieceStorage::createFastIndexBitfield void DefaultPieceStorage::getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer) + const SharedHandle& peer, + cuid_t cuid) { getMissingPiece(pieces, minMissingBlocks, - peer->getBitfield(), peer->getBitfieldLength()); + peer->getBitfield(), peer->getBitfieldLength(), + cuid); } @@ -252,20 +260,23 @@ void DefaultPieceStorage::getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) + const std::vector& excludedIndexes, + cuid_t cuid) { BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), bitfieldMan_->getTotalLength()); tempBitfield.setBitfield(peer->getBitfield(), peer->getBitfieldLength()); unsetExcludedIndexes(tempBitfield, excludedIndexes); getMissingPiece(pieces, minMissingBlocks, - tempBitfield.getBitfield(), tempBitfield.getBitfieldLength()); + tempBitfield.getBitfield(), tempBitfield.getBitfieldLength(), + cuid); } void DefaultPieceStorage::getMissingFastPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer) + const SharedHandle& peer, + cuid_t cuid) { if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) { BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), @@ -273,7 +284,8 @@ void DefaultPieceStorage::getMissingFastPiece createFastIndexBitfield(tempBitfield, peer); getMissingPiece(pieces, minMissingBlocks, tempBitfield.getBitfield(), - tempBitfield.getBitfieldLength()); + tempBitfield.getBitfieldLength(), + cuid); } } @@ -281,7 +293,8 @@ void DefaultPieceStorage::getMissingFastPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) + const std::vector& excludedIndexes, + cuid_t cuid) { if(peer->isFastExtensionEnabled() && peer->countPeerAllowedIndexSet() > 0) { BitfieldMan tempBitfield(bitfieldMan_->getBlockLength(), @@ -290,15 +303,18 @@ void DefaultPieceStorage::getMissingFastPiece unsetExcludedIndexes(tempBitfield, excludedIndexes); getMissingPiece(pieces, minMissingBlocks, tempBitfield.getBitfield(), - tempBitfield.getBitfieldLength()); + tempBitfield.getBitfieldLength(), + cuid); } } SharedHandle -DefaultPieceStorage::getMissingPiece(const SharedHandle& peer) +DefaultPieceStorage::getMissingPiece +(const SharedHandle& peer, + cuid_t cuid) { std::vector > pieces; - getMissingPiece(pieces, 1, peer); + getMissingPiece(pieces, 1, peer, cuid); if(pieces.empty()) { return SharedHandle(); } else { @@ -307,10 +323,12 @@ DefaultPieceStorage::getMissingPiece(const SharedHandle& peer) } SharedHandle DefaultPieceStorage::getMissingPiece -(const SharedHandle& peer, const std::vector& excludedIndexes) +(const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid) { std::vector > pieces; - getMissingPiece(pieces, 1, peer, excludedIndexes); + getMissingPiece(pieces, 1, peer, excludedIndexes, cuid); if(pieces.empty()) { return SharedHandle(); } else { @@ -319,10 +337,11 @@ SharedHandle DefaultPieceStorage::getMissingPiece } SharedHandle DefaultPieceStorage::getMissingFastPiece -(const SharedHandle& peer) +(const SharedHandle& peer, + cuid_t cuid) { std::vector > pieces; - getMissingFastPiece(pieces, 1, peer); + getMissingFastPiece(pieces, 1, peer, cuid); if(pieces.empty()) { return SharedHandle(); } else { @@ -331,10 +350,12 @@ SharedHandle DefaultPieceStorage::getMissingFastPiece } SharedHandle DefaultPieceStorage::getMissingFastPiece -(const SharedHandle& peer, const std::vector& excludedIndexes) +(const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid) { std::vector > pieces; - getMissingFastPiece(pieces, 1, peer, excludedIndexes); + getMissingFastPiece(pieces, 1, peer, excludedIndexes, cuid); if(pieces.empty()) { return SharedHandle(); } else { @@ -351,23 +372,28 @@ bool DefaultPieceStorage::hasMissingUnusedPiece() } SharedHandle 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; if(streamPieceSelector_->select (index, minSplitSize, ignoreBitfield, length)) { - return checkOutPiece(index); + return checkOutPiece(index, cuid); } else { return SharedHandle(); } } -SharedHandle DefaultPieceStorage::getMissingPiece(size_t index) +SharedHandle DefaultPieceStorage::getMissingPiece +(size_t index, + cuid_t cuid) { if(hasPiece(index) || isPieceUsed(index)) { return SharedHandle(); } else { - return checkOutPiece(index); + return checkOutPiece(index, cuid); } } @@ -464,12 +490,16 @@ bool DefaultPieceStorage::isSelectiveDownloadingMode() } // not unittested -void DefaultPieceStorage::cancelPiece(const SharedHandle& piece) +void DefaultPieceStorage::cancelPiece +(const SharedHandle& piece, cuid_t cuid) { if(!piece) { return; } - bitfieldMan_->unsetUseBit(piece->getIndex()); + piece->removeUser(cuid); + if(!piece->getUsed()) { + bitfieldMan_->unsetUseBit(piece->getIndex()); + } if(!isEndGame()) { if(piece->getCompletedLength() == 0) { deleteUsedPiece(piece); diff --git a/src/DefaultPieceStorage.h b/src/DefaultPieceStorage.h index bb38dc43..18d664de 100644 --- a/src/DefaultPieceStorage.h +++ b/src/DefaultPieceStorage.h @@ -92,13 +92,14 @@ private: (std::vector >& pieces, size_t minMissingBlocks, const unsigned char* bitfield, - size_t length); + size_t length, + cuid_t cuid); void createFastIndexBitfield(BitfieldMan& bitfield, const SharedHandle& peer); #endif // ENABLE_BITTORRENT - SharedHandle checkOutPiece(size_t index); + SharedHandle checkOutPiece(size_t index, cuid_t cuid); // size_t deleteUsedPiecesByFillRate(int fillRate, size_t toDelete); // void reduceUsedPieces(size_t upperBound); void deleteUsedPiece(const SharedHandle& piece); @@ -123,50 +124,64 @@ public: virtual void getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer); + const SharedHandle& peer, + cuid_t cuid); virtual void getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes); - - virtual void getMissingFastPiece - (std::vector >& pieces, - size_t minMissingBlocks, - const SharedHandle& peer); + const std::vector& excludedIndexes, + cuid_t cuid); virtual void getMissingFastPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes); + cuid_t cuid); - virtual SharedHandle getMissingPiece(const SharedHandle& peer); + virtual void getMissingFastPiece + (std::vector >& pieces, + size_t minMissingBlocks, + const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid); + + virtual SharedHandle getMissingPiece + (const SharedHandle& peer, + cuid_t cuid); virtual SharedHandle getMissingPiece - (const SharedHandle& peer, const std::vector& excludedIndexes); + (const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid); SharedHandle getMissingFastPiece - (const SharedHandle& peer); + (const SharedHandle& peer, + cuid_t cuid); SharedHandle getMissingFastPiece - (const SharedHandle& peer, const std::vector& excludedIndexes); + (const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid); #endif // ENABLE_BITTORRENT virtual bool hasMissingUnusedPiece(); virtual SharedHandle 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 getMissingPiece(size_t index); + virtual SharedHandle getMissingPiece(size_t index, cuid_t cuid); virtual SharedHandle getPiece(size_t index); virtual void completePiece(const SharedHandle& piece); - virtual void cancelPiece(const SharedHandle& piece); + virtual void cancelPiece(const SharedHandle& piece, cuid_t cuid); virtual bool hasPiece(size_t index); diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc index 488456ac..0d7a3059 100644 --- a/src/PeerInteractionCommand.cc +++ b/src/PeerInteractionCommand.cc @@ -194,6 +194,7 @@ PeerInteractionCommand::PeerInteractionCommand reqFactory->setPieceStorage(pieceStorage); reqFactory->setBtMessageDispatcher(dispatcher.get()); reqFactory->setBtMessageFactory(factory.get()); + reqFactory->setCuid(cuid); DefaultBtInteractiveHandle btInteractive (new DefaultBtInteractive(requestGroup_->getDownloadContext(), getPeer())); @@ -248,6 +249,7 @@ PeerInteractionCommand::PeerInteractionCommand extensionMessageFactory->setBtMessageFactory(factory.get()); if(metadataGetMode) { + utMetadataRequestFactory->setCuid(cuid); utMetadataRequestFactory->setDownloadContext (requestGroup_->getDownloadContext()); utMetadataRequestFactory->setBtMessageDispatcher(dispatcher.get()); diff --git a/src/Piece.cc b/src/Piece.cc index c7fe2c06..c2734123 100644 --- a/src/Piece.cc +++ b/src/Piece.cc @@ -44,7 +44,8 @@ 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 , nextBegin_(0) #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): index_(index), length_(length), blockLength_(blockLength), - bitfield_(new BitfieldMan(blockLength_, length)) + bitfield_(new BitfieldMan(blockLength_, length)), + usedBySegment_(false) #ifdef ENABLE_MESSAGE_DIGEST - , nextBegin_(0) + , nextBegin_(0) #endif // ENABLE_MESSAGE_DIGEST {} @@ -235,4 +237,21 @@ void Piece::destroyHashContext() #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 diff --git a/src/Piece.h b/src/Piece.h index c9abbd36..8e824c68 100644 --- a/src/Piece.h +++ b/src/Piece.h @@ -42,6 +42,7 @@ #include #include "SharedHandle.h" +#include "Command.h" namespace aria2 { @@ -59,7 +60,8 @@ private: size_t length_; size_t blockLength_; BitfieldMan* bitfield_; - + std::vector users_; + bool usedBySegment_; #ifdef ENABLE_MESSAGE_DIGEST size_t nextBegin_; @@ -176,6 +178,22 @@ public: * Loses current bitfield state. */ 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 diff --git a/src/PieceStorage.h b/src/PieceStorage.h index 762201de..e50495b7 100644 --- a/src/PieceStorage.h +++ b/src/PieceStorage.h @@ -74,7 +74,8 @@ public: virtual void getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer) = 0; + const SharedHandle& peer, + cuid_t cuid) = 0; // Same as getMissingPiece(pieces, minMissingBlocks, peer), but the // indexes in excludedIndexes are excluded. @@ -82,7 +83,8 @@ public: (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) = 0; + const std::vector& excludedIndexes, + cuid_t cuid) = 0; // Stores pieces that the peer has but localhost doesn't. Only // pieces that declared as "fast" are stored. Those pieces stored @@ -96,7 +98,8 @@ public: virtual void getMissingFastPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer) = 0; + const SharedHandle& peer, + cuid_t cuid) = 0; // Same as getMissingFastPiece(pieces, minMissingBlocks, peer), but // the indexes in excludedIndexes are excluded. @@ -104,7 +107,8 @@ public: (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) = 0; + const std::vector& excludedIndexes, + cuid_t cuid) = 0; /** * Returns a piece that the peer has but localhost doesn't. @@ -113,7 +117,7 @@ public: * to several commands. */ virtual SharedHandle - getMissingPiece(const SharedHandle& peer) = 0; + getMissingPiece(const SharedHandle& peer, cuid_t cuid) = 0; /** * Same as getMissingPiece(const SharedHandle& peer), but the indexes in @@ -121,7 +125,8 @@ public: */ virtual SharedHandle getMissingPiece (const SharedHandle& peer, - const std::vector& excludedIndexes) = 0; + const std::vector& excludedIndexes, + cuid_t cuid) = 0; #endif // ENABLE_BITTORRENT // 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. */ virtual SharedHandle 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. @@ -140,7 +148,7 @@ public: * then returns 0. * Also returns 0 if any of missing piece is not available. */ - virtual SharedHandle getMissingPiece(size_t index) = 0; + virtual SharedHandle getMissingPiece(size_t index, cuid_t cuid) = 0; /** * Returns the piece denoted by index. @@ -161,7 +169,7 @@ public: /** * Tells that the download of the specified piece is canceled. */ - virtual void cancelPiece(const SharedHandle& piece) = 0; + virtual void cancelPiece(const SharedHandle& piece, cuid_t cuid) = 0; /** * Returns true if the specified piece is already downloaded. diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc index d4aa3122..7fb65b38 100644 --- a/src/SegmentMan.cc +++ b/src/SegmentMan.cc @@ -123,6 +123,7 @@ SharedHandle SegmentMan::checkoutSegment A2_LOG_DEBUG(fmt("Attach segment#%lu to CUID#%lld.", static_cast(piece->getIndex()), cuid)); + piece->setUsedBySegment(true); SharedHandle segment; if(piece->getLength() == 0) { segment.reset(new GrowSegment(piece)); @@ -175,7 +176,8 @@ SharedHandle SegmentMan::getSegment(cuid_t cuid, size_t minSplitSize) SharedHandle piece = pieceStorage_->getMissingPiece (minSplitSize, - ignoreBitfield_.getFilterBitfield(), ignoreBitfield_.getBitfieldLength()); + ignoreBitfield_.getFilterBitfield(), ignoreBitfield_.getBitfieldLength(), + cuid); return checkoutSegment(cuid, piece); } @@ -195,7 +197,8 @@ void SegmentMan::getSegment checkoutSegment(cuid, pieceStorage_->getMissingPiece (minSplitSize, - filter.getFilterBitfield(), filter.getBitfieldLength())); + filter.getFilterBitfield(), filter.getBitfieldLength(), + cuid)); if(!segment) { break; } @@ -217,7 +220,7 @@ SharedHandle SegmentMan::getSegmentWithIndex if(index > 0 && downloadContext_->getNumPieces() <= index) { return SharedHandle(); } - return checkoutSegment(cuid, pieceStorage_->getMissingPiece(index)); + return checkoutSegment(cuid, pieceStorage_->getMissingPiece(index, cuid)); } SharedHandle SegmentMan::getCleanSegmentIfOwnerIsIdle @@ -249,11 +252,14 @@ SharedHandle SegmentMan::getCleanSegmentIfOwnerIsIdle return SharedHandle(); } -void SegmentMan::cancelSegment(const SharedHandle& segment) +void SegmentMan::cancelSegmentInternal +(cuid_t cuid, + const SharedHandle& segment) { A2_LOG_DEBUG(fmt("Canceling segment#%lu", static_cast(segment->getIndex()))); - pieceStorage_->cancelPiece(segment->getPiece()); + segment->getPiece()->setUsedBySegment(false); + pieceStorage_->cancelPiece(segment->getPiece(), cuid); segmentWrittenLengthMemo_[segment->getIndex()] = segment->getWrittenLength(); A2_LOG_DEBUG(fmt("Memorized segment index=%lu, writtenLength=%lu", static_cast(segment->getIndex()), @@ -264,7 +270,7 @@ void SegmentMan::cancelSegment(cuid_t cuid) { for(SegmentEntries::iterator itr = usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end(); itr != eoi;) { if((*itr)->cuid == cuid) { - cancelSegment((*itr)->segment); + cancelSegmentInternal(cuid, (*itr)->segment); itr = usedSegmentEntries_.erase(itr); eoi = usedSegmentEntries_.end(); } else { @@ -279,9 +285,8 @@ void SegmentMan::cancelSegment for(SegmentEntries::iterator itr = usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end(); itr != eoi;) { if((*itr)->cuid == cuid && *(*itr)->segment == *segment) { - cancelSegment((*itr)->segment); + cancelSegmentInternal(cuid, (*itr)->segment); itr = usedSegmentEntries_.erase(itr); - //eoi = usedSegmentEntries_.end(); break; } else { ++itr; @@ -294,7 +299,7 @@ void SegmentMan::cancelAllSegments() for(std::deque >::iterator itr = usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end(); itr != eoi; ++itr) { - cancelSegment((*itr)->segment); + cancelSegmentInternal((*itr)->cuid, (*itr)->segment); } usedSegmentEntries_.clear(); } diff --git a/src/SegmentMan.h b/src/SegmentMan.h index 8c6e6423..3eae1501 100644 --- a/src/SegmentMan.h +++ b/src/SegmentMan.h @@ -106,7 +106,7 @@ private: SharedHandle checkoutSegment(cuid_t cuid, const SharedHandle& piece); - void cancelSegment(const SharedHandle& segment); + void cancelSegmentInternal(cuid_t cuid, const SharedHandle& segment); public: SegmentMan(const Option* option, const SharedHandle& downloadContext, diff --git a/src/UTMetadataRequestFactory.cc b/src/UTMetadataRequestFactory.cc index 604449cf..53d34e73 100644 --- a/src/UTMetadataRequestFactory.cc +++ b/src/UTMetadataRequestFactory.cc @@ -50,7 +50,8 @@ namespace aria2 { UTMetadataRequestFactory::UTMetadataRequestFactory() : dispatcher_(0), messageFactory_(0), - tracker_(0) + tracker_(0), + cuid_(0) {} void UTMetadataRequestFactory::create @@ -60,7 +61,7 @@ void UTMetadataRequestFactory::create while(num) { std::vector metadataRequests = tracker_->getAllTrackedIndex(); SharedHandle p = - pieceStorage->getMissingPiece(peer_, metadataRequests); + pieceStorage->getMissingPiece(peer_, metadataRequests, cuid_); if(!p) { A2_LOG_DEBUG("No ut_metadata piece is available to download."); break; diff --git a/src/UTMetadataRequestFactory.h b/src/UTMetadataRequestFactory.h index e8e02b2a..7af3e8da 100644 --- a/src/UTMetadataRequestFactory.h +++ b/src/UTMetadataRequestFactory.h @@ -40,6 +40,7 @@ #include #include "SharedHandle.h" +#include "Command.h" namespace aria2 { @@ -62,6 +63,7 @@ private: BtMessageFactory* messageFactory_; UTMetadataRequestTracker* tracker_; + cuid_t cuid_; public: UTMetadataRequestFactory(); @@ -94,6 +96,11 @@ public: { tracker_ = tracker; } + + void setCuid(cuid_t cuid) + { + cuid_ = cuid; + } }; } // namespace aria2 diff --git a/src/UnknownLengthPieceStorage.cc b/src/UnknownLengthPieceStorage.cc index 706d5e4b..c0809dff 100644 --- a/src/UnknownLengthPieceStorage.cc +++ b/src/UnknownLengthPieceStorage.cc @@ -81,7 +81,8 @@ bool UnknownLengthPieceStorage::hasMissingPiece(const SharedHandle& peer) void UnknownLengthPieceStorage::getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer) + const SharedHandle& peer, + cuid_t cuid) { abort(); } @@ -90,15 +91,8 @@ void UnknownLengthPieceStorage::getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) -{ - abort(); -} - -void UnknownLengthPieceStorage::getMissingFastPiece -(std::vector >& pieces, - size_t minMissingBlocks, - const SharedHandle& peer) + const std::vector& excludedIndexes, + cuid_t cuid) { abort(); } @@ -107,18 +101,32 @@ void UnknownLengthPieceStorage::getMissingFastPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) + cuid_t cuid) { abort(); } -SharedHandle UnknownLengthPieceStorage::getMissingPiece(const SharedHandle& peer) +void UnknownLengthPieceStorage::getMissingFastPiece +(std::vector >& pieces, + size_t minMissingBlocks, + const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid) { abort(); } SharedHandle UnknownLengthPieceStorage::getMissingPiece -(const SharedHandle& peer, const std::vector& excludedIndexes) +(const SharedHandle& peer, + cuid_t cuid) +{ + abort(); +} + +SharedHandle UnknownLengthPieceStorage::getMissingPiece +(const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid) { abort(); } @@ -130,7 +138,10 @@ bool UnknownLengthPieceStorage::hasMissingUnusedPiece() } SharedHandle 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_) { return SharedHandle(); @@ -143,10 +154,12 @@ SharedHandle UnknownLengthPieceStorage::getMissingPiece } } -SharedHandle UnknownLengthPieceStorage::getMissingPiece(size_t index) +SharedHandle UnknownLengthPieceStorage::getMissingPiece +(size_t index, + cuid_t cuid) { if(index == 0) { - return getMissingPiece(0, 0, 0); + return getMissingPiece(0, 0, 0, cuid); } else { return SharedHandle(); } @@ -175,7 +188,9 @@ void UnknownLengthPieceStorage::completePiece(const SharedHandle& piece) } } -void UnknownLengthPieceStorage::cancelPiece(const SharedHandle& piece) +void UnknownLengthPieceStorage::cancelPiece +(const SharedHandle& piece, + cuid_t cuid) { if(*piece_ == *piece) { piece_.reset(); diff --git a/src/UnknownLengthPieceStorage.h b/src/UnknownLengthPieceStorage.h index e2531f14..d409b3e9 100644 --- a/src/UnknownLengthPieceStorage.h +++ b/src/UnknownLengthPieceStorage.h @@ -76,29 +76,37 @@ public: virtual void getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer); + const SharedHandle& peer, + cuid_t cuid); virtual void getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes); - - virtual void getMissingFastPiece - (std::vector >& pieces, - size_t minMissingBlocks, - const SharedHandle& peer); + const std::vector& excludedIndexes, + cuid_t cuid); virtual void getMissingFastPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes); + cuid_t cuid); - virtual SharedHandle getMissingPiece(const SharedHandle& peer); + virtual void getMissingFastPiece + (std::vector >& pieces, + size_t minMissingBlocks, + const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid); virtual SharedHandle getMissingPiece - (const SharedHandle& peer, const std::vector& excludedIndexes); + (const SharedHandle& peer, + cuid_t cuid); + + virtual SharedHandle getMissingPiece + (const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid); #endif // ENABLE_BITTORRENT virtual bool hasMissingUnusedPiece(); @@ -107,7 +115,10 @@ public: * Returns a missing piece if available. Otherwise returns 0; */ virtual SharedHandle 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. @@ -115,7 +126,7 @@ public: * then returns 0. * Also returns 0 if any of missing piece is not available. */ - virtual SharedHandle getMissingPiece(size_t index); + virtual SharedHandle getMissingPiece(size_t index, cuid_t cuid); /** * Returns the piece denoted by index. @@ -131,7 +142,7 @@ public: /** * Tells that the download of the specified piece is canceled. */ - virtual void cancelPiece(const SharedHandle& piece); + virtual void cancelPiece(const SharedHandle& piece, cuid_t cuid); /** * Returns true if the specified piece is already downloaded. diff --git a/test/DefaultPieceStorageTest.cc b/test/DefaultPieceStorageTest.cc index bc403bbf..054d2598 100644 --- a/test/DefaultPieceStorageTest.cc +++ b/test/DefaultPieceStorageTest.cc @@ -88,16 +88,17 @@ void DefaultPieceStorageTest::testGetMissingPiece() { pss.setPieceSelector(pieceSelector_); peer->setAllBitfield(); - SharedHandle piece = pss.getMissingPiece(peer); + SharedHandle piece = pss.getMissingPiece(peer, 1); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), 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"), piece->toString()); - piece = pss.getMissingPiece(peer); + piece = pss.getMissingPiece(peer, 1); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), piece->toString()); - piece = pss.getMissingPiece(peer); + piece = pss.getMissingPiece(peer, 1); CPPUNIT_ASSERT(!piece); } @@ -106,14 +107,15 @@ void DefaultPieceStorageTest::testGetMissingPiece_many() { pss.setPieceSelector(pieceSelector_); peer->setAllBitfield(); std::vector > pieces; - pss.getMissingPiece(pieces, 2, peer); + pss.getMissingPiece(pieces, 2, peer, 1); CPPUNIT_ASSERT_EQUAL((size_t)2, pieces.size()); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), pieces[0]->toString()); + CPPUNIT_ASSERT(pieces[0]->usedBy(1)); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"), pieces[1]->toString()); pieces.clear(); - pss.getMissingPiece(pieces, 2, peer); + pss.getMissingPiece(pieces, 2, peer, 1); CPPUNIT_ASSERT_EQUAL((size_t)1, pieces.size()); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), pieces[0]->toString()); @@ -130,15 +132,15 @@ void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes() std::vector excludedIndexes; excludedIndexes.push_back(1); - SharedHandle piece = pss.getMissingPiece(peer, excludedIndexes); + SharedHandle piece = pss.getMissingPiece(peer, excludedIndexes, 1); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), piece->toString()); - piece = pss.getMissingPiece(peer, excludedIndexes); + piece = pss.getMissingPiece(peer, excludedIndexes, 1); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), piece->toString()); - piece = pss.getMissingPiece(peer, excludedIndexes); + piece = pss.getMissingPiece(peer, excludedIndexes, 1); CPPUNIT_ASSERT(!piece); } @@ -149,14 +151,14 @@ void DefaultPieceStorageTest::testGetMissingPiece_manyWithExcludedIndexes() { std::vector excludedIndexes; excludedIndexes.push_back(1); std::vector > 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(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); + pss.getMissingPiece(pieces, 2, peer, excludedIndexes, 1); CPPUNIT_ASSERT(pieces.empty()); } @@ -169,11 +171,11 @@ void DefaultPieceStorageTest::testGetMissingFastPiece() { peer->setFastExtensionEnabled(true); peer->addPeerAllowedIndex(2); - SharedHandle piece = pss.getMissingFastPiece(peer); + SharedHandle piece = pss.getMissingFastPiece(peer, 1); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=2, length=128"), piece->toString()); - CPPUNIT_ASSERT(!pss.getMissingFastPiece(peer)); + CPPUNIT_ASSERT(!pss.getMissingFastPiece(peer, 1)); } void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes() @@ -190,11 +192,11 @@ void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes() std::vector excludedIndexes; excludedIndexes.push_back(2); - SharedHandle piece = pss.getMissingFastPiece(peer, excludedIndexes); + SharedHandle piece = pss.getMissingFastPiece(peer, excludedIndexes, 1); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=1, length=128"), piece->toString()); - CPPUNIT_ASSERT(!pss.getMissingFastPiece(peer, excludedIndexes)); + CPPUNIT_ASSERT(!pss.getMissingFastPiece(peer, excludedIndexes, 1)); } void DefaultPieceStorageTest::testHasMissingPiece() { @@ -214,7 +216,7 @@ void DefaultPieceStorageTest::testCompletePiece() { peer->setAllBitfield(); - SharedHandle piece = pss.getMissingPiece(peer); + SharedHandle piece = pss.getMissingPiece(peer, 1); CPPUNIT_ASSERT_EQUAL(std::string("piece: index=0, length=128"), piece->toString()); @@ -224,7 +226,7 @@ void DefaultPieceStorageTest::testCompletePiece() { CPPUNIT_ASSERT_EQUAL((uint64_t)128ULL, pss.getCompletedLength()); - SharedHandle incompletePiece = pss.getMissingPiece(peer); + SharedHandle incompletePiece = pss.getMissingPiece(peer, 1); incompletePiece->completeBlock(0); CPPUNIT_ASSERT_EQUAL((uint64_t)256ULL, pss.getCompletedLength()); } @@ -272,14 +274,16 @@ void DefaultPieceStorageTest::testCancelPiece() SharedHandle ps(new DefaultPieceStorage(dctx, option_.get())); - SharedHandle p = ps->getMissingPiece(0); + SharedHandle p = ps->getMissingPiece(0, 1); p->completeBlock(0); - ps->cancelPiece(p); + ps->cancelPiece(p, 1); - SharedHandle p2 = ps->getMissingPiece(0); + SharedHandle p2 = ps->getMissingPiece(0, 2); CPPUNIT_ASSERT(p2->hasBlock(0)); + CPPUNIT_ASSERT(p2->usedBy(2)); + CPPUNIT_ASSERT(!p2->usedBy(1)); } void DefaultPieceStorageTest::testMarkPiecesDone() @@ -345,11 +349,11 @@ void DefaultPieceStorageTest::testGetNextUsedIndex() { DefaultPieceStorage pss(dctx_, option_.get()); CPPUNIT_ASSERT_EQUAL((size_t)3, pss.getNextUsedIndex(0)); - SharedHandle piece = pss.getMissingPiece(2); + SharedHandle piece = pss.getMissingPiece(2, 1); CPPUNIT_ASSERT_EQUAL((size_t)2, pss.getNextUsedIndex(0)); pss.completePiece(piece); 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)); } diff --git a/test/MockPieceStorage.h b/test/MockPieceStorage.h index 4990e50a..94a44f92 100644 --- a/test/MockPieceStorage.h +++ b/test/MockPieceStorage.h @@ -47,35 +47,44 @@ public: virtual void getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, - const SharedHandle& peer) + const SharedHandle& peer, + cuid_t cuid) {} virtual void getMissingPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) - {} - - virtual void getMissingFastPiece - (std::vector >& pieces, - size_t minMissingBlocks, - const SharedHandle& peer) + const std::vector& excludedIndexes, + cuid_t cuid) {} virtual void getMissingFastPiece (std::vector >& pieces, size_t minMissingBlocks, const SharedHandle& peer, - const std::vector& excludedIndexes) + cuid_t cuid) {} - virtual SharedHandle getMissingPiece(const SharedHandle& peer) { + virtual void getMissingFastPiece + (std::vector >& pieces, + size_t minMissingBlocks, + const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid) + {} + + virtual SharedHandle getMissingPiece + (const SharedHandle& peer, + cuid_t cuid) + { return SharedHandle(new Piece()); } virtual SharedHandle getMissingPiece - (const SharedHandle& peer, const std::vector& excludedIndexes) + (const SharedHandle& peer, + const std::vector& excludedIndexes, + cuid_t cuid) { return SharedHandle(new Piece()); } @@ -88,12 +97,15 @@ public: } virtual SharedHandle 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(new Piece()); } - virtual SharedHandle getMissingPiece(size_t index) + virtual SharedHandle getMissingPiece(size_t index, cuid_t cuid) { return SharedHandle(new Piece()); } @@ -113,7 +125,7 @@ public: virtual void completePiece(const SharedHandle& piece) {} - virtual void cancelPiece(const SharedHandle& piece) {} + virtual void cancelPiece(const SharedHandle& piece, cuid_t cuid) {} virtual bool hasPiece(size_t index) { return false; diff --git a/test/UTMetadataRequestFactoryTest.cc b/test/UTMetadataRequestFactoryTest.cc index d2384d19..bfa37c62 100644 --- a/test/UTMetadataRequestFactoryTest.cc +++ b/test/UTMetadataRequestFactoryTest.cc @@ -30,7 +30,8 @@ public: virtual SharedHandle getMissingPiece (const SharedHandle& peer, - const std::vector& exlucdedIndexes) + const std::vector& exlucdedIndexes, + cuid_t cuid) { if(missingIndexes.empty()) { return SharedHandle();