浏览代码

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
Tatsuhiro Tsujikawa 17 年之前
父节点
当前提交
4b3e582542
共有 2 个文件被更改,包括 52 次插入36 次删除
  1. 6 0
      ChangeLog
  2. 46 36
      src/DHTPeerAnnounceStorage.cc

+ 6 - 0
ChangeLog

@@ -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>
 
 	Call subtractPieceStats from ~PeerInteractionCommand only when the

+ 46 - 36
src/DHTPeerAnnounceStorage.cc

@@ -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()