|
@@ -43,6 +43,7 @@
|
|
|
#include "LogFactory.h"
|
|
|
#include "Logger.h"
|
|
|
#include "Util.h"
|
|
|
+#include "a2functional.h"
|
|
|
#include <cstring>
|
|
|
#include <algorithm>
|
|
|
|
|
@@ -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)
|
|
|
- {
|
|
|
- memcpy(_infoHash, infoHash, DHT_ID_LENGTH);
|
|
|
- }
|
|
|
-
|
|
|
- bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& entry) const
|
|
|
+ bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& lhs,
|
|
|
+ const SharedHandle<DHTPeerAnnounceEntry>& rhs)
|
|
|
{
|
|
|
- return memcmp(_infoHash, entry->getInfoHash(), DHT_ID_LENGTH) == 0;
|
|
|
+ return memcmp(lhs->getInfoHash(), rhs->getInfoHash(), DHT_ID_LENGTH) < 0;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
SharedHandle<DHTPeerAnnounceEntry>
|
|
|
DHTPeerAnnounceStorage::getPeerAnnounceEntry(const unsigned char* infoHash)
|
|
|
{
|
|
|
+ SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
|
|
|
+
|
|
|
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
|
|
|
- std::find_if(_entries.begin(), _entries.end(), FindPeerAnnounceEntry(infoHash));
|
|
|
- SharedHandle<DHTPeerAnnounceEntry> 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<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(
|
|
|
+ ctx->getInfoHash()));
|
|
|
+
|
|
|
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::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<BtContext>());
|
|
|
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<DHTPeerAnnounceEntry> 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<SharedHandle<Peer> >& peers,
|
|
|
const unsigned char* infoHash)
|
|
|
{
|
|
|
+ SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
|
|
|
+
|
|
|
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::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);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void DHTPeerAnnounceStorage::handleTimeout()
|
|
|
+class RemoveStalePeerAddrEntry
|
|
|
{
|
|
|
- _logger->debug("Now purge peer announces which are timed out.");
|
|
|
- size_t numPeerAddr = 0;
|
|
|
- for(std::deque<SharedHandle<DHTPeerAnnounceEntry> >::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;
|
|
|
- }
|
|
|
+public:
|
|
|
+ void operator()(const SharedHandle<DHTPeerAnnounceEntry>& e)
|
|
|
+ {
|
|
|
+ e->removeStalePeerAddrEntry(DHT_PEER_ANNOUNCE_PURGE_INTERVAL);
|
|
|
}
|
|
|
- _logger->debug("Currently %zu peer announce entries, %zu PeerAddr entries",
|
|
|
- _entries.size(), numPeerAddr);
|
|
|
+};
|
|
|
+
|
|
|
+void DHTPeerAnnounceStorage::handleTimeout()
|
|
|
+{
|
|
|
+ _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()
|