Use RequestSlot as pointer to avoid copying

pull/103/head
Tatsuhiro Tsujikawa 2013-06-30 00:31:50 +09:00
parent d128a39fb6
commit 03ae308faa
11 changed files with 183 additions and 349 deletions

View File

@ -79,12 +79,12 @@ public:
virtual bool isOutstandingRequest(size_t index, size_t blockIndex) = 0; virtual bool isOutstandingRequest(size_t index, size_t blockIndex) = 0;
virtual RequestSlot getOutstandingRequest virtual const RequestSlot* getOutstandingRequest
(size_t index, int32_t begin, int32_t length) = 0; (size_t index, int32_t begin, int32_t length) = 0;
virtual void removeOutstandingRequest(const RequestSlot& slot) = 0; virtual void removeOutstandingRequest(const RequestSlot* slot) = 0;
virtual void addOutstandingRequest(const RequestSlot& slot) = 0; virtual void addOutstandingRequest(std::unique_ptr<RequestSlot> slot) = 0;
virtual size_t countOutstandingUpload() = 0; virtual size_t countOutstandingUpload() = 0;
}; };

View File

@ -103,11 +103,11 @@ void BtPieceMessage::doReceivedAction()
if(isMetadataGetMode()) { if(isMetadataGetMode()) {
return; return;
} }
RequestSlot slot = getBtMessageDispatcher()->getOutstandingRequest auto slot = getBtMessageDispatcher()->getOutstandingRequest
(index_, begin_, blockLength_); (index_, begin_, blockLength_);
getPeer()->updateDownloadLength(blockLength_); getPeer()->updateDownloadLength(blockLength_);
downloadContext_->updateDownloadLength(blockLength_); downloadContext_->updateDownloadLength(blockLength_);
if(!RequestSlot::isNull(slot)) { if(slot) {
getPeer()->snubbing(false); getPeer()->snubbing(false);
std::shared_ptr<Piece> piece = getPieceStorage()->getPiece(index_); std::shared_ptr<Piece> piece = getPieceStorage()->getPiece(index_);
int64_t offset = int64_t offset =
@ -118,8 +118,8 @@ void BtPieceMessage::doReceivedAction()
begin_, begin_,
blockLength_, blockLength_,
static_cast<int64_t>(offset), static_cast<int64_t>(offset),
static_cast<unsigned long>(slot.getBlockIndex()))); static_cast<unsigned long>(slot->getBlockIndex())));
if(piece->hasBlock(slot.getBlockIndex())) { if(piece->hasBlock(slot->getBlockIndex())) {
A2_LOG_DEBUG("Already have this block."); A2_LOG_DEBUG("Already have this block.");
return; return;
} }
@ -134,7 +134,7 @@ void BtPieceMessage::doReceivedAction()
getPieceStorage()->getDiskAdaptor()->writeData(data_+9, blockLength_, getPieceStorage()->getDiskAdaptor()->writeData(data_+9, blockLength_,
offset); offset);
} }
piece->completeBlock(slot.getBlockIndex()); piece->completeBlock(slot->getBlockIndex());
A2_LOG_DEBUG(fmt(MSG_PIECE_BITFIELD, getCuid(), A2_LOG_DEBUG(fmt(MSG_PIECE_BITFIELD, getCuid(),
util::toHex(piece->getBitfield(), util::toHex(piece->getBitfield(),
piece->getBitfieldLength()).c_str())); piece->getBitfieldLength()).c_str()));

View File

@ -65,13 +65,12 @@ void BtRejectMessage::doReceivedAction()
} }
// TODO Current implementation does not close a connection even if // TODO Current implementation does not close a connection even if
// a request for this reject message has never sent. // a request for this reject message has never sent.
RequestSlot slot = auto slot = getBtMessageDispatcher()->getOutstandingRequest
getBtMessageDispatcher()->getOutstandingRequest
(getIndex(), getBegin(), getLength()); (getIndex(), getBegin(), getLength());
if(RequestSlot::isNull(slot)) { if(slot) {
//throw DL_ABORT_EX("reject received, but it is not in the request slots.");
} else {
getBtMessageDispatcher()->removeOutstandingRequest(slot); getBtMessageDispatcher()->removeOutstandingRequest(slot);
} else {
//throw DL_ABORT_EX("reject received, but it is not in the request slots.");
} }
} }

View File

@ -79,9 +79,9 @@ void BtRequestMessage::doReceivedAction()
void BtRequestMessage::onQueued() void BtRequestMessage::onQueued()
{ {
RequestSlot requestSlot(getIndex(), getBegin(), getLength(), blockIndex_, getBtMessageDispatcher()->addOutstandingRequest
getPieceStorage()->getPiece(getIndex())); (make_unique<RequestSlot>(getIndex(), getBegin(), getLength(), blockIndex_,
getBtMessageDispatcher()->addOutstandingRequest(requestSlot); getPieceStorage()->getPiece(getIndex())));
} }
void BtRequestMessage::onAbortOutstandingRequestEvent void BtRequestMessage::onAbortOutstandingRequestEvent

View File

@ -143,40 +143,33 @@ void DefaultBtMessageDispatcher::doCancelSendingPieceAction
namespace { namespace {
void abortOutstandingRequest void abortOutstandingRequest
(const RequestSlot& slot, const std::shared_ptr<Piece>& piece, cuid_t cuid) (const RequestSlot* slot, const std::shared_ptr<Piece>& piece, cuid_t cuid)
{ {
A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT, A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT,
cuid, cuid,
static_cast<unsigned long>(slot.getIndex()), static_cast<unsigned long>(slot->getIndex()),
slot.getBegin(), slot->getBegin(),
static_cast<unsigned long>(slot.getBlockIndex()))); static_cast<unsigned long>(slot->getBlockIndex())));
piece->cancelBlock(slot.getBlockIndex()); piece->cancelBlock(slot->getBlockIndex());
} }
} // namespace } // namespace
namespace {
struct FindRequestSlotByIndex {
size_t index;
FindRequestSlotByIndex(size_t index) : index(index) {}
bool operator()(const RequestSlot& slot) const
{
return slot.getIndex() == index;
}
};
} // namespace
// localhost cancels outstanding download requests to the peer. // localhost cancels outstanding download requests to the peer.
void DefaultBtMessageDispatcher::doAbortOutstandingRequestAction void DefaultBtMessageDispatcher::doAbortOutstandingRequestAction
(const std::shared_ptr<Piece>& piece) { (const std::shared_ptr<Piece>& piece) {
for(std::deque<RequestSlot>::iterator itr = requestSlots_.begin(), for(auto& slot : requestSlots_) {
eoi = requestSlots_.end(); itr != eoi; ++itr) { if(slot->getIndex() == piece->getIndex()) {
if((*itr).getIndex() == piece->getIndex()) { abortOutstandingRequest(slot.get(), piece, cuid_);
abortOutstandingRequest(*itr, piece, cuid_);
} }
} }
requestSlots_.erase(std::remove_if(requestSlots_.begin(), requestSlots_.end(), requestSlots_.erase
FindRequestSlotByIndex(piece->getIndex())), (std::remove_if(std::begin(requestSlots_),
requestSlots_.end()); std::end(requestSlots_),
[&](const std::unique_ptr<RequestSlot>& slot)
{
return slot->getIndex() == piece->getIndex();
}),
std::end(requestSlots_));
BtAbortOutstandingRequestEvent event(piece); BtAbortOutstandingRequestEvent event(piece);
@ -187,60 +180,26 @@ void DefaultBtMessageDispatcher::doAbortOutstandingRequestAction
} }
} }
namespace {
class ProcessChokedRequestSlot {
private:
cuid_t cuid_;
std::shared_ptr<Peer> peer_;
PieceStorage* pieceStorage_;
public:
ProcessChokedRequestSlot
(cuid_t cuid, const std::shared_ptr<Peer>& peer, PieceStorage* pieceStorage)
: cuid_(cuid),
peer_(peer),
pieceStorage_(pieceStorage)
{}
void operator()(const RequestSlot& slot) const
{
if(!peer_->isInPeerAllowedIndexSet(slot.getIndex())) {
A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT_CHOKED,
cuid_,
static_cast<unsigned long>(slot.getIndex()),
slot.getBegin(),
static_cast<unsigned long>(slot.getBlockIndex())));
std::shared_ptr<Piece> piece = pieceStorage_->getPiece(slot.getIndex());
piece->cancelBlock(slot.getBlockIndex());
}
}
};
} // namespace
namespace {
class FindChokedRequestSlot {
private:
std::shared_ptr<Peer> peer_;
public:
FindChokedRequestSlot(const std::shared_ptr<Peer>& peer):
peer_(peer) {}
bool operator()(const RequestSlot& slot) const
{
return !peer_->isInPeerAllowedIndexSet(slot.getIndex());
}
};
} // namespace
// localhost received choke message from the peer. // localhost received choke message from the peer.
void DefaultBtMessageDispatcher::doChokedAction() void DefaultBtMessageDispatcher::doChokedAction()
{ {
std::for_each(requestSlots_.begin(), requestSlots_.end(), for(auto& slot : requestSlots_) {
ProcessChokedRequestSlot(cuid_, peer_, pieceStorage_)); if(!peer_->isInPeerAllowedIndexSet(slot->getIndex())) {
A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT_CHOKED,
requestSlots_.erase(std::remove_if(requestSlots_.begin(), requestSlots_.end(), cuid_,
FindChokedRequestSlot(peer_)), static_cast<unsigned long>(slot->getIndex()),
requestSlots_.end()); slot->getBegin(),
static_cast<unsigned long>(slot->getBlockIndex())));
slot->getPiece()->cancelBlock(slot->getBlockIndex());
}
}
requestSlots_.erase
(std::remove_if(std::begin(requestSlots_), std::end(requestSlots_),
[&](const std::unique_ptr<RequestSlot>& slot)
{
return !peer_->isInPeerAllowedIndexSet(slot->getIndex());
}),
std::end(requestSlots_));
} }
// localhost dispatched choke message to the peer. // localhost dispatched choke message to the peer.
@ -255,93 +214,38 @@ void DefaultBtMessageDispatcher::doChokingAction()
} }
} }
namespace {
class ProcessStaleRequestSlot {
private:
cuid_t cuid_;
std::shared_ptr<Peer> peer_;
PieceStorage* pieceStorage_;
BtMessageDispatcher* messageDispatcher_;
BtMessageFactory* messageFactory_;
time_t requestTimeout_;
public:
ProcessStaleRequestSlot
(cuid_t cuid, const std::shared_ptr<Peer>& peer,
PieceStorage* pieceStorage,
BtMessageDispatcher* dispatcher,
BtMessageFactory* factory,
time_t requestTimeout)
: cuid_(cuid),
peer_(peer),
pieceStorage_(pieceStorage),
messageDispatcher_(dispatcher),
messageFactory_(factory),
requestTimeout_(requestTimeout)
{}
void operator()(const RequestSlot& slot)
{
if(slot.isTimeout(requestTimeout_)) {
A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT_TIMEOUT,
cuid_,
static_cast<unsigned long>(slot.getIndex()),
slot.getBegin(),
static_cast<unsigned long>(slot.getBlockIndex())));
slot.getPiece()->cancelBlock(slot.getBlockIndex());
peer_->snubbing(true);
} else if(slot.getPiece()->hasBlock(slot.getBlockIndex())) {
A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT_ACQUIRED,
cuid_,
static_cast<unsigned long>(slot.getIndex()),
slot.getBegin(),
static_cast<unsigned long>(slot.getBlockIndex())));
messageDispatcher_->addMessageToQueue
(messageFactory_->createCancelMessage(slot.getIndex(),
slot.getBegin(),
slot.getLength()));
}
}
};
} // namespace
namespace {
class FindStaleRequestSlot {
private:
PieceStorage* pieceStorage_;
time_t requestTimeout_;
public:
FindStaleRequestSlot(PieceStorage* pieceStorage, time_t requestTimeout)
: pieceStorage_(pieceStorage),
requestTimeout_(requestTimeout) {}
bool operator()(const RequestSlot& slot)
{
if(slot.isTimeout(requestTimeout_)) {
return true;
} else {
if(slot.getPiece()->hasBlock(slot.getBlockIndex())) {
return true;
} else {
return false;
}
}
}
};
} // namespace
void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing() void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing()
{ {
std::for_each(requestSlots_.begin(), requestSlots_.end(), for(auto& slot : requestSlots_) {
ProcessStaleRequestSlot(cuid_, if(slot->isTimeout(requestTimeout_)) {
peer_, A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT_TIMEOUT,
pieceStorage_, cuid_,
this, static_cast<unsigned long>(slot->getIndex()),
messageFactory_, slot->getBegin(),
requestTimeout_)); static_cast<unsigned long>(slot->getBlockIndex())));
requestSlots_.erase(std::remove_if(requestSlots_.begin(), requestSlots_.end(), slot->getPiece()->cancelBlock(slot->getBlockIndex());
FindStaleRequestSlot(pieceStorage_, peer_->snubbing(true);
requestTimeout_)), } else if(slot->getPiece()->hasBlock(slot->getBlockIndex())) {
requestSlots_.end()); A2_LOG_DEBUG(fmt(MSG_DELETING_REQUEST_SLOT_ACQUIRED,
cuid_,
static_cast<unsigned long>(slot->getIndex()),
slot->getBegin(),
static_cast<unsigned long>(slot->getBlockIndex())));
addMessageToQueue
(messageFactory_->createCancelMessage(slot->getIndex(),
slot->getBegin(),
slot->getLength()));
}
}
requestSlots_.erase
(std::remove_if(std::begin(requestSlots_), std::end(requestSlots_),
[&](const std::unique_ptr<RequestSlot>& slot)
{
return slot->isTimeout(requestTimeout_) ||
slot->getPiece()->hasBlock(slot->getBlockIndex());
}),
std::end(requestSlots_));
} }
bool DefaultBtMessageDispatcher::isSendingInProgress() bool DefaultBtMessageDispatcher::isSendingInProgress()
@ -349,63 +253,47 @@ bool DefaultBtMessageDispatcher::isSendingInProgress()
return peerConnection_->getBufferEntrySize(); return peerConnection_->getBufferEntrySize();
} }
namespace {
class BlockIndexLess {
public:
bool operator()(const RequestSlot& lhs, const RequestSlot& rhs) const
{
if(lhs.getIndex() == rhs.getIndex()) {
return lhs.getBlockIndex() < rhs.getBlockIndex();
} else {
return lhs.getIndex() < rhs.getIndex();
}
}
};
} // namespace
bool DefaultBtMessageDispatcher::isOutstandingRequest bool DefaultBtMessageDispatcher::isOutstandingRequest
(size_t index, size_t blockIndex) { (size_t index, size_t blockIndex) {
for(std::deque<RequestSlot>::const_iterator itr = requestSlots_.begin(), for(auto& slot : requestSlots_) {
eoi = requestSlots_.end(); itr != eoi; ++itr) { if(slot->getIndex() == index && slot->getBlockIndex() == blockIndex) {
if((*itr).getIndex() == index && (*itr).getBlockIndex() == blockIndex) {
return true; return true;
} }
} }
return false; return false;
} }
RequestSlot const RequestSlot*
DefaultBtMessageDispatcher::getOutstandingRequest DefaultBtMessageDispatcher::getOutstandingRequest
(size_t index, int32_t begin, int32_t length) (size_t index, int32_t begin, int32_t length)
{ {
for(std::deque<RequestSlot>::const_iterator itr = requestSlots_.begin(), for(auto& slot : requestSlots_) {
eoi = requestSlots_.end(); itr != eoi; ++itr) { if(slot->getIndex() == index &&
if((*itr).getIndex() == index && slot->getBegin() == begin &&
(*itr).getBegin() == begin && slot->getLength() == length) {
(*itr).getLength() == length) { return slot.get();
return *itr;
} }
} }
return RequestSlot::nullSlot; return nullptr;
} }
void DefaultBtMessageDispatcher::removeOutstandingRequest void DefaultBtMessageDispatcher::removeOutstandingRequest
(const RequestSlot& slot) (const RequestSlot* slot)
{ {
for(std::deque<RequestSlot>::iterator itr = requestSlots_.begin(), for(auto i = std::begin(requestSlots_), eoi = std::end(requestSlots_);
eoi = requestSlots_.end(); itr != eoi; ++itr) { i != eoi; ++i) {
if(*itr == slot) { if(*(*i) == *slot) {
abortOutstandingRequest(*itr, slot.getPiece(), cuid_); abortOutstandingRequest((*i).get(), (*i)->getPiece(), cuid_);
requestSlots_.erase(itr); requestSlots_.erase(i);
break; break;
} }
} }
} }
void DefaultBtMessageDispatcher::addOutstandingRequest void DefaultBtMessageDispatcher::addOutstandingRequest
(const RequestSlot& slot) (std::unique_ptr<RequestSlot> slot)
{ {
requestSlots_.push_back(slot); requestSlots_.push_back(std::move(slot));
} }
size_t DefaultBtMessageDispatcher::countOutstandingUpload() size_t DefaultBtMessageDispatcher::countOutstandingUpload()

View File

@ -58,7 +58,7 @@ class DefaultBtMessageDispatcher : public BtMessageDispatcher {
private: private:
cuid_t cuid_; cuid_t cuid_;
std::deque<std::shared_ptr<BtMessage> > messageQueue_; std::deque<std::shared_ptr<BtMessage> > messageQueue_;
std::deque<RequestSlot> requestSlots_; std::deque<std::unique_ptr<RequestSlot>> requestSlots_;
DownloadContext* downloadContext_; DownloadContext* downloadContext_;
PeerStorage* peerStorage_; PeerStorage* peerStorage_;
PieceStorage* pieceStorage_; PieceStorage* pieceStorage_;
@ -108,12 +108,12 @@ public:
virtual bool isOutstandingRequest(size_t index, size_t blockIndex); virtual bool isOutstandingRequest(size_t index, size_t blockIndex);
virtual RequestSlot getOutstandingRequest virtual const RequestSlot* getOutstandingRequest
(size_t index, int32_t begin, int32_t length); (size_t index, int32_t begin, int32_t length);
virtual void removeOutstandingRequest(const RequestSlot& slot); virtual void removeOutstandingRequest(const RequestSlot* slot);
virtual void addOutstandingRequest(const RequestSlot& requestSlot); virtual void addOutstandingRequest(std::unique_ptr<RequestSlot> requestSlot);
virtual size_t countOutstandingUpload(); virtual size_t countOutstandingUpload();
@ -122,7 +122,7 @@ public:
return messageQueue_; return messageQueue_;
} }
const std::deque<RequestSlot>& getRequestSlots() const const std::deque<std::unique_ptr<RequestSlot>>& getRequestSlots() const
{ {
return requestSlots_; return requestSlots_;
} }

View File

@ -36,8 +36,6 @@
namespace aria2 { namespace aria2 {
RequestSlot RequestSlot::nullSlot = RequestSlot();
void RequestSlot::setDispatchedTime(time_t sec) { void RequestSlot::setDispatchedTime(time_t sec) {
dispatchedTime_.reset(sec); dispatchedTime_.reset(sec);
} }
@ -46,9 +44,4 @@ bool RequestSlot::isTimeout(time_t timeoutSec) const {
return dispatchedTime_.difference(global::wallclock()) >= timeoutSec; return dispatchedTime_.difference(global::wallclock()) >= timeoutSec;
} }
bool RequestSlot::isNull(const RequestSlot& requestSlot) {
return requestSlot.index_ == 0 && requestSlot.begin_ == 0&&
requestSlot.length_ == 0;
}
} // namespace aria2 } // namespace aria2

View File

@ -43,60 +43,14 @@
namespace aria2 { namespace aria2 {
class RequestSlot { class RequestSlot {
private:
Timer dispatchedTime_;
size_t index_;
int32_t begin_;
int32_t length_;
size_t blockIndex_;
// This is the piece whose index is index of this RequestSlot has.
// To detect duplicate RequestSlot, we have to find the piece using
// PieceStorage::getPiece() repeatedly. It turns out that this process
// takes time(about 1.7% of processing time). To reduce it, we put piece here
// at the construction of RequestSlot as a cache.
std::shared_ptr<Piece> piece_;
// inlined for performance reason
void copy(const RequestSlot& requestSlot)
{
dispatchedTime_ = requestSlot.dispatchedTime_;
index_ = requestSlot.index_;
begin_ = requestSlot.begin_;
length_ = requestSlot.length_;
blockIndex_ = requestSlot.blockIndex_;
piece_ = requestSlot.piece_;
}
public: public:
RequestSlot(size_t index, int32_t begin, int32_t length, size_t blockIndex, RequestSlot(size_t index, int32_t begin, int32_t length, size_t blockIndex,
const std::shared_ptr<Piece>& piece = std::shared_ptr<Piece>()): const std::shared_ptr<Piece>& piece = std::shared_ptr<Piece>())
dispatchedTime_(global::wallclock()), : dispatchedTime_(global::wallclock()),
index_(index), begin_(begin), length_(length), blockIndex_(blockIndex), index_(index), begin_(begin), length_(length), blockIndex_(blockIndex),
piece_(piece) {} piece_(piece)
RequestSlot(const RequestSlot& requestSlot):
dispatchedTime_(requestSlot.dispatchedTime_),
index_(requestSlot.index_),
begin_(requestSlot.begin_),
length_(requestSlot.length_),
blockIndex_(requestSlot.blockIndex_),
piece_(requestSlot.piece_) {}
RequestSlot():dispatchedTime_(0), index_(0), begin_(0), length_(0),
blockIndex_(0)
{} {}
~RequestSlot() {}
RequestSlot& operator=(const RequestSlot& requestSlot)
{
if(this != &requestSlot) {
copy(requestSlot);
}
return *this;
}
bool operator==(const RequestSlot& requestSlot) const bool operator==(const RequestSlot& requestSlot) const
{ {
return index_ == requestSlot.index_ && begin_ == requestSlot.begin_ return index_ == requestSlot.index_ && begin_ == requestSlot.begin_
@ -137,10 +91,19 @@ public:
{ {
return piece_; return piece_;
} }
private:
Timer dispatchedTime_;
size_t index_;
int32_t begin_;
int32_t length_;
size_t blockIndex_;
static RequestSlot nullSlot; // This is the piece whose index is index of this RequestSlot has.
// To detect duplicate RequestSlot, we have to find the piece using
static bool isNull(const RequestSlot& requestSlot); // PieceStorage::getPiece() repeatedly. It turns out that this process
// takes time(about 1.7% of processing time). To reduce it, we put piece here
// at the construction of RequestSlot as a cache.
std::shared_ptr<Piece> piece_;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -33,29 +33,30 @@ public:
class MockBtMessageDispatcher2 : public MockBtMessageDispatcher { class MockBtMessageDispatcher2 : public MockBtMessageDispatcher {
public: public:
RequestSlot slot; std::unique_ptr<RequestSlot> slot;
public:
MockBtMessageDispatcher2():slot(RequestSlot::nullSlot) {}
void setRequestSlot(const RequestSlot& slot) { void setRequestSlot(std::unique_ptr<RequestSlot> s)
this->slot = slot; {
slot = std::move(s);
} }
virtual RequestSlot getOutstandingRequest virtual const RequestSlot* getOutstandingRequest
(size_t index, int32_t begin, int32_t length) { (size_t index, int32_t begin, int32_t length) override {
if(slot.getIndex() == index && slot.getBegin() == begin && if(slot &&
slot.getLength() == length) { slot->getIndex() == index && slot->getBegin() == begin &&
return slot; slot->getLength() == length) {
return slot.get();
} else { } else {
return RequestSlot::nullSlot; return nullptr;
} }
} }
virtual void removeOutstandingRequest(const RequestSlot& slot) { virtual void removeOutstandingRequest(const RequestSlot* s) override
if(this->slot.getIndex() == slot.getIndex() && {
this->slot.getBegin() == slot.getBegin() && if(slot->getIndex() == s->getIndex() &&
this->slot.getLength() == slot.getLength()) { slot->getBegin() == s->getBegin() &&
this->slot = RequestSlot::nullSlot; slot->getLength() == s->getLength()) {
slot.reset();
} }
} }
}; };
@ -131,39 +132,32 @@ void BtRejectMessageTest::testCreateMessage() {
void BtRejectMessageTest::testDoReceivedAction() { void BtRejectMessageTest::testDoReceivedAction() {
peer->setFastExtensionEnabled(true); peer->setFastExtensionEnabled(true);
RequestSlot slot(1, 16, 32, 2); dispatcher->setRequestSlot(make_unique<RequestSlot>(1, 16, 32, 2));
dispatcher->setRequestSlot(slot);
CPPUNIT_ASSERT CPPUNIT_ASSERT(dispatcher->getOutstandingRequest(1, 16, 32));
(!RequestSlot::isNull(dispatcher->getOutstandingRequest(1, 16, 32)));
msg->doReceivedAction(); msg->doReceivedAction();
CPPUNIT_ASSERT CPPUNIT_ASSERT(!dispatcher->getOutstandingRequest(1, 16, 32));
(RequestSlot::isNull(dispatcher->getOutstandingRequest(1, 16, 32)));
} }
void BtRejectMessageTest::testDoReceivedActionNoMatch() { void BtRejectMessageTest::testDoReceivedActionNoMatch() {
peer->setFastExtensionEnabled(true); peer->setFastExtensionEnabled(true);
RequestSlot slot(2, 16, 32, 2); dispatcher->setRequestSlot(make_unique<RequestSlot>(2, 16, 32, 2));
dispatcher->setRequestSlot(slot);
CPPUNIT_ASSERT CPPUNIT_ASSERT(dispatcher->getOutstandingRequest(2, 16, 32));
(!RequestSlot::isNull(dispatcher->getOutstandingRequest(2, 16, 32)));
msg->doReceivedAction(); msg->doReceivedAction();
CPPUNIT_ASSERT CPPUNIT_ASSERT(dispatcher->getOutstandingRequest(2, 16, 32));
(!RequestSlot::isNull(dispatcher->getOutstandingRequest(2, 16, 32)));
} }
void BtRejectMessageTest::testDoReceivedActionFastExtensionDisabled() { void BtRejectMessageTest::testDoReceivedActionFastExtensionDisabled() {
RequestSlot slot(1, 16, 32, 2); RequestSlot slot(1, 16, 32, 2);
dispatcher->setRequestSlot(slot); dispatcher->setRequestSlot(make_unique<RequestSlot>(1, 16, 32, 2));
CPPUNIT_ASSERT CPPUNIT_ASSERT(dispatcher->getOutstandingRequest(1, 16, 32));
(!RequestSlot::isNull(dispatcher->getOutstandingRequest(1, 16, 32)));
try { try {
msg->doReceivedAction(); msg->doReceivedAction();
CPPUNIT_FAIL("exception must be thrown."); CPPUNIT_FAIL("exception must be thrown.");

View File

@ -248,9 +248,7 @@ void DefaultBtMessageDispatcherTest::testDoCancelSendingPieceAction() {
int MY_PIECE_LENGTH = 16*1024; int MY_PIECE_LENGTH = 16*1024;
void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() { void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
std::shared_ptr<Piece> piece(new Piece(0, MY_PIECE_LENGTH)); auto piece = std::make_shared<Piece>(0, MY_PIECE_LENGTH);
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
size_t index; size_t index;
CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index)); CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index));
CPPUNIT_ASSERT_EQUAL((size_t)0, index); CPPUNIT_ASSERT_EQUAL((size_t)0, index);
@ -260,7 +258,8 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
btMessageDispatcher->setRequestTimeout(60); btMessageDispatcher->setRequestTimeout(60);
btMessageDispatcher->setPieceStorage(pieceStorage.get()); btMessageDispatcher->setPieceStorage(pieceStorage.get());
btMessageDispatcher->addOutstandingRequest(slot); btMessageDispatcher->addOutstandingRequest
(make_unique<RequestSlot>(0, 0, MY_PIECE_LENGTH, 0, piece));
btMessageDispatcher->checkRequestSlotAndDoNecessaryThing(); btMessageDispatcher->checkRequestSlotAndDoNecessaryThing();
@ -270,12 +269,9 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
btMessageDispatcher->getRequestSlots().size()); btMessageDispatcher->getRequestSlots().size());
} }
void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_timeout() { void DefaultBtMessageDispatcherTest::
std::shared_ptr<Piece> piece(new Piece(0, MY_PIECE_LENGTH)); testCheckRequestSlotAndDoNecessaryThing_timeout() {
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece); auto piece = std::make_shared<Piece>(0, MY_PIECE_LENGTH);
// make this slot timeout
slot.setDispatchedTime(0);
size_t index; size_t index;
CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index)); CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index));
CPPUNIT_ASSERT_EQUAL((size_t)0, index); CPPUNIT_ASSERT_EQUAL((size_t)0, index);
@ -285,8 +281,10 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_tim
btMessageDispatcher->setRequestTimeout(60); btMessageDispatcher->setRequestTimeout(60);
btMessageDispatcher->setPieceStorage(pieceStorage.get()); btMessageDispatcher->setPieceStorage(pieceStorage.get());
btMessageDispatcher->addOutstandingRequest(slot); auto slot = make_unique<RequestSlot>(0, 0, MY_PIECE_LENGTH, 0, piece);
// make this slot timeout
slot->setDispatchedTime(0);
btMessageDispatcher->addOutstandingRequest(std::move(slot));
btMessageDispatcher->checkRequestSlotAndDoNecessaryThing(); btMessageDispatcher->checkRequestSlotAndDoNecessaryThing();
CPPUNIT_ASSERT_EQUAL((size_t)0, CPPUNIT_ASSERT_EQUAL((size_t)0,
@ -297,18 +295,17 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_tim
CPPUNIT_ASSERT_EQUAL(true, peer->snubbing()); CPPUNIT_ASSERT_EQUAL(true, peer->snubbing());
} }
void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_completeBlock() { void DefaultBtMessageDispatcherTest::
std::shared_ptr<Piece> piece(new Piece(0, MY_PIECE_LENGTH)); testCheckRequestSlotAndDoNecessaryThing_completeBlock() {
auto piece = std::make_shared<Piece>(0, MY_PIECE_LENGTH);
piece->completeBlock(0); piece->completeBlock(0);
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
auto pieceStorage = make_unique<MockPieceStorage2>(); auto pieceStorage = make_unique<MockPieceStorage2>();
pieceStorage->setPiece(piece); pieceStorage->setPiece(piece);
btMessageDispatcher->setRequestTimeout(60); btMessageDispatcher->setRequestTimeout(60);
btMessageDispatcher->setPieceStorage(pieceStorage.get()); btMessageDispatcher->setPieceStorage(pieceStorage.get());
btMessageDispatcher->addOutstandingRequest(slot); btMessageDispatcher->addOutstandingRequest
(make_unique<RequestSlot>(0, 0, MY_PIECE_LENGTH, 0, piece));
btMessageDispatcher->checkRequestSlotAndDoNecessaryThing(); btMessageDispatcher->checkRequestSlotAndDoNecessaryThing();
@ -319,15 +316,15 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_com
} }
void DefaultBtMessageDispatcherTest::testCountOutstandingRequest() { void DefaultBtMessageDispatcherTest::testCountOutstandingRequest() {
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0); btMessageDispatcher->addOutstandingRequest
btMessageDispatcher->addOutstandingRequest(slot); (make_unique<RequestSlot>(0, 0, MY_PIECE_LENGTH, 0));
CPPUNIT_ASSERT_EQUAL((size_t)1, CPPUNIT_ASSERT_EQUAL((size_t)1,
btMessageDispatcher->countOutstandingRequest()); btMessageDispatcher->countOutstandingRequest());
} }
void DefaultBtMessageDispatcherTest::testIsOutstandingRequest() { void DefaultBtMessageDispatcherTest::testIsOutstandingRequest() {
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0); btMessageDispatcher->addOutstandingRequest
btMessageDispatcher->addOutstandingRequest(slot); (make_unique<RequestSlot>(0, 0, MY_PIECE_LENGTH, 0));
CPPUNIT_ASSERT(btMessageDispatcher->isOutstandingRequest(0, 0)); CPPUNIT_ASSERT(btMessageDispatcher->isOutstandingRequest(0, 0));
CPPUNIT_ASSERT(!btMessageDispatcher->isOutstandingRequest(0, 1)); CPPUNIT_ASSERT(!btMessageDispatcher->isOutstandingRequest(0, 1));
@ -336,42 +333,42 @@ void DefaultBtMessageDispatcherTest::testIsOutstandingRequest() {
} }
void DefaultBtMessageDispatcherTest::testGetOutstandingRequest() { void DefaultBtMessageDispatcherTest::testGetOutstandingRequest() {
RequestSlot slot(1, 1024, 16*1024, 10); btMessageDispatcher->addOutstandingRequest
btMessageDispatcher->addOutstandingRequest(slot); (make_unique<RequestSlot>(1, 1024, 16*1024, 10));
RequestSlot s2 = btMessageDispatcher->getOutstandingRequest(1, 1024, 16*1024); CPPUNIT_ASSERT(btMessageDispatcher->getOutstandingRequest(1, 1024, 16*1024));
CPPUNIT_ASSERT(!RequestSlot::isNull(s2));
RequestSlot s3 = btMessageDispatcher->getOutstandingRequest(1, 1024, 17*1024); CPPUNIT_ASSERT(!btMessageDispatcher->
CPPUNIT_ASSERT(RequestSlot::isNull(s3)); getOutstandingRequest(1, 1024, 17*1024));
RequestSlot s4 = CPPUNIT_ASSERT(!btMessageDispatcher->
btMessageDispatcher->getOutstandingRequest(1, 2*1024, 16*1024); getOutstandingRequest(1, 2*1024, 16*1024));
CPPUNIT_ASSERT(RequestSlot::isNull(s4));
RequestSlot s5 = btMessageDispatcher->getOutstandingRequest(2, 1024, 16*1024); CPPUNIT_ASSERT(!btMessageDispatcher->
CPPUNIT_ASSERT(RequestSlot::isNull(s5)); getOutstandingRequest(2, 1024, 16*1024));
} }
void DefaultBtMessageDispatcherTest::testRemoveOutstandingRequest() { void DefaultBtMessageDispatcherTest::testRemoveOutstandingRequest() {
std::shared_ptr<Piece> piece(new Piece(1, 1024*1024)); auto piece = std::make_shared<Piece>(1, 1024*1024);
size_t blockIndex = 0; size_t blockIndex = 0;
CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(blockIndex)); CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(blockIndex));
uint32_t begin = blockIndex*piece->getBlockLength(); uint32_t begin = blockIndex*piece->getBlockLength();
size_t length = piece->getBlockLength(blockIndex); size_t length = piece->getBlockLength(blockIndex);
RequestSlot slot(piece->getIndex(), begin, length, blockIndex, piece); RequestSlot slot;
btMessageDispatcher->addOutstandingRequest(slot); btMessageDispatcher->addOutstandingRequest
(make_unique<RequestSlot>(piece->getIndex(), begin, length, blockIndex,
piece));
RequestSlot s2 = btMessageDispatcher->getOutstandingRequest auto s2 = btMessageDispatcher->getOutstandingRequest(piece->getIndex(),
(piece->getIndex(), begin, length); begin, length);
CPPUNIT_ASSERT(!RequestSlot::isNull(s2)); CPPUNIT_ASSERT(s2);
CPPUNIT_ASSERT(piece->isBlockUsed(blockIndex)); CPPUNIT_ASSERT(piece->isBlockUsed(blockIndex));
btMessageDispatcher->removeOutstandingRequest(s2); btMessageDispatcher->removeOutstandingRequest(s2);
RequestSlot s3 = btMessageDispatcher->getOutstandingRequest auto s3 = btMessageDispatcher->getOutstandingRequest(piece->getIndex(),
(piece->getIndex(), begin, length); begin, length);
CPPUNIT_ASSERT(RequestSlot::isNull(s3)); CPPUNIT_ASSERT(!s3);
CPPUNIT_ASSERT(!piece->isBlockUsed(blockIndex)); CPPUNIT_ASSERT(!piece->isBlockUsed(blockIndex));
} }

View File

@ -57,14 +57,14 @@ public:
return false; return false;
} }
virtual RequestSlot getOutstandingRequest virtual const RequestSlot* getOutstandingRequest
(size_t index, int32_t begin, int32_t length) { (size_t index, int32_t begin, int32_t length) {
return RequestSlot::nullSlot; return nullptr;
} }
virtual void removeOutstandingRequest(const RequestSlot& slot) {} virtual void removeOutstandingRequest(const RequestSlot* slot) {}
virtual void addOutstandingRequest(const RequestSlot& slot) {} virtual void addOutstandingRequest(std::unique_ptr<RequestSlot> slot) {}
virtual size_t countOutstandingUpload() virtual size_t countOutstandingUpload()
{ {