2008-05-17 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Sorted DHTPeerAnnounceEntry in a ascending order of info hash 
and
	used lower_bound to process them rather than linear search.
	* src/DHTPeerAnnounceStorage.cc
pull/1/head
Tatsuhiro Tsujikawa 2008-05-17 06:10:52 +00:00
parent 73a2599a04
commit 4b3e582542
2 changed files with 52 additions and 36 deletions

View File

@ -1,3 +1,9 @@
2008-05-17 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
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 <tujikawa at rednoah dot com> 2008-05-17 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Call subtractPieceStats from ~PeerInteractionCommand only when the Call subtractPieceStats from ~PeerInteractionCommand only when the

View File

@ -43,6 +43,7 @@
#include "LogFactory.h" #include "LogFactory.h"
#include "Logger.h" #include "Logger.h"
#include "Util.h" #include "Util.h"
#include "a2functional.h"
#include <cstring> #include <cstring>
#include <algorithm> #include <algorithm>
@ -53,32 +54,29 @@ DHTPeerAnnounceStorage::DHTPeerAnnounceStorage():
DHTPeerAnnounceStorage::~DHTPeerAnnounceStorage() {} DHTPeerAnnounceStorage::~DHTPeerAnnounceStorage() {}
class FindPeerAnnounceEntry { class InfoHashLess
private: {
unsigned char _infoHash[DHT_ID_LENGTH];
public: public:
FindPeerAnnounceEntry(const unsigned char* infoHash) bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& lhs,
const SharedHandle<DHTPeerAnnounceEntry>& rhs)
{ {
memcpy(_infoHash, infoHash, DHT_ID_LENGTH); return memcmp(lhs->getInfoHash(), rhs->getInfoHash(), DHT_ID_LENGTH) < 0;
}
bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& entry) const
{
return memcmp(_infoHash, entry->getInfoHash(), DHT_ID_LENGTH) == 0;
} }
}; };
SharedHandle<DHTPeerAnnounceEntry> SharedHandle<DHTPeerAnnounceEntry>
DHTPeerAnnounceStorage::getPeerAnnounceEntry(const unsigned char* infoHash) DHTPeerAnnounceStorage::getPeerAnnounceEntry(const unsigned char* infoHash)
{ {
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i = std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash)); std::lower_bound(_entries.begin(), _entries.end(), entry, InfoHashLess());
SharedHandle<DHTPeerAnnounceEntry> entry;
if(i == _entries.end()) { if(i != _entries.end() &&
entry.reset(new DHTPeerAnnounceEntry(infoHash)); memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0) {
_entries.push_back(entry);
} else {
entry = *i; entry = *i;
} else {
_entries.insert(i, entry);
} }
return entry; return entry;
} }
@ -102,9 +100,14 @@ void DHTPeerAnnounceStorage::addPeerAnnounce(const BtContextHandle& ctx)
void DHTPeerAnnounceStorage::removePeerAnnounce(const BtContextHandle& ctx) void DHTPeerAnnounceStorage::removePeerAnnounce(const BtContextHandle& ctx)
{ {
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(
ctx->getInfoHash()));
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i = std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(ctx->getInfoHash())); std::lower_bound(_entries.begin(), _entries.end(), entry, InfoHashLess());
if(i != _entries.end()) {
if(i != _entries.end() &&
memcmp(ctx->getInfoHash(), (*i)->getInfoHash(), DHT_ID_LENGTH) == 0) {
(*i)->setBtContext(SharedHandle<BtContext>()); (*i)->setBtContext(SharedHandle<BtContext>());
if((*i)->empty()) { if((*i)->empty()) {
_entries.erase(i); _entries.erase(i);
@ -114,37 +117,44 @@ void DHTPeerAnnounceStorage::removePeerAnnounce(const BtContextHandle& ctx)
bool DHTPeerAnnounceStorage::contains(const unsigned char* infoHash) const bool DHTPeerAnnounceStorage::contains(const unsigned char* infoHash) const
{ {
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
return 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<SharedHandle<Peer> >& peers, void DHTPeerAnnounceStorage::getPeers(std::deque<SharedHandle<Peer> >& peers,
const unsigned char* infoHash) const unsigned char* infoHash)
{ {
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i = std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash)); std::lower_bound(_entries.begin(), _entries.end(), entry, InfoHashLess());
if(i != _entries.end() && !(*i)->empty()) { if(i != _entries.end() &&
memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0 &&
!(*i)->empty()) {
(*i)->getPeers(peers); (*i)->getPeers(peers);
} }
} }
class RemoveStalePeerAddrEntry
{
public:
void operator()(const SharedHandle<DHTPeerAnnounceEntry>& e)
{
e->removeStalePeerAddrEntry(DHT_PEER_ANNOUNCE_PURGE_INTERVAL);
}
};
void DHTPeerAnnounceStorage::handleTimeout() void DHTPeerAnnounceStorage::handleTimeout()
{ {
_logger->debug("Now purge peer announces which are timed out."); _logger->debug("Now purge peer announces(%zu entries) which are timed out.",
size_t numPeerAddr = 0; _entries.size());
for(std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i = _entries.begin(); i != _entries.end();) {
(*i)->removeStalePeerAddrEntry(DHT_PEER_ANNOUNCE_PURGE_INTERVAL); std::for_each(_entries.begin(), _entries.end(), RemoveStalePeerAddrEntry());
if((*i)->empty()) { _entries.erase(std::remove_if(_entries.begin(), _entries.end(),
_logger->debug("1 entry purged: infoHash=%s", mem_fun_sh(&DHTPeerAnnounceEntry::empty)),
Util::toHex((*i)->getInfoHash(), DHT_ID_LENGTH).c_str()); _entries.end());
i = _entries.erase(i); _logger->debug("Currently %zu peer announce entries", _entries.size());
} else {
numPeerAddr += (*i)->countPeerAddrEntry();
++i;
}
}
_logger->debug("Currently %zu peer announce entries, %zu PeerAddr entries",
_entries.size(), numPeerAddr);
} }
void DHTPeerAnnounceStorage::announcePeer() void DHTPeerAnnounceStorage::announcePeer()