From 4b3e5825425b470180d4310818e290d87821044a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 17 May 2008 06:10:52 +0000 Subject: [PATCH] 2008-05-17 Tatsuhiro Tsujikawa Sorted DHTPeerAnnounceEntry in a ascending order of info hash and used lower_bound to process them rather than linear search. * src/DHTPeerAnnounceStorage.cc --- ChangeLog | 6 +++ src/DHTPeerAnnounceStorage.cc | 82 ++++++++++++++++++++--------------- 2 files changed, 52 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c0dda0d..17953784 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-05-17 Tatsuhiro Tsujikawa + + Sorted DHTPeerAnnounceEntry in a ascending order of info hash and + used lower_bound to process them rather than linear search. + * src/DHTPeerAnnounceStorage.cc + 2008-05-17 Tatsuhiro Tsujikawa Call subtractPieceStats from ~PeerInteractionCommand only when the diff --git a/src/DHTPeerAnnounceStorage.cc b/src/DHTPeerAnnounceStorage.cc index ad27da5d..33b34ab8 100644 --- a/src/DHTPeerAnnounceStorage.cc +++ b/src/DHTPeerAnnounceStorage.cc @@ -43,6 +43,7 @@ #include "LogFactory.h" #include "Logger.h" #include "Util.h" +#include "a2functional.h" #include #include @@ -53,32 +54,29 @@ DHTPeerAnnounceStorage::DHTPeerAnnounceStorage(): DHTPeerAnnounceStorage::~DHTPeerAnnounceStorage() {} -class FindPeerAnnounceEntry { -private: - unsigned char _infoHash[DHT_ID_LENGTH]; +class InfoHashLess +{ public: - FindPeerAnnounceEntry(const unsigned char* infoHash) + bool operator()(const SharedHandle& lhs, + const SharedHandle& rhs) { - memcpy(_infoHash, infoHash, DHT_ID_LENGTH); - } - - bool operator()(const SharedHandle& entry) const - { - return memcmp(_infoHash, entry->getInfoHash(), DHT_ID_LENGTH) == 0; + return memcmp(lhs->getInfoHash(), rhs->getInfoHash(), DHT_ID_LENGTH) < 0; } }; SharedHandle DHTPeerAnnounceStorage::getPeerAnnounceEntry(const unsigned char* infoHash) { + SharedHandle entry(new DHTPeerAnnounceEntry(infoHash)); + std::deque >::iterator i = - std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash)); - SharedHandle entry; - if(i == _entries.end()) { - entry.reset(new DHTPeerAnnounceEntry(infoHash)); - _entries.push_back(entry); - } else { + std::lower_bound(_entries.begin(), _entries.end(), entry, InfoHashLess()); + + if(i != _entries.end() && + memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0) { entry = *i; + } else { + _entries.insert(i, entry); } return entry; } @@ -102,9 +100,14 @@ void DHTPeerAnnounceStorage::addPeerAnnounce(const BtContextHandle& ctx) void DHTPeerAnnounceStorage::removePeerAnnounce(const BtContextHandle& ctx) { + SharedHandle entry(new DHTPeerAnnounceEntry( + ctx->getInfoHash())); + std::deque >::iterator i = - std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(ctx->getInfoHash())); - if(i != _entries.end()) { + std::lower_bound(_entries.begin(), _entries.end(), entry, InfoHashLess()); + + if(i != _entries.end() && + memcmp(ctx->getInfoHash(), (*i)->getInfoHash(), DHT_ID_LENGTH) == 0) { (*i)->setBtContext(SharedHandle()); if((*i)->empty()) { _entries.erase(i); @@ -114,37 +117,44 @@ void DHTPeerAnnounceStorage::removePeerAnnounce(const BtContextHandle& ctx) bool DHTPeerAnnounceStorage::contains(const unsigned char* infoHash) const { + SharedHandle entry(new DHTPeerAnnounceEntry(infoHash)); return - std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash)) != _entries.end(); + std::binary_search(_entries.begin(), _entries.end(), entry, InfoHashLess()); } void DHTPeerAnnounceStorage::getPeers(std::deque >& peers, const unsigned char* infoHash) { + SharedHandle entry(new DHTPeerAnnounceEntry(infoHash)); + std::deque >::iterator i = - std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash)); - if(i != _entries.end() && !(*i)->empty()) { + std::lower_bound(_entries.begin(), _entries.end(), entry, InfoHashLess()); + if(i != _entries.end() && + memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0 && + !(*i)->empty()) { (*i)->getPeers(peers); } } +class RemoveStalePeerAddrEntry +{ +public: + void operator()(const SharedHandle& e) + { + e->removeStalePeerAddrEntry(DHT_PEER_ANNOUNCE_PURGE_INTERVAL); + } +}; + void DHTPeerAnnounceStorage::handleTimeout() { - _logger->debug("Now purge peer announces which are timed out."); - size_t numPeerAddr = 0; - for(std::deque >::iterator i = _entries.begin(); i != _entries.end();) { - (*i)->removeStalePeerAddrEntry(DHT_PEER_ANNOUNCE_PURGE_INTERVAL); - if((*i)->empty()) { - _logger->debug("1 entry purged: infoHash=%s", - Util::toHex((*i)->getInfoHash(), DHT_ID_LENGTH).c_str()); - i = _entries.erase(i); - } else { - numPeerAddr += (*i)->countPeerAddrEntry(); - ++i; - } - } - _logger->debug("Currently %zu peer announce entries, %zu PeerAddr entries", - _entries.size(), numPeerAddr); + _logger->debug("Now purge peer announces(%zu entries) which are timed out.", + _entries.size()); + + std::for_each(_entries.begin(), _entries.end(), RemoveStalePeerAddrEntry()); + _entries.erase(std::remove_if(_entries.begin(), _entries.end(), + mem_fun_sh(&DHTPeerAnnounceEntry::empty)), + _entries.end()); + _logger->debug("Currently %zu peer announce entries", _entries.size()); } void DHTPeerAnnounceStorage::announcePeer()