Don't use sorted std::deque for requestSlots_.

Don't use sorted deque for requestSlots_. For the most time, first
data requested is sent back first. So using std::deque, we find
received RequestSlot by O(1), while sorted std::deque requires
O(logN).
pull/1/head
Tatsuhiro Tsujikawa 2011-08-10 23:18:23 +09:00
parent 6ee913b0bc
commit 2d9323651b
1 changed files with 49 additions and 52 deletions

View File

@ -142,24 +142,25 @@ void DefaultBtMessageDispatcher::doCancelSendingPieceAction
} }
namespace { namespace {
class AbortOutstandingRequest { void abortOutstandingRequest
private: (const RequestSlot& slot, const SharedHandle<Piece>& piece, cuid_t cuid)
SharedHandle<Piece> piece_; {
cuid_t cuid_;
public:
AbortOutstandingRequest(const SharedHandle<Piece>& piece, cuid_t cuid)
: piece_(piece),
cuid_(cuid)
{}
void operator()(const RequestSlot& slot) const
{
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 {
struct FindRequestSlotByIndex {
size_t index;
FindRequestSlotByIndex(size_t index) : index(index) {}
bool operator()(const RequestSlot& slot) const
{
return slot.getIndex() == index;
} }
}; };
} // namespace } // namespace
@ -167,16 +168,15 @@ public:
// localhost cancels outstanding download requests to the peer. // localhost cancels outstanding download requests to the peer.
void DefaultBtMessageDispatcher::doAbortOutstandingRequestAction void DefaultBtMessageDispatcher::doAbortOutstandingRequestAction
(const SharedHandle<Piece>& piece) { (const SharedHandle<Piece>& piece) {
RequestSlot rs(piece->getIndex(), 0, 0, 0); for(std::deque<RequestSlot>::iterator itr = requestSlots_.begin(),
std::deque<RequestSlot>::iterator first = eoi = requestSlots_.end(); itr != eoi; ++itr) {
std::lower_bound(requestSlots_.begin(), requestSlots_.end(), rs); if((*itr).getIndex() == piece->getIndex()) {
abortOutstandingRequest(*itr, piece, cuid_);
rs.setIndex(piece->getIndex()+1); }
std::deque<RequestSlot>::iterator last = }
std::lower_bound(requestSlots_.begin(), requestSlots_.end(), rs); requestSlots_.erase(std::remove_if(requestSlots_.begin(), requestSlots_.end(),
FindRequestSlotByIndex(piece->getIndex())),
std::for_each(first, last, AbortOutstandingRequest(piece, cuid_)); requestSlots_.end());
requestSlots_.erase(first, last);
BtAbortOutstandingRequestEvent event(piece); BtAbortOutstandingRequestEvent event(piece);
@ -370,50 +370,47 @@ public:
bool DefaultBtMessageDispatcher::isOutstandingRequest bool DefaultBtMessageDispatcher::isOutstandingRequest
(size_t index, size_t blockIndex) { (size_t index, size_t blockIndex) {
RequestSlot rs(index, 0, 0, blockIndex); for(std::deque<RequestSlot>::const_iterator itr = requestSlots_.begin(),
eoi = requestSlots_.end(); itr != eoi; ++itr) {
std::deque<RequestSlot>::iterator i = if((*itr).getIndex() == index && (*itr).getBlockIndex() == blockIndex) {
std::lower_bound(requestSlots_.begin(), requestSlots_.end(), return true;
rs, BlockIndexLess()); }
return i != requestSlots_.end() && }
(*i).getIndex() == index && (*i).getBlockIndex() == blockIndex; return false;
} }
RequestSlot RequestSlot
DefaultBtMessageDispatcher::getOutstandingRequest DefaultBtMessageDispatcher::getOutstandingRequest
(size_t index, uint32_t begin, size_t length) (size_t index, uint32_t begin, size_t length)
{ {
RequestSlot ret; for(std::deque<RequestSlot>::const_iterator itr = requestSlots_.begin(),
RequestSlot rs(index, begin, length, 0); eoi = requestSlots_.end(); itr != eoi; ++itr) {
std::deque<RequestSlot>::iterator i = if((*itr).getIndex() == index &&
std::lower_bound(requestSlots_.begin(), requestSlots_.end(), rs); (*itr).getBegin() == begin &&
if(i != requestSlots_.end() && (*i) == rs) { (*itr).getLength() == length) {
ret = *i; return *itr;
} else {
ret = RequestSlot::nullSlot;
} }
return ret; }
return RequestSlot::nullSlot;
} }
void DefaultBtMessageDispatcher::removeOutstandingRequest void DefaultBtMessageDispatcher::removeOutstandingRequest
(const RequestSlot& slot) (const RequestSlot& slot)
{ {
std::deque<RequestSlot>::iterator i = for(std::deque<RequestSlot>::iterator itr = requestSlots_.begin(),
std::lower_bound(requestSlots_.begin(), requestSlots_.end(), slot); eoi = requestSlots_.end(); itr != eoi; ++itr) {
if(i != requestSlots_.end() && (*i) == slot) { if(*itr == slot) {
AbortOutstandingRequest(slot.getPiece(), cuid_)(*i); abortOutstandingRequest(*itr, slot.getPiece(), cuid_);
requestSlots_.erase(i); requestSlots_.erase(itr);
break;
}
} }
} }
void DefaultBtMessageDispatcher::addOutstandingRequest void DefaultBtMessageDispatcher::addOutstandingRequest
(const RequestSlot& slot) (const RequestSlot& slot)
{ {
std::deque<RequestSlot>::iterator i = requestSlots_.push_back(slot);
std::lower_bound(requestSlots_.begin(), requestSlots_.end(), slot);
if(i == requestSlots_.end() || (*i) != slot) {
requestSlots_.insert(i, slot);
}
} }
size_t DefaultBtMessageDispatcher::countOutstandingUpload() size_t DefaultBtMessageDispatcher::countOutstandingUpload()