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());
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<SharedHandle<Piece> >::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<unsigned long>(*i)));
pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i));
pieceStorage_->cancelPiece(pieceStorage_->getPiece(*i), cuid_);
}
}
}
@ -524,7 +525,7 @@ void DefaultBtInteractive::doInteractionProcessing() {
utMetadataRequestTracker_->removeTimeoutEntry();
for(std::vector<size_t>::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()) {

View File

@ -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> peer_;
SharedHandle<PieceStorage> pieceStorage_;
cuid_t cuid_;
public:
ProcessChokedPiece(const SharedHandle<Peer>& peer,
const SharedHandle<PieceStorage>& pieceStorage):
const SharedHandle<PieceStorage>& pieceStorage,
cuid_t cuid):
peer_(peer),
pieceStorage_(pieceStorage) {}
pieceStorage_(pieceStorage),
cuid_(cuid)
{}
void operator()(const SharedHandle<Piece>& 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<SharedHandle<Piece> >::iterator itr = pieces_.begin(),
eoi = pieces_.end(); itr != eoi; ++itr) {
dispatcher_->doAbortOutstandingRequestAction(*itr);
pieceStorage_->cancelPiece(*itr);
pieceStorage_->cancelPiece(*itr, cuid_);
}
pieces_.clear();
}

View File

@ -56,6 +56,7 @@ private:
BtMessageDispatcher* dispatcher_;
BtMessageFactory* messageFactory_;
std::deque<SharedHandle<Piece> > 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<DefaultBtRequestFactory> DefaultBtRequestFactoryHandle;

View File

@ -96,14 +96,14 @@ DefaultPieceStorage::~DefaultPieceStorage()
delete bitfieldMan_;
}
SharedHandle<Piece> DefaultPieceStorage::checkOutPiece(size_t index)
SharedHandle<Piece> DefaultPieceStorage::checkOutPiece
(size_t index, cuid_t cuid)
{
bitfieldMan_->setUseBit(index);
SharedHandle<Piece> 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<Piece> 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<SharedHandle<Piece> >& 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<unsigned char> misbitfield(new unsigned char[mislen]);
@ -195,8 +195,14 @@ void DefaultPieceStorage::getMissingPiece
std::random_shuffle(indexes.begin(), indexes.end());
for(std::vector<size_t>::const_iterator i = indexes.begin(),
eoi = indexes.end(); i != eoi && misBlock < minMissingBlocks; ++i) {
pieces.push_back(checkOutPiece(*i));
misBlock += pieces.back()->countMissingBlock();
SharedHandle<Piece> 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<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
const SharedHandle<Peer>& 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<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
const std::vector<size_t>& 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<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
const SharedHandle<Peer>& 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<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
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) {
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<Piece>
DefaultPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer)
DefaultPieceStorage::getMissingPiece
(const SharedHandle<Peer>& peer,
cuid_t cuid)
{
std::vector<SharedHandle<Piece> > pieces;
getMissingPiece(pieces, 1, peer);
getMissingPiece(pieces, 1, peer, cuid);
if(pieces.empty()) {
return SharedHandle<Piece>();
} else {
@ -307,10 +323,12 @@ DefaultPieceStorage::getMissingPiece(const SharedHandle<Peer>& peer)
}
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;
getMissingPiece(pieces, 1, peer, excludedIndexes);
getMissingPiece(pieces, 1, peer, excludedIndexes, cuid);
if(pieces.empty()) {
return SharedHandle<Piece>();
} else {
@ -319,10 +337,11 @@ SharedHandle<Piece> DefaultPieceStorage::getMissingPiece
}
SharedHandle<Piece> DefaultPieceStorage::getMissingFastPiece
(const SharedHandle<Peer>& peer)
(const SharedHandle<Peer>& peer,
cuid_t cuid)
{
std::vector<SharedHandle<Piece> > pieces;
getMissingFastPiece(pieces, 1, peer);
getMissingFastPiece(pieces, 1, peer, cuid);
if(pieces.empty()) {
return SharedHandle<Piece>();
} else {
@ -331,10 +350,12 @@ 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;
getMissingFastPiece(pieces, 1, peer, excludedIndexes);
getMissingFastPiece(pieces, 1, peer, excludedIndexes, cuid);
if(pieces.empty()) {
return SharedHandle<Piece>();
} else {
@ -351,23 +372,28 @@ bool DefaultPieceStorage::hasMissingUnusedPiece()
}
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;
if(streamPieceSelector_->select
(index, minSplitSize, ignoreBitfield, length)) {
return checkOutPiece(index);
return checkOutPiece(index, cuid);
} else {
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)) {
return SharedHandle<Piece>();
} else {
return checkOutPiece(index);
return checkOutPiece(index, cuid);
}
}
@ -464,12 +490,16 @@ bool DefaultPieceStorage::isSelectiveDownloadingMode()
}
// not unittested
void DefaultPieceStorage::cancelPiece(const SharedHandle<Piece>& piece)
void DefaultPieceStorage::cancelPiece
(const SharedHandle<Piece>& 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);

View File

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

View File

@ -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());

View File

@ -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

View File

@ -42,6 +42,7 @@
#include <string>
#include "SharedHandle.h"
#include "Command.h"
namespace aria2 {
@ -59,7 +60,8 @@ private:
size_t length_;
size_t blockLength_;
BitfieldMan* bitfield_;
std::vector<cuid_t> 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

View File

@ -74,7 +74,8 @@ public:
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer) = 0;
const SharedHandle<Peer>& 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<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
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
// pieces that declared as "fast" are stored. Those pieces stored
@ -96,7 +98,8 @@ public:
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer) = 0;
const SharedHandle<Peer>& 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<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
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.
@ -113,7 +117,7 @@ public:
* to several commands.
*/
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
@ -121,7 +125,8 @@ public:
*/
virtual SharedHandle<Piece> getMissingPiece
(const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes) = 0;
const std::vector<size_t>& 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<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.
@ -140,7 +148,7 @@ public:
* then returns 0.
* 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.
@ -161,7 +169,7 @@ public:
/**
* 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.

View File

@ -123,6 +123,7 @@ SharedHandle<Segment> SegmentMan::checkoutSegment
A2_LOG_DEBUG(fmt("Attach segment#%lu to CUID#%lld.",
static_cast<unsigned long>(piece->getIndex()),
cuid));
piece->setUsedBySegment(true);
SharedHandle<Segment> segment;
if(piece->getLength() == 0) {
segment.reset(new GrowSegment(piece));
@ -175,7 +176,8 @@ SharedHandle<Segment> SegmentMan::getSegment(cuid_t cuid, size_t minSplitSize)
SharedHandle<Piece> 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<Segment> SegmentMan::getSegmentWithIndex
if(index > 0 && downloadContext_->getNumPieces() <= index) {
return SharedHandle<Segment>();
}
return checkoutSegment(cuid, pieceStorage_->getMissingPiece(index));
return checkoutSegment(cuid, pieceStorage_->getMissingPiece(index, cuid));
}
SharedHandle<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle
@ -249,11 +252,14 @@ SharedHandle<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle
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",
static_cast<unsigned long>(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<unsigned long>(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<SharedHandle<SegmentEntry> >::iterator itr =
usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end();
itr != eoi; ++itr) {
cancelSegment((*itr)->segment);
cancelSegmentInternal((*itr)->cuid, (*itr)->segment);
}
usedSegmentEntries_.clear();
}

View File

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

View File

@ -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<size_t> metadataRequests = tracker_->getAllTrackedIndex();
SharedHandle<Piece> p =
pieceStorage->getMissingPiece(peer_, metadataRequests);
pieceStorage->getMissingPiece(peer_, metadataRequests, cuid_);
if(!p) {
A2_LOG_DEBUG("No ut_metadata piece is available to download.");
break;

View File

@ -40,6 +40,7 @@
#include <vector>
#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

View File

@ -81,7 +81,8 @@ bool UnknownLengthPieceStorage::hasMissingPiece(const SharedHandle<Peer>& peer)
void UnknownLengthPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
const SharedHandle<Peer>& peer,
cuid_t cuid)
{
abort();
}
@ -90,15 +91,8 @@ void UnknownLengthPieceStorage::getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes)
{
abort();
}
void UnknownLengthPieceStorage::getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer)
const std::vector<size_t>& excludedIndexes,
cuid_t cuid)
{
abort();
}
@ -107,18 +101,32 @@ 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();
}
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();
}
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();
}
@ -130,7 +138,10 @@ bool UnknownLengthPieceStorage::hasMissingUnusedPiece()
}
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_) {
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) {
return getMissingPiece(0, 0, 0);
return getMissingPiece(0, 0, 0, cuid);
} else {
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) {
piece_.reset();

View File

@ -76,29 +76,37 @@ public:
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
const SharedHandle<Peer>& peer,
cuid_t cuid);
virtual void getMissingPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer,
const std::vector<size_t>& excludedIndexes);
virtual void getMissingFastPiece
(std::vector<SharedHandle<Piece> >& pieces,
size_t minMissingBlocks,
const SharedHandle<Peer>& peer);
const std::vector<size_t>& excludedIndexes,
cuid_t cuid);
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);
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, 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
virtual bool hasMissingUnusedPiece();
@ -107,7 +115,10 @@ public:
* Returns a missing piece if available. Otherwise returns 0;
*/
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.
@ -115,7 +126,7 @@ public:
* then returns 0.
* 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.
@ -131,7 +142,7 @@ public:
/**
* 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.

View File

@ -88,16 +88,17 @@ void DefaultPieceStorageTest::testGetMissingPiece() {
pss.setPieceSelector(pieceSelector_);
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"),
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<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(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<size_t> excludedIndexes;
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"),
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<size_t> excludedIndexes;
excludedIndexes.push_back(1);
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(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> piece = pss.getMissingFastPiece(peer);
SharedHandle<Piece> 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<size_t> excludedIndexes;
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"),
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> piece = pss.getMissingPiece(peer);
SharedHandle<Piece> 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<Piece> incompletePiece = pss.getMissingPiece(peer);
SharedHandle<Piece> incompletePiece = pss.getMissingPiece(peer, 1);
incompletePiece->completeBlock(0);
CPPUNIT_ASSERT_EQUAL((uint64_t)256ULL, pss.getCompletedLength());
}
@ -272,14 +274,16 @@ void DefaultPieceStorageTest::testCancelPiece()
SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, option_.get()));
SharedHandle<Piece> p = ps->getMissingPiece(0);
SharedHandle<Piece> p = ps->getMissingPiece(0, 1);
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->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> piece = pss.getMissingPiece(2);
SharedHandle<Piece> 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));
}

View File

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

View File

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