Pārlūkot izejas kodu

Use std::set instead of std::deque if the elements are sorted and
insertions and deletions are frequent.

Tatsuhiro Tsujikawa 13 gadi atpakaļ
vecāks
revīzija
eed804baaa

+ 24 - 26
src/AuthConfigFactory.cc

@@ -64,20 +64,21 @@ AuthConfigFactory::createAuthConfig
 
     if(op->getAsBool(PREF_HTTP_AUTH_CHALLENGE)) {
       if(!request->getUsername().empty()) {
-        updateBasicCred(BasicCred(request->getUsername(),
-                                  request->getPassword(),
-                                  request->getHost(),
-                                  request->getPort(),
-                                  request->getDir(), true));
+        SharedHandle<BasicCred> bc(new BasicCred(request->getUsername(),
+                                                 request->getPassword(),
+                                                 request->getHost(),
+                                                 request->getPort(),
+                                                 request->getDir(), true));
+        updateBasicCred(bc);
         return createAuthConfig(request->getUsername(), request->getPassword());
       }
-      std::deque<BasicCred>::const_iterator i =
+      BasicCredSet::iterator i =
         findBasicCred(request->getHost(), request->getPort(),
                       request->getDir());
       if(i == basicCreds_.end()) {
         return SharedHandle<AuthConfig>();
       } else {
-        return createAuthConfig((*i).user_, (*i).password_);
+        return createAuthConfig((*i)->user_, (*i)->password_);
       }
     } else {
       if(!request->getUsername().empty()) {
@@ -170,13 +171,12 @@ void AuthConfigFactory::setNetrc(const SharedHandle<Netrc>& netrc)
   netrc_ = netrc;
 }
 
-void AuthConfigFactory::updateBasicCred(const BasicCred& basicCred)
+void AuthConfigFactory::updateBasicCred
+(const SharedHandle<BasicCred>& basicCred)
 {
-  std::deque<BasicCred>::iterator i =
-    std::lower_bound(basicCreds_.begin(), basicCreds_.end(), basicCred);
-
-  if(i != basicCreds_.end() && (*i) == basicCred) {
-    (*i) = basicCred;
+  BasicCredSet::iterator i = basicCreds_.lower_bound(basicCred);
+  if(i != basicCreds_.end() && *(*i) == *basicCred) {
+    *(*i) = *basicCred;
   } else {
     basicCreds_.insert(i, basicCred);
   }
@@ -188,22 +188,21 @@ bool AuthConfigFactory::activateBasicCred
  const std::string& path,
  const Option* op)
 {
-
-  std::deque<BasicCred>::iterator i = findBasicCred(host, port, path);
+  BasicCredSet::iterator i = findBasicCred(host, port, path);
   if(i == basicCreds_.end()) {
     SharedHandle<AuthConfig> authConfig =
       createHttpAuthResolver(op)->resolveAuthConfig(host);
     if(!authConfig) {
       return false;
     } else {
-      BasicCred bc(authConfig->getUser(), authConfig->getPassword(),
-                   host, port, path, true);
-      i = std::lower_bound(basicCreds_.begin(), basicCreds_.end(), bc);
-      basicCreds_.insert(i, bc);
+      SharedHandle<BasicCred> bc
+        (new BasicCred(authConfig->getUser(), authConfig->getPassword(),
+                       host, port, path, true));
+      basicCreds_.insert(bc);
       return true;
     }
   } else {
-    (*i).activate();
+    (*i)->activate();
     return true;
   }
 }
@@ -242,18 +241,17 @@ bool AuthConfigFactory::BasicCred::operator<(const BasicCred& cred) const
                                (!(cred.port_ < port_) && path_ > cred.path_)));
 }
 
-std::deque<AuthConfigFactory::BasicCred>::iterator
+AuthConfigFactory::BasicCredSet::iterator
 AuthConfigFactory::findBasicCred
 (const std::string& host,
  uint16_t port,
  const std::string& path)
 {
-  BasicCred bc("", "", host, port, path);
-  std::deque<BasicCred>::iterator i =
-    std::lower_bound(basicCreds_.begin(), basicCreds_.end(), bc);
-  for(; i != basicCreds_.end() && (*i).host_ == host && (*i).port_ == port;
+  SharedHandle<BasicCred> bc(new BasicCred("", "", host, port, path));
+  BasicCredSet::iterator i = basicCreds_.lower_bound(bc);
+  for(; i != basicCreds_.end() && (*i)->host_ == host && (*i)->port_ == port;
       ++i) {
-    if(util::startsWith(bc.path_, (*i).path_)) {
+    if(util::startsWith(bc->path_, (*i)->path_)) {
       return i;
     }
   }

+ 8 - 4
src/AuthConfigFactory.h

@@ -38,10 +38,11 @@
 #include "common.h"
 
 #include <string>
-#include <deque>
+#include <set>
 
 #include "SharedHandle.h"
 #include "SingletonHolder.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -83,8 +84,11 @@ public:
 
     bool operator<(const BasicCred& cred) const;
   };
+
+  typedef std::set<SharedHandle<BasicCred>,
+                   DerefLess<SharedHandle<BasicCred> > > BasicCredSet;
 private:
-  std::deque<BasicCred> basicCreds_;
+  BasicCredSet basicCreds_;
 public:
   
   AuthConfigFactory();
@@ -115,7 +119,7 @@ public:
   // Find a BasicCred using host, port and path and return the
   // iterator pointing to it. If not found, then return
   // basicCreds_.end().
-  std::deque<AuthConfigFactory::BasicCred>::iterator
+  BasicCredSet::iterator
   findBasicCred
   (const std::string& host,
    uint16_t port,
@@ -124,7 +128,7 @@ public:
   // If the same BasicCred is already added, then it is replaced with
   // given basicCred. Otherwise, insert given basicCred to
   // basicCreds_.
-  void updateBasicCred(const BasicCred& basicCred);
+  void updateBasicCred(const SharedHandle<BasicCred>& basicCred);
 
   static const std::string ANONYMOUS;
 

+ 50 - 37
src/CookieStorage.cc

@@ -93,6 +93,21 @@ void swap(CookieStorage::DomainEntry& a, CookieStorage::DomainEntry& b)
   a.swap(b);
 }
 
+void CookieStorage::DomainEntry::findCookie
+(std::vector<Cookie>& out,
+ const std::string& requestHost,
+ const std::string& requestPath,
+ time_t now, bool secure)
+{
+  for(std::deque<Cookie>::iterator i = cookies_.begin(),
+        eoi = cookies_.end(); i != eoi; ++i) {
+    if((*i).match(requestHost, requestPath, now, secure)) {
+      (*i).setLastAccessTime(now);
+      out.push_back(*i);
+    }
+  }
+}
+
 bool CookieStorage::DomainEntry::addCookie(const Cookie& cookie, time_t now)
 {
   setLastAccessTime(now);
@@ -152,6 +167,10 @@ size_t CookieStorage::DomainEntry::countCookie() const
   return cookies_.size();
 }
 
+bool CookieStorage::DomainEntry::operator==(const DomainEntry& de) const
+{
+  return key_ == de.key_;
+}
 
 bool CookieStorage::DomainEntry::operator<(const DomainEntry& de) const
 {
@@ -172,20 +191,21 @@ const double DOMAIN_EVICTION_RATE = 0.1;
 bool CookieStorage::store(const Cookie& cookie, time_t now)
 {
   if(domains_.size() >= DOMAIN_EVICTION_TRIGGER) {
-    std::sort(domains_.begin(), domains_.end(),
+    std::vector<SharedHandle<DomainEntry> > evictions(domains_.begin(),
+                                                      domains_.end());
+    std::sort(evictions.begin(), evictions.end(),
               LeastRecentAccess<DomainEntry>());
-    size_t delnum = (size_t)(domains_.size()*DOMAIN_EVICTION_RATE);
-    domains_.erase(domains_.begin(), domains_.begin()+delnum);
-    std::sort(domains_.begin(), domains_.end());
+    size_t delnum = (size_t)(evictions.size()*DOMAIN_EVICTION_RATE);
+    domains_.clear();
+    domains_.insert(evictions.begin()+delnum, evictions.end());
   }
-  DomainEntry v(cookie.getDomain());
-  std::deque<DomainEntry>::iterator i =
-    std::lower_bound(domains_.begin(), domains_.end(), v);
+  SharedHandle<DomainEntry> v(new DomainEntry(cookie.getDomain()));
+  DomainEntrySet::iterator i = domains_.lower_bound(v);
   bool added = false;
-  if(i != domains_.end() && (*i).getKey() == v.getKey()) {
-    added = (*i).addCookie(cookie, now);
+  if(i != domains_.end() && *(*i) == *v) {
+    added = (*i)->addCookie(cookie, now);
   } else {
-    added = v.addCookie(cookie, now);
+    added = v->addCookie(cookie, now);
     if(added) {
       domains_.insert(i, v);
     }
@@ -264,32 +284,27 @@ public:
 };
 } // namespace
 
-namespace {
-template<typename DomainInputIterator, typename CookieOutputIterator>
-void searchCookieByDomainSuffix
-(const std::string& domain,
- DomainInputIterator first, DomainInputIterator last, CookieOutputIterator out,
+void CookieStorage::searchCookieByDomainSuffix
+(std::vector<Cookie>& out,
+ const std::string& domain,
  const std::string& requestHost,
  const std::string& requestPath,
  time_t now, bool secure)
 {
-  CookieStorage::DomainEntry v(domain);
-  std::deque<CookieStorage::DomainEntry>::iterator i =
-    std::lower_bound(first, last, v);
-  if(i != last && (*i).getKey() == v.getKey()) {
-    (*i).setLastAccessTime(now);
-    (*i).findCookie(out, requestHost, requestPath, now, secure);
+  SharedHandle<DomainEntry> v(new DomainEntry(domain));
+  DomainEntrySet::iterator i = domains_.lower_bound(v);
+  if(i != domains_.end() && *(*i) == *v) {
+    (*i)->setLastAccessTime(now);
+    (*i)->findCookie(out, requestHost, requestPath, now, secure);
   }
 }
-} // namespace
 
 bool CookieStorage::contains(const Cookie& cookie) const
 {
-  CookieStorage::DomainEntry v(cookie.getDomain());
-  std::deque<CookieStorage::DomainEntry>::const_iterator i =
-    std::lower_bound(domains_.begin(), domains_.end(), v);
-  if(i != domains_.end() && (*i).getKey() == v.getKey()) {
-    return (*i).contains(cookie);
+  SharedHandle<DomainEntry> v(new DomainEntry(cookie.getDomain()));
+  DomainEntrySet::iterator i = domains_.find(v);
+  if(i != domains_.end()) {
+    return (*i)->contains(cookie);
   } else {
     return false;
   }
@@ -307,8 +322,7 @@ std::vector<Cookie> CookieStorage::criteriaFind
   }
   if(util::isNumericHost(requestHost)) {
     searchCookieByDomainSuffix
-      (requestHost, domains_.begin(), domains_.end(), std::back_inserter(res),
-       requestHost, requestPath, now, secure);
+      (res, requestHost, requestHost, requestPath, now, secure);
   } else {
     std::vector<Scip> levels;
     util::splitIter(requestHost.begin(), requestHost.end(),
@@ -319,8 +333,7 @@ std::vector<Cookie> CookieStorage::criteriaFind
         i != eoi; ++i, domain.insert(domain.begin(), '.')) {
       domain.insert(domain.begin(), (*i).first, (*i).second);
       searchCookieByDomainSuffix
-        (domain, domains_.begin(), domains_.end(),
-         std::back_inserter(res), requestHost, requestPath, now, secure);
+        (res, domain, requestHost, requestPath, now, secure);
     }
   }
   std::vector<CookiePathDivider> divs;
@@ -335,9 +348,9 @@ std::vector<Cookie> CookieStorage::criteriaFind
 size_t CookieStorage::size() const
 {
   size_t numCookie = 0;
-  for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
-        eoi = domains_.end(); i != eoi; ++i) {
-    numCookie += (*i).countCookie();
+  for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
+      i != eoi; ++i) {
+    numCookie += (*i)->countCookie();
   }
   return numCookie;
 }
@@ -394,9 +407,9 @@ bool CookieStorage::saveNsFormat(const std::string& filename)
       A2_LOG_ERROR(fmt("Cannot create cookie file %s", filename.c_str()));
       return false;
     }
-    for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
-          eoi = domains_.end(); i != eoi; ++i) {
-      if(!(*i).writeCookie(fp)) {
+    for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
+        i != eoi; ++i) {
+      if(!(*i)->writeCookie(fp)) {
         A2_LOG_ERROR(fmt("Failed to save cookies to %s", filename.c_str()));
         return false;
       }

+ 22 - 18
src/CookieStorage.h

@@ -40,10 +40,12 @@
 #include <string>
 #include <deque>
 #include <vector>
+#include <set>
 #include <algorithm>
 
 #include "a2time.h"
 #include "Cookie.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -78,22 +80,11 @@ public:
       return key_;
     }
 
-    template<typename OutputIterator>
-    OutputIterator findCookie
-    (OutputIterator out,
+    void findCookie
+    (std::vector<Cookie>& out,
      const std::string& requestHost,
      const std::string& requestPath,
-     time_t now, bool secure)
-    {
-      for(std::deque<Cookie>::iterator i = cookies_.begin(),
-            eoi = cookies_.end(); i != eoi; ++i) {
-        if((*i).match(requestHost, requestPath, now, secure)) {
-          (*i).setLastAccessTime(now);
-          out++ = *i;
-        }
-      }
-      return out;
-    }
+     time_t now, bool secure);
 
     size_t countCookie() const;
 
@@ -119,10 +110,13 @@ public:
       return std::copy(cookies_.begin(), cookies_.end(), out);
     }
 
+    bool operator==(const DomainEntry& de) const;
     bool operator<(const DomainEntry& de) const;
   };
 private:
-  std::deque<DomainEntry> domains_;
+  typedef std::set<SharedHandle<DomainEntry>,
+                   DerefLess<SharedHandle<DomainEntry> > > DomainEntrySet;
+  DomainEntrySet domains_;
 
   template<typename InputIterator>
   void storeCookies(InputIterator first, InputIterator last, time_t now)
@@ -176,12 +170,22 @@ public:
   // satisfies.
   bool contains(const Cookie& cookie) const;
 
+  // Searches Cookie using given domain, requestHost, requestPath,
+  // current time and secure flag. The found Cookies are stored in
+  // out.
+  void searchCookieByDomainSuffix
+  (std::vector<Cookie>& out,
+   const std::string& domain,
+   const std::string& requestHost,
+   const std::string& requestPath,
+   time_t now, bool secure);
+
   template<typename OutputIterator>
   OutputIterator dumpCookie(OutputIterator out) const
   {
-    for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
-          eoi = domains_.end(); i != eoi; ++i) {
-      out = (*i).dumpCookie(out);
+    for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
+        i != eoi; ++i) {
+      out = (*i)->dumpCookie(out);
     }
     return out;
   }

+ 17 - 21
src/DHTPeerAnnounceStorage.cc

@@ -56,25 +56,19 @@ DHTPeerAnnounceStorage::DHTPeerAnnounceStorage() {}
 
 DHTPeerAnnounceStorage::~DHTPeerAnnounceStorage() {}
 
-namespace {
-class InfoHashLess
+bool DHTPeerAnnounceStorage::InfoHashLess::operator()
+  (const SharedHandle<DHTPeerAnnounceEntry>& lhs,
+   const SharedHandle<DHTPeerAnnounceEntry>& rhs)
 {
-public:
-  bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& lhs,
-                  const SharedHandle<DHTPeerAnnounceEntry>& rhs)
-  {
-    return memcmp(lhs->getInfoHash(), rhs->getInfoHash(), DHT_ID_LENGTH) < 0;
-  }
-};
-} // namespace
+  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::lower_bound(entries_.begin(), entries_.end(), entry, InfoHashLess());
+  DHTPeerAnnounceEntrySet::iterator i = entries_.lower_bound(entry);
 
   if(i != entries_.end() &&
      memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0) {
@@ -107,11 +101,8 @@ void DHTPeerAnnounceStorage::getPeers(std::vector<SharedHandle<Peer> >& peers,
 {
   SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
 
-  std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i = 
-    std::lower_bound(entries_.begin(), entries_.end(), entry, InfoHashLess());
-  if(i != entries_.end() &&
-     memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0 &&
-     !(*i)->empty()) {
+  DHTPeerAnnounceEntrySet::iterator i = entries_.find(entry);
+  if(i != entries_.end()) {
     (*i)->getPeers(peers);
   }
 }
@@ -132,9 +123,14 @@ void DHTPeerAnnounceStorage::handleTimeout()
   A2_LOG_DEBUG(fmt("Now purge peer announces(%lu entries) which are timed out.",
                    static_cast<unsigned long>(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());
+  for(DHTPeerAnnounceEntrySet::iterator i = entries_.begin(),
+        eoi = entries_.end(); i != eoi;) {
+    if((*i)->empty()) {
+      entries_.erase(i++);
+    } else {
+      ++i;
+    }
+  }
   A2_LOG_DEBUG(fmt("Currently %lu peer announce entries",
                    static_cast<unsigned long>(entries_.size())));
 }
@@ -142,7 +138,7 @@ void DHTPeerAnnounceStorage::handleTimeout()
 void DHTPeerAnnounceStorage::announcePeer()
 {
   A2_LOG_DEBUG("Now announcing peer.");
-  for(std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
+  for(DHTPeerAnnounceEntrySet::iterator i =
         entries_.begin(), eoi = entries_.end(); i != eoi; ++i) {
     if((*i)->getLastUpdated().
        difference(global::wallclock()) >= DHT_PEER_ANNOUNCE_INTERVAL) {

+ 9 - 2
src/DHTPeerAnnounceStorage.h

@@ -37,7 +37,7 @@
 
 #include "common.h"
 
-#include <deque>
+#include <set>
 #include <vector>
 #include <string>
 
@@ -52,7 +52,14 @@ class DHTTaskFactory;
 
 class DHTPeerAnnounceStorage {
 private:
-  std::deque<SharedHandle<DHTPeerAnnounceEntry> > entries_;
+  class InfoHashLess {
+  public:
+    bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& lhs,
+                    const SharedHandle<DHTPeerAnnounceEntry>& rhs);
+  };
+  typedef std::set<SharedHandle<DHTPeerAnnounceEntry>, InfoHashLess>
+  DHTPeerAnnounceEntrySet;
+  DHTPeerAnnounceEntrySet entries_;
 
   SharedHandle<DHTPeerAnnounceEntry> getPeerAnnounceEntry(const unsigned char* infoHash);
 

+ 26 - 27
src/DNSCache.cc

@@ -76,9 +76,16 @@ DNSCache::CacheEntry& DNSCache::CacheEntry::operator=(const CacheEntry& c)
   return *this;
 }
 
-void DNSCache::CacheEntry::add(const std::string& addr)
+bool DNSCache::CacheEntry::add(const std::string& addr)
 {
+  for(std::vector<AddrEntry>::const_iterator i = addrEntries_.begin(),
+        eoi = addrEntries_.end(); i != eoi; ++i) {
+    if((*i).addr_ == addr) {
+      return false;
+    }
+  }
   addrEntries_.push_back(AddrEntry(addr));
+  return true;
 }
 
 std::vector<DNSCache::AddrEntry>::iterator DNSCache::CacheEntry::find
@@ -160,50 +167,42 @@ DNSCache& DNSCache::operator=(const DNSCache& c)
 const std::string& DNSCache::find
 (const std::string& hostname, uint16_t port) const
 {
-  CacheEntry target(hostname, port);
-  std::deque<CacheEntry>::const_iterator i =
-    std::lower_bound(entries_.begin(), entries_.end(), target);
-  if(i != entries_.end() && (*i) == target) {
-    return (*i).getGoodAddr();
+  SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
+  CacheEntrySet::iterator i = entries_.find(target);
+  if(i == entries_.end()) {
+    return A2STR::NIL;
+  } else {
+    return (*i)->getGoodAddr();
   }
-  return A2STR::NIL;
 }
 
 void DNSCache::put
 (const std::string& hostname, const std::string& ipaddr, uint16_t port)
 {
-  CacheEntry target(hostname, port);
-  std::deque<CacheEntry>::iterator i =
-    std::lower_bound(entries_.begin(), entries_.end(), target);
-  if(i == entries_.end() || !((*i) == target)) {
-    target.add(ipaddr);
-    entries_.insert(i, target);
+  SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
+  CacheEntrySet::iterator i = entries_.lower_bound(target);
+  if(i != entries_.end() && *(*i) == *target) {
+    (*i)->add(ipaddr);
   } else {
-    if(!(*i).contains(ipaddr)) {
-      (*i).add(ipaddr);
-    }
+    target->add(ipaddr);
+    entries_.insert(i, target);
   }
 }
 
 void DNSCache::markBad
 (const std::string& hostname, const std::string& ipaddr, uint16_t port)
 {
-  CacheEntry target(hostname, port);
-  std::deque<CacheEntry>::iterator i =
-    std::lower_bound(entries_.begin(), entries_.end(), target);
-  if(i != entries_.end() && (*i) == target) {
-    (*i).markBad(ipaddr);
+  SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
+  CacheEntrySet::iterator i = entries_.find(target);
+  if(i != entries_.end()) {
+    (*i)->markBad(ipaddr);
   }
 }
 
 void DNSCache::remove(const std::string& hostname, uint16_t port)
 {
-  CacheEntry target(hostname, port);
-  std::deque<CacheEntry>::iterator i =
-    std::lower_bound(entries_.begin(), entries_.end(), target);
-  if(i != entries_.end() && (*i) == target) {
-    entries_.erase(i);
-  }
+  SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
+  entries_.erase(target);
 }
 
 } // namespace aria2

+ 11 - 9
src/DNSCache.h

@@ -38,10 +38,12 @@
 #include "common.h"
 
 #include <string>
-#include <deque>
+#include <set>
 #include <algorithm>
 #include <vector>
 
+#include "a2functional.h"
+
 namespace aria2 {
 
 class DNSCache {
@@ -68,7 +70,7 @@ private:
 
     CacheEntry& operator=(const CacheEntry& c);
 
-    void add(const std::string& addr);
+    bool add(const std::string& addr);
 
     std::vector<AddrEntry>::iterator find(const std::string& addr);
 
@@ -96,8 +98,9 @@ private:
     bool operator==(const CacheEntry& e) const;
   };
 
-  std::deque<CacheEntry> entries_;
-
+  typedef std::set<SharedHandle<CacheEntry>,
+                   DerefLess<SharedHandle<CacheEntry> > > CacheEntrySet;
+  CacheEntrySet entries_;
 public:
   DNSCache();
   DNSCache(const DNSCache& c);
@@ -111,11 +114,10 @@ public:
   void findAll
   (OutputIterator out, const std::string& hostname, uint16_t port) const
   {
-    CacheEntry target(hostname, port);
-    std::deque<CacheEntry>::const_iterator i =
-      std::lower_bound(entries_.begin(), entries_.end(), target);
-    if(i != entries_.end() && (*i) == target) {
-      (*i).getAllGoodAddrs(out);
+    SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
+    CacheEntrySet::iterator i = entries_.find(target);
+    if(i != entries_.end()) {
+      (*i)->getAllGoodAddrs(out);
     }
   }
 

+ 8 - 20
src/DefaultPieceStorage.cc

@@ -140,10 +140,7 @@ SharedHandle<Piece> DefaultPieceStorage::getPiece(size_t index)
 
 void DefaultPieceStorage::addUsedPiece(const SharedHandle<Piece>& piece)
 {
-  std::deque<SharedHandle<Piece> >::iterator i =
-    std::lower_bound(usedPieces_.begin(), usedPieces_.end(), piece,
-                     DerefLess<SharedHandle<Piece> >());
-  usedPieces_.insert(i, piece);
+  usedPieces_.insert(piece);
   A2_LOG_DEBUG(fmt("usedPieces_.size()=%lu",
                    static_cast<unsigned long>(usedPieces_.size())));
 }
@@ -153,14 +150,12 @@ SharedHandle<Piece> DefaultPieceStorage::findUsedPiece(size_t index) const
   SharedHandle<Piece> p(new Piece());
   p->setIndex(index);
 
-  std::deque<SharedHandle<Piece> >::const_iterator i =
-    std::lower_bound(usedPieces_.begin(), usedPieces_.end(), p,
-                     DerefLess<SharedHandle<Piece> >());
-  if(i != usedPieces_.end() && *(*i) == *p) {
-    return *i;
-  } else {
+  UsedPieceSet::iterator i = usedPieces_.find(p);
+  if(i == usedPieces_.end()) {
     p.reset();
     return p;
+  } else {
+    return *i;
   }
 }
 
@@ -238,7 +233,7 @@ void unsetExcludedIndexes(BitfieldMan& bitfield,
 void DefaultPieceStorage::createFastIndexBitfield
 (BitfieldMan& bitfield, const SharedHandle<Peer>& peer)
 {
-  for(std::vector<size_t>::const_iterator itr =
+  for(std::set<size_t>::const_iterator itr =
         peer->getPeerAllowedIndexSet().begin(),
         eoi = peer->getPeerAllowedIndexSet().end(); itr != eoi; ++itr) {
     if(!bitfieldMan_->isBitSet(*itr) && peer->hasPiece(*itr)) {
@@ -405,12 +400,7 @@ void DefaultPieceStorage::deleteUsedPiece(const SharedHandle<Piece>& piece)
   if(!piece) {
     return;
   }
-  std::deque<SharedHandle<Piece> >::iterator i = 
-    std::lower_bound(usedPieces_.begin(), usedPieces_.end(), piece,
-                     DerefLess<SharedHandle<Piece> >());
-  if(i != usedPieces_.end() && *(*i) == *piece) {
-    usedPieces_.erase(i);
-  }
+  usedPieces_.erase(piece);
 }
 
 // void DefaultPieceStorage::reduceUsedPieces(size_t upperBound)
@@ -758,9 +748,7 @@ void DefaultPieceStorage::markPieceMissing(size_t index)
 void DefaultPieceStorage::addInFlightPiece
 (const std::vector<SharedHandle<Piece> >& pieces)
 {
-  usedPieces_.insert(usedPieces_.end(), pieces.begin(), pieces.end());
-  std::sort(usedPieces_.begin(), usedPieces_.end(),
-            DerefLess<SharedHandle<Piece> >());
+  usedPieces_.insert(pieces.begin(), pieces.end());
 }
 
 size_t DefaultPieceStorage::countInFlightPiece()

+ 6 - 1
src/DefaultPieceStorage.h

@@ -38,6 +38,9 @@
 #include "PieceStorage.h"
 
 #include <deque>
+#include <set>
+
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -76,7 +79,9 @@ private:
   BitfieldMan* bitfieldMan_;
   SharedHandle<DiskAdaptor> diskAdaptor_;
   SharedHandle<DiskWriterFactory> diskWriterFactory_;
-  std::deque<SharedHandle<Piece> > usedPieces_;
+  typedef std::set<SharedHandle<Piece>,
+                   DerefLess<SharedHandle<Piece> > > UsedPieceSet;
+  UsedPieceSet usedPieces_;
 
   bool endGame_;
   size_t endGamePieceNum_;

+ 15 - 23
src/EpollEventPoll.cc

@@ -132,7 +132,7 @@ void EpollEventPoll::poll(const struct timeval& tv)
   // own timeout and ares may create new sockets or closes socket in
   // their API. So we call ares_process_fd for all ares_channel and
   // re-register their sockets.
-  for(std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator i =
+  for(KAsyncNameResolverEntrySet::iterator i =
         nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
       i != eoi; ++i) {
     (*i)->processTimeout();
@@ -169,9 +169,7 @@ bool EpollEventPoll::addEvents(sock_t socket,
                                const EpollEventPoll::KEvent& event)
 {
   SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
-  std::deque<SharedHandle<KSocketEntry> >::iterator i =
-    std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
-                     DerefLess<SharedHandle<KSocketEntry> >());
+  KSocketEntrySet::iterator i = socketEntries_.lower_bound(socketEntry);
   int r = 0;
   int errNum = 0;
   if(i != socketEntries_.end() && *(*i) == *socketEntry) {
@@ -232,13 +230,12 @@ bool EpollEventPoll::deleteEvents(sock_t socket,
                                   const EpollEventPoll::KEvent& event)
 {
   SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
-  std::deque<SharedHandle<KSocketEntry> >::iterator i =
-    std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
-                     DerefLess<SharedHandle<KSocketEntry> >());
-  if(i != socketEntries_.end() && *(*i) == *socketEntry) {
-
+  KSocketEntrySet::iterator i = socketEntries_.find(socketEntry);
+  if(i == socketEntries_.end()) {
+    A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
+    return false;
+  } else {
     event.removeSelf(*i);
-
     int r = 0;
     int errNum = 0;
     if((*i)->eventEmpty()) {
@@ -266,9 +263,6 @@ bool EpollEventPoll::deleteEvents(sock_t socket,
     } else {
       return true;
     }
-  } else {
-    A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
-    return false;
   }
 }
 
@@ -293,15 +287,14 @@ bool EpollEventPoll::addNameResolver
 {
   SharedHandle<KAsyncNameResolverEntry> entry
     (new KAsyncNameResolverEntry(resolver, command));
-  std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
-    std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
-                 derefEqual(entry));
-  if(itr == nameResolverEntries_.end()) {
-    nameResolverEntries_.push_back(entry);
+  KAsyncNameResolverEntrySet::iterator itr =
+    nameResolverEntries_.lower_bound(entry);
+  if(itr != nameResolverEntries_.end() && *(*itr) == *entry) {
+    return false;
+  } else {
+    nameResolverEntries_.insert(itr, entry);
     entry->addSocketEvents(this);
     return true;
-  } else {
-    return false;
   }
 }
 
@@ -310,9 +303,8 @@ bool EpollEventPoll::deleteNameResolver
 {
   SharedHandle<KAsyncNameResolverEntry> entry
     (new KAsyncNameResolverEntry(resolver, command));
-  std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
-    std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
-                 derefEqual(entry));
+  KAsyncNameResolverEntrySet::iterator itr =
+    nameResolverEntries_.find(entry);
   if(itr == nameResolverEntries_.end()) {
     return false;
   } else {

+ 9 - 3
src/EpollEventPoll.h

@@ -39,9 +39,10 @@
 
 # include <sys/epoll.h>
 
-#include <deque>
+#include <set>
 
 #include "Event.h"
+#include "a2functional.h"
 #ifdef ENABLE_ASYNC_DNS
 # include "AsyncNameResolver.h"
 #endif // ENABLE_ASYNC_DNS
@@ -69,9 +70,14 @@ private:
   friend int accumulateEvent(int events, const KEvent& event);
 
 private:
-  std::deque<SharedHandle<KSocketEntry> > socketEntries_;
+  typedef std::set<SharedHandle<KSocketEntry>,
+                   DerefLess<SharedHandle<KSocketEntry> > > KSocketEntrySet;
+  KSocketEntrySet socketEntries_;
 #ifdef ENABLE_ASYNC_DNS
-  std::deque<SharedHandle<KAsyncNameResolverEntry> > nameResolverEntries_;
+  typedef std::set<SharedHandle<KAsyncNameResolverEntry>,
+                   DerefLess<SharedHandle<KAsyncNameResolverEntry> > >
+  KAsyncNameResolverEntrySet;
+  KAsyncNameResolverEntrySet nameResolverEntries_;
 #endif // ENABLE_ASYNC_DNS
 
   int epfd_;

+ 7 - 0
src/Event.h

@@ -327,6 +327,13 @@ public:
       command_ == entry.command_;
   }
 
+  bool operator<(const AsyncNameResolverEntry& entry)
+  {
+    return nameResolver_.get() < entry.nameResolver_.get() ||
+      (nameResolver_.get() == entry.nameResolver_.get() &&
+       command_ < entry.command_);
+  }
+
   void addSocketEvents(EventPoll* e)
   {
     socketsSize_ = 0;

+ 30 - 42
src/FileEntry.cc

@@ -51,6 +51,21 @@
 
 namespace aria2 {
 
+bool FileEntry::RequestFaster::operator()
+  (const SharedHandle<Request>& lhs,
+   const SharedHandle<Request>& rhs) const
+{
+  if(!lhs->getPeerStat()) {
+    return false;
+  }
+  if(!rhs->getPeerStat()) {
+    return true;
+  }
+  int lspd = lhs->getPeerStat()->getAvgDownloadSpeed();
+  int rspd = rhs->getPeerStat()->getAvgDownloadSpeed();
+  return lspd > rspd || (lspd == rspd && lhs.get() < rhs.get());
+}
+
 FileEntry::FileEntry
 (const std::string& path,
  off_t length,
@@ -158,7 +173,7 @@ FileEntry::getRequest
           req->setReferer(util::percentEncodeMini(referer));
           req->setMethod(method);
           spentUris_.push_back(uri);
-          inFlightRequests_.push_back(req);
+          inFlightRequests_.insert(req);
           break;
         } else {
           req.reset();
@@ -177,8 +192,8 @@ FileEntry::getRequest
     // sleeping(Request::getWakeTime() < global::wallclock()).  If all
     // pooled objects are sleeping, return first one.  Caller should
     // inspect returned object's getWakeTime().
-    std::deque<SharedHandle<Request> >::iterator i = requestPool_.begin();
-    std::deque<SharedHandle<Request> >::iterator eoi = requestPool_.end();
+    RequestPool::iterator i = requestPool_.begin();
+    RequestPool::iterator eoi = requestPool_.end();
     for(; i != eoi; ++i) {
       if((*i)->getWakeTime() <= global::wallclock()) {
         break;
@@ -189,7 +204,7 @@ FileEntry::getRequest
     }
     req = *i;
     requestPool_.erase(i);
-    inFlightRequests_.push_back(req);
+    inFlightRequests_.insert(req);
     A2_LOG_DEBUG(fmt("Picked up from pool: %s", req->getUri().c_str()));
   }
   return req;
@@ -203,7 +218,8 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
      lastFasterReplace_.difference(global::wallclock()) < startupIdleTime) {
     return SharedHandle<Request>();
   }
-  const SharedHandle<PeerStat>& fastest = requestPool_.front()->getPeerStat();
+  const SharedHandle<PeerStat>& fastest =
+    (*requestPool_.begin())->getPeerStat();
   if(!fastest) {
     return SharedHandle<Request>();
   }
@@ -214,9 +230,9 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
       difference(global::wallclock()) >= startupIdleTime &&
       fastest->getAvgDownloadSpeed()*0.8 > basestat->calculateDownloadSpeed())){
     // TODO we should consider that "fastest" is very slow.
-    SharedHandle<Request> fastestRequest = requestPool_.front();
-    requestPool_.pop_front();
-    inFlightRequests_.push_back(fastestRequest);
+    SharedHandle<Request> fastestRequest = *requestPool_.begin();
+    requestPool_.erase(requestPool_.begin());
+    inFlightRequests_.insert(fastestRequest);
     lastFasterReplace_ = global::wallclock();
     return fastestRequest;
   }
@@ -279,7 +295,7 @@ FileEntry::findFasterRequest
     fastestRequest->setReferer(base->getReferer());
     uris_.erase(std::find(uris_.begin(), uris_.end(), uri));
     spentUris_.push_back(uri);
-    inFlightRequests_.push_back(fastestRequest);
+    inFlightRequests_.insert(fastestRequest);
     lastFasterReplace_ = global::wallclock();
     return fastestRequest;
   }
@@ -287,24 +303,6 @@ FileEntry::findFasterRequest
   return SharedHandle<Request>();
 }
 
-namespace {
-class RequestFaster {
-public:
-  bool operator()(const SharedHandle<Request>& lhs,
-                  const SharedHandle<Request>& rhs) const
-  {
-    if(!lhs->getPeerStat()) {
-      return false;
-    }
-    if(!rhs->getPeerStat()) {
-      return true;
-    }
-    return
-      lhs->getPeerStat()->getAvgDownloadSpeed() > rhs->getPeerStat()->getAvgDownloadSpeed();
-  }
-};
-} // namespace
-
 void FileEntry::storePool(const SharedHandle<Request>& request)
 {
   const SharedHandle<PeerStat>& peerStat = request->getPeerStat();
@@ -313,10 +311,7 @@ void FileEntry::storePool(const SharedHandle<Request>& request)
     // store Request in the right position in the pool.
     peerStat->calculateAvgDownloadSpeed();
   }
-  std::deque<SharedHandle<Request> >::iterator i =
-    std::lower_bound(requestPool_.begin(), requestPool_.end(), request,
-                     RequestFaster());
-  requestPool_.insert(i, request);
+  requestPool_.insert(request);
 }
 
 void FileEntry::poolRequest(const SharedHandle<Request>& request)
@@ -329,15 +324,7 @@ void FileEntry::poolRequest(const SharedHandle<Request>& request)
 
 bool FileEntry::removeRequest(const SharedHandle<Request>& request)
 {
-  for(std::deque<SharedHandle<Request> >::iterator i =
-        inFlightRequests_.begin(), eoi = inFlightRequests_.end();
-      i != eoi; ++i) {
-    if((*i).get() == request.get()) {
-      inFlightRequests_.erase(i);
-      return true;
-    }
-  }
-  return false;
+  return inFlightRequests_.erase(request) == 1;
 }
 
 void FileEntry::removeURIWhoseHostnameIs(const std::string& hostname)
@@ -500,10 +487,11 @@ bool FileEntry::removeUri(const std::string& uri)
   } else {
     spentUris_.erase(itr);
     SharedHandle<Request> req;
-    std::deque<SharedHandle<Request> >::iterator riter =
+    InFlightRequestSet::iterator riter =
       findRequestByUri(inFlightRequests_.begin(), inFlightRequests_.end(), uri);
     if(riter == inFlightRequests_.end()) {
-      riter = findRequestByUri(requestPool_.begin(), requestPool_.end(), uri);
+      RequestPool::iterator riter = findRequestByUri(requestPool_.begin(),
+                                                     requestPool_.end(), uri);
       if(riter == requestPool_.end()) {
         return true;
       } else {

+ 16 - 3
src/FileEntry.h

@@ -41,6 +41,7 @@
 #include <deque>
 #include <vector>
 #include <ostream>
+#include <set>
 
 #include "SharedHandle.h"
 #include "File.h"
@@ -50,6 +51,7 @@
 #include "A2STR.h"
 #include "TimerA2.h"
 #include "util.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -57,6 +59,9 @@ class URISelector;
 class ServerStatMan;
 
 class FileEntry {
+public:
+  typedef std::set<SharedHandle<Request>, RefLess<Request> >
+  InFlightRequestSet;
 private:
   std::string path_;
   std::deque<std::string> uris_;
@@ -64,8 +69,16 @@ private:
   off_t length_;
   off_t offset_;
   bool requested_;
-  std::deque<SharedHandle<Request> > requestPool_;
-  std::deque<SharedHandle<Request> > inFlightRequests_;
+
+  class RequestFaster {
+  public:
+    bool operator()(const SharedHandle<Request>& lhs,
+                    const SharedHandle<Request>& rhs) const;
+  };
+
+  typedef std::set<SharedHandle<Request>, RequestFaster> RequestPool;
+  RequestPool requestPool_;
+  InFlightRequestSet inFlightRequests_;
   std::string contentType_;
   // URIResult is stored in the ascending order of the time when its result is
   // available.
@@ -186,7 +199,7 @@ public:
 
   size_t countPooledRequest() const;
 
-  const std::deque<SharedHandle<Request> >& getInFlightRequests() const
+  const InFlightRequestSet& getInFlightRequests() const
   {
     return inFlightRequests_;
   }

+ 1 - 1
src/Peer.cc

@@ -287,7 +287,7 @@ size_t Peer::countPeerAllowedIndexSet() const
   return res_->peerAllowedIndexSet().size();
 }
 
-const std::vector<size_t>& Peer::getPeerAllowedIndexSet() const
+const std::set<size_t>& Peer::getPeerAllowedIndexSet() const
 {
   assert(res_);
   return res_->peerAllowedIndexSet();

+ 2 - 2
src/Peer.h

@@ -39,7 +39,7 @@
 
 #include <cassert>
 #include <string>
-#include <vector>
+#include <set>
 #include <algorithm>
 
 #include "SharedHandle.h"
@@ -265,7 +265,7 @@ public:
 
   size_t countPeerAllowedIndexSet() const;
 
-  const std::vector<size_t>& getPeerAllowedIndexSet() const;
+  const std::set<size_t>& getPeerAllowedIndexSet() const;
 
   void addAmAllowedIndex(size_t index);
 

+ 5 - 19
src/PeerSessionResource.cc

@@ -162,43 +162,29 @@ void PeerSessionResource::fastExtensionEnabled(bool b)
   fastExtensionEnabled_ = b;
 }
 
-const std::vector<size_t>& PeerSessionResource::peerAllowedIndexSet() const
+const std::set<size_t>& PeerSessionResource::peerAllowedIndexSet() const
 {
   return peerAllowedIndexSet_;
 }
 
-namespace {
-void updateIndexSet(std::vector<size_t>& c, size_t index)
-{
-  std::vector<size_t>::iterator i = std::lower_bound(c.begin(), c.end(), index);
-  if(i == c.end() || (*i) != index) {
-    c.insert(i, index);
-  } 
-}
-} // namespace
-
 void PeerSessionResource::addPeerAllowedIndex(size_t index)
 {
-  updateIndexSet(peerAllowedIndexSet_, index);
+  peerAllowedIndexSet_.insert(index);
 }
 
 bool PeerSessionResource::peerAllowedIndexSetContains(size_t index) const
 {
-  return std::binary_search(peerAllowedIndexSet_.begin(),
-                            peerAllowedIndexSet_.end(),
-                            index);
+  return peerAllowedIndexSet_.count(index) == 1;
 }
 
 void PeerSessionResource::addAmAllowedIndex(size_t index)
 {
-  updateIndexSet(amAllowedIndexSet_, index);
+  amAllowedIndexSet_.insert(index);
 }
 
 bool PeerSessionResource::amAllowedIndexSetContains(size_t index) const
 {
-  return std::binary_search(amAllowedIndexSet_.begin(),
-                            amAllowedIndexSet_.end(),
-                            index);
+  return amAllowedIndexSet_.count(index) == 1;
 }
 
 void PeerSessionResource::extendedMessagingEnabled(bool b)

+ 5 - 5
src/PeerSessionResource.h

@@ -38,7 +38,7 @@
 #include "common.h"
 
 #include <string>
-#include <vector>
+#include <set>
 
 #include "BtConstants.h"
 #include "PeerStat.h"
@@ -69,9 +69,9 @@ private:
   BitfieldMan* bitfieldMan_;
   bool fastExtensionEnabled_;
   // fast index set which a peer has sent to localhost.
-  std::vector<size_t> peerAllowedIndexSet_;
+  std::set<size_t> peerAllowedIndexSet_;
   // fast index set which localhost has sent to a peer.
-  std::vector<size_t> amAllowedIndexSet_;
+  std::set<size_t> amAllowedIndexSet_;
   bool extendedMessagingEnabled_;
   Extensions extensions_;
   bool dhtEnabled_;
@@ -169,14 +169,14 @@ public:
   void fastExtensionEnabled(bool b);
 
   // fast index set which a peer has sent to localhost.
-  const std::vector<size_t>& peerAllowedIndexSet() const;
+  const std::set<size_t>& peerAllowedIndexSet() const;
 
   void addPeerAllowedIndex(size_t index);
 
   bool peerAllowedIndexSetContains(size_t index) const;
 
   // fast index set which localhost has sent to a peer.
-  const std::vector<size_t>& amAllowedIndexSet() const
+  const std::set<size_t>& amAllowedIndexSet() const
   {
     return amAllowedIndexSet_;
   }

+ 19 - 29
src/PollEventPoll.cc

@@ -101,14 +101,12 @@ void PollEventPoll::poll(const struct timeval& tv)
         first != last; ++first) {
       if(first->revents) {
         se->setSocket(first->fd);
-        std::deque<SharedHandle<KSocketEntry> >::iterator itr =
-          std::lower_bound(socketEntries_.begin(), socketEntries_.end(), se,
-                           DerefLess<SharedHandle<KSocketEntry> >());
-        if(itr != socketEntries_.end() && *(*itr) == *se) {
-          (*itr)->processEvents(first->revents);
-        } else {
+        KSocketEntrySet::iterator itr = socketEntries_.find(se);
+        if(itr == socketEntries_.end()) {
           A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.",
                            first->fd));
+        } else {
+          (*itr)->processEvents(first->revents);
         }
       }
     }
@@ -121,9 +119,8 @@ void PollEventPoll::poll(const struct timeval& tv)
   // own timeout and ares may create new sockets or closes socket in
   // their API. So we call ares_process_fd for all ares_channel and
   // re-register their sockets.
-  for(std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator i =
-        nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
-      i != eoi; ++i) {
+  for(KAsyncNameResolverEntrySet::iterator i = nameResolverEntries_.begin(),
+        eoi = nameResolverEntries_.end(); i != eoi; ++i) {
     (*i)->processTimeout();
     (*i)->removeSocketEvents(this);
     (*i)->addSocketEvents(this);
@@ -156,9 +153,7 @@ bool PollEventPoll::addEvents
 (sock_t socket, const PollEventPoll::KEvent& event)
 {
   SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
-  std::deque<SharedHandle<KSocketEntry> >::iterator i =
-    std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
-                     DerefLess<SharedHandle<KSocketEntry> >());
+  KSocketEntrySet::iterator i = socketEntries_.lower_bound(socketEntry);
   if(i != socketEntries_.end() && *(*i) == *socketEntry) {
     event.addSelf(*i);
     for(struct pollfd* first = pollfds_, *last = pollfds_+pollfdNum_;
@@ -204,10 +199,11 @@ bool PollEventPoll::deleteEvents
 (sock_t socket, const PollEventPoll::KEvent& event)
 {
   SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
-  std::deque<SharedHandle<KSocketEntry> >::iterator i =
-    std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
-                     DerefLess<SharedHandle<KSocketEntry> >());
-  if(i != socketEntries_.end() && *(*i) == *socketEntry) {
+  KSocketEntrySet::iterator i = socketEntries_.find(socketEntry);
+  if(i == socketEntries_.end()) {
+    A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
+    return false;
+  } else {
     event.removeSelf(*i);
     for(struct pollfd* first = pollfds_, *last = pollfds_+pollfdNum_;
         first != last; ++first) {
@@ -225,9 +221,6 @@ bool PollEventPoll::deleteEvents
       }
     }
     return true;
-  } else {
-    A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
-    return false;
   }
 }
 
@@ -252,15 +245,14 @@ bool PollEventPoll::addNameResolver
 {
   SharedHandle<KAsyncNameResolverEntry> entry
     (new KAsyncNameResolverEntry(resolver, command));
-  std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
-    std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
-                 derefEqual(entry));
-  if(itr == nameResolverEntries_.end()) {
-    nameResolverEntries_.push_back(entry);
+  KAsyncNameResolverEntrySet::iterator itr =
+    nameResolverEntries_.lower_bound(entry);
+  if(itr != nameResolverEntries_.end() && *(*itr) == *entry) {
+    return false;
+  } else {
+    nameResolverEntries_.insert(itr, entry);
     entry->addSocketEvents(this);
     return true;
-  } else {
-    return false;
   }
 }
 
@@ -269,9 +261,7 @@ bool PollEventPoll::deleteNameResolver
 {
   SharedHandle<KAsyncNameResolverEntry> entry
     (new KAsyncNameResolverEntry(resolver, command));
-  std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
-    std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
-                 derefEqual(entry));
+  KAsyncNameResolverEntrySet::iterator itr = nameResolverEntries_.find(entry);
   if(itr == nameResolverEntries_.end()) {
     return false;
   } else {

+ 9 - 3
src/PollEventPoll.h

@@ -39,9 +39,10 @@
 
 # include <poll.h>
 
-#include <deque>
+#include <set>
 
 #include "Event.h"
+#include "a2functional.h"
 #ifdef ENABLE_ASYNC_DNS
 # include "AsyncNameResolver.h"
 #endif // ENABLE_ASYNC_DNS
@@ -69,9 +70,14 @@ private:
   friend int accumulateEvent(int events, const KEvent& event);
 
 private:
-  std::deque<SharedHandle<KSocketEntry> > socketEntries_;
+  typedef std::set<SharedHandle<KSocketEntry>,
+                   DerefLess<SharedHandle<KSocketEntry> > > KSocketEntrySet;
+  KSocketEntrySet socketEntries_;
 #ifdef ENABLE_ASYNC_DNS
-  std::deque<SharedHandle<KAsyncNameResolverEntry> > nameResolverEntries_;
+  typedef std::set<SharedHandle<KAsyncNameResolverEntry>,
+                   DerefLess<SharedHandle<KAsyncNameResolverEntry> > >
+  KAsyncNameResolverEntrySet;
+  KAsyncNameResolverEntrySet nameResolverEntries_;
 #endif // ENABLE_ASYNC_DNS
 
   // Allocated the number of struct pollfd in pollfds_.

+ 2 - 2
src/RequestGroupMan.cc

@@ -971,9 +971,9 @@ void RequestGroupMan::getUsedHosts
   std::vector<Triplet<size_t, int, std::string> > tempHosts;
   for(std::deque<SharedHandle<RequestGroup> >::const_iterator i =
         requestGroups_.begin(), eoi = requestGroups_.end(); i != eoi; ++i) {
-    const std::deque<SharedHandle<Request> >& inFlightReqs =
+    const FileEntry::InFlightRequestSet& inFlightReqs =
       (*i)->getDownloadContext()->getFirstFileEntry()->getInFlightRequests();
-    for(std::deque<SharedHandle<Request> >::const_iterator j =
+    for(FileEntry::InFlightRequestSet::iterator j =
           inFlightReqs.begin(), eoj = inFlightReqs.end(); j != eoj; ++j) {
       uri::UriStruct us;
       if(uri::parse(us, (*j)->getUri())) {

+ 2 - 2
src/RpcMethodImpl.cc

@@ -1368,9 +1368,9 @@ SharedHandle<ValueBase> GetServersRpcMethod::process
     SharedHandle<Dict> fileEntry = Dict::g();
     fileEntry->put(KEY_INDEX, util::uitos(index));
     SharedHandle<List> servers = List::g();
-    const std::deque<SharedHandle<Request> >& requests =
+    const FileEntry::InFlightRequestSet& requests =
       (*fi)->getInFlightRequests();
-    for(std::deque<SharedHandle<Request> >::const_iterator ri =requests.begin(),
+    for(FileEntry::InFlightRequestSet::iterator ri =requests.begin(),
           eoi = requests.end(); ri != eoi; ++ri) {
       SharedHandle<PeerStat> ps = (*ri)->getPeerStat();
       if(ps) {

+ 21 - 36
src/SelectEventPoll.cc

@@ -181,9 +181,8 @@ void SelectEventPoll::poll(const struct timeval& tv)
 #endif // __MINGW32__
 #ifdef ENABLE_ASYNC_DNS
 
-  for(std::deque<SharedHandle<AsyncNameResolverEntry> >::const_iterator itr =
-        nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
-      itr != eoi; ++itr) {
+  for(AsyncNameResolverEntrySet::iterator itr = nameResolverEntries_.begin(),
+        eoi = nameResolverEntries_.end(); itr != eoi; ++itr) {
     const SharedHandle<AsyncNameResolverEntry>& entry = *itr;
     int fd = entry->getFds(&rfds, &wfds);
     // TODO force error if fd == 0
@@ -203,8 +202,8 @@ void SelectEventPoll::poll(const struct timeval& tv)
 #endif // !__MINGW32__
   } while(retval == -1 && errno == EINTR);
   if(retval > 0) {
-    for(std::deque<SharedHandle<SocketEntry> >::const_iterator i =
-          socketEntries_.begin(), eoi = socketEntries_.end(); i != eoi; ++i) {
+    for(SocketEntrySet::iterator i = socketEntries_.begin(),
+          eoi = socketEntries_.end(); i != eoi; ++i) {
       int events = 0;
       if(FD_ISSET((*i)->getSocket(), &rfds)) {
         events |= EventPoll::EVENT_READ;
@@ -220,9 +219,8 @@ void SelectEventPoll::poll(const struct timeval& tv)
   }
 #ifdef ENABLE_ASYNC_DNS
 
-  for(std::deque<SharedHandle<AsyncNameResolverEntry> >::const_iterator i =
-        nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
-      i != eoi; ++i) {
+  for(AsyncNameResolverEntrySet::iterator i = nameResolverEntries_.begin(),
+        eoi = nameResolverEntries_.end(); i != eoi; ++i) {
     (*i)->process(&rfds, &wfds);
   }
 
@@ -250,8 +248,8 @@ void SelectEventPoll::updateFdSet()
 #endif // !__MINGW32__
   FD_ZERO(&rfdset_);
   FD_ZERO(&wfdset_);
-  for(std::deque<SharedHandle<SocketEntry> >::const_iterator i =
-        socketEntries_.begin(), eoi = socketEntries_.end(); i != eoi; ++i) {
+  for(SocketEntrySet::iterator i = socketEntries_.begin(),
+        eoi = socketEntries_.end(); i != eoi; ++i) {
     sock_t fd = (*i)->getSocket();
 #ifndef __MINGW32__
     if(fd < 0 || FD_SETSIZE <= fd) {
@@ -283,9 +281,7 @@ bool SelectEventPoll::addEvents(sock_t socket, Command* command,
                                 EventPoll::EventType events)
 {
   SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
-  std::deque<SharedHandle<SocketEntry> >::iterator i =
-    std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
-                     DerefLess<SharedHandle<SocketEntry> >());
+  SocketEntrySet::iterator i = socketEntries_.lower_bound(socketEntry);
   if(i != socketEntries_.end() && *(*i) == *socketEntry) {
     (*i)->addCommandEvent(command, events);
   } else {
@@ -300,19 +296,17 @@ bool SelectEventPoll::deleteEvents(sock_t socket, Command* command,
                                    EventPoll::EventType events)
 {
   SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
-  std::deque<SharedHandle<SocketEntry> >::iterator i =
-    std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
-                     DerefLess<SharedHandle<SocketEntry> >());
-  if(i != socketEntries_.end() && *(*i) == *socketEntry) {
+  SocketEntrySet::iterator i = socketEntries_.find(socketEntry);
+  if(i == socketEntries_.end()) {
+    A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
+    return false;
+  } else {
     (*i)->removeCommandEvent(command, events);
     if((*i)->eventEmpty()) {
       socketEntries_.erase(i);
     }
     updateFdSet();
     return true;
-  } else {
-    A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
-    return false;
   }
 }
 
@@ -322,14 +316,13 @@ bool SelectEventPoll::addNameResolver
 {
   SharedHandle<AsyncNameResolverEntry> entry
     (new AsyncNameResolverEntry(resolver, command));
-  std::deque<SharedHandle<AsyncNameResolverEntry> >::iterator itr =
-    std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
-                 derefEqual(entry));
-  if(itr == nameResolverEntries_.end()) {
-    nameResolverEntries_.push_back(entry);
-    return true;
-  } else {
+  AsyncNameResolverEntrySet::iterator itr =
+    nameResolverEntries_.lower_bound(entry);
+  if(itr != nameResolverEntries_.end() && *(*itr) == *entry) {
     return false;
+  } else {
+    nameResolverEntries_.insert(itr, entry);
+    return true;
   }
 }
 
@@ -338,15 +331,7 @@ bool SelectEventPoll::deleteNameResolver
 {
   SharedHandle<AsyncNameResolverEntry> entry
     (new AsyncNameResolverEntry(resolver, command));
-  std::deque<SharedHandle<AsyncNameResolverEntry> >::iterator itr =
-    std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
-                 derefEqual(entry));
-  if(itr == nameResolverEntries_.end()) {
-    return false;
-  } else {
-    nameResolverEntries_.erase(itr);
-    return true;
-  }
+  return nameResolverEntries_.erase(entry) == 1;
 }
 #endif // ENABLE_ASYNC_DNS
 

+ 16 - 2
src/SelectEventPoll.h

@@ -38,7 +38,9 @@
 #include "EventPoll.h"
 
 #include <deque>
+#include <set>
 
+#include "a2functional.h"
 #ifdef ENABLE_ASYNC_DNS
 # include "AsyncNameResolver.h"
 #endif // ENABLE_ASYNC_DNS
@@ -145,6 +147,13 @@ private:
         command_ == entry.command_;
     }
 
+    bool operator<(const AsyncNameResolverEntry& entry)
+    {
+      return nameResolver_.get() < entry.nameResolver_.get() ||
+        (nameResolver_.get() == entry.nameResolver_.get() &&
+         command_ < entry.command_);
+    }
+
     int getFds(fd_set* rfdsPtr, fd_set* wfdsPtr);
 
     void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
@@ -155,9 +164,14 @@ private:
   fd_set wfdset_;
   sock_t fdmax_;
 
-  std::deque<SharedHandle<SocketEntry> > socketEntries_;
+  typedef std::set<SharedHandle<SocketEntry>,
+                   DerefLess<SharedHandle<SocketEntry> > > SocketEntrySet;
+  SocketEntrySet socketEntries_;
 #ifdef ENABLE_ASYNC_DNS
-  std::deque<SharedHandle<AsyncNameResolverEntry> > nameResolverEntries_;
+  typedef std::set<SharedHandle<AsyncNameResolverEntry>,
+                   DerefLess<SharedHandle<AsyncNameResolverEntry> > >
+  AsyncNameResolverEntrySet;
+  AsyncNameResolverEntrySet nameResolverEntries_;
 #endif // ENABLE_ASYNC_DNS
 
 #ifdef __MINGW32__

+ 2 - 6
src/ServerStat.cc

@@ -191,12 +191,8 @@ void ServerStat::setError()
 
 bool ServerStat::operator<(const ServerStat& serverStat) const
 {
-  int c = hostname_.compare(serverStat.hostname_);
-  if(c == 0) {
-    return protocol_ < serverStat.protocol_;
-  } else {
-    return c < 0;
-  }
+  return hostname_ < serverStat.hostname_ ||
+    (hostname_ == serverStat.hostname_ && protocol_ < serverStat.protocol_);
 }
 
 bool ServerStat::operator==(const ServerStat& serverStat) const

+ 16 - 16
src/ServerStatMan.cc

@@ -61,23 +61,17 @@ SharedHandle<ServerStat> ServerStatMan::find(const std::string& hostname,
                                              const std::string& protocol) const
 {
   SharedHandle<ServerStat> ss(new ServerStat(hostname, protocol));
-  std::deque<SharedHandle<ServerStat> >::const_iterator i =
-    std::lower_bound(serverStats_.begin(), serverStats_.end(), ss,
-                     DerefLess<SharedHandle<ServerStat> >());
-  if(i != serverStats_.end() &&
-     (*i)->getHostname() == hostname && (*i)->getProtocol() == protocol) {
-    return *i;
-  } else {
+  ServerStatSet::iterator i = serverStats_.find(ss);
+  if(i == serverStats_.end()) {
     return SharedHandle<ServerStat>();
+  } else {
+    return *i;
   }
 }
 
 bool ServerStatMan::add(const SharedHandle<ServerStat>& serverStat)
 {
-  std::deque<SharedHandle<ServerStat> >::iterator i =
-    std::lower_bound(serverStats_.begin(), serverStats_.end(), serverStat,
-                     DerefLess<SharedHandle<ServerStat> >());
-
+  ServerStatSet::iterator i = serverStats_.lower_bound(serverStat);
   if(i != serverStats_.end() && *(*i) == *serverStat) {
     return false;
   } else {
@@ -97,8 +91,8 @@ bool ServerStatMan::save(const std::string& filename) const
                        filename.c_str()));
       return false;
     }
-    for(std::deque<SharedHandle<ServerStat> >::const_iterator i =
-          serverStats_.begin(), eoi = serverStats_.end(); i != eoi; ++i) {
+    for(ServerStatSet::iterator i = serverStats_.begin(),
+          eoi = serverStats_.end(); i != eoi; ++i) {
       std::string l = (*i)->toString();
       l += "\n";
       if(fp.write(l.data(), l.size()) != l.size()) {
@@ -217,9 +211,15 @@ public:
 
 void ServerStatMan::removeStaleServerStat(time_t timeout)
 {
-  serverStats_.erase(std::remove_if(serverStats_.begin(), serverStats_.end(),
-                                    FindStaleServerStat(timeout)),
-                     serverStats_.end());
+  FindStaleServerStat finder(timeout);
+  for(ServerStatSet::iterator i = serverStats_.begin(),
+        eoi = serverStats_.end(); i != eoi;) {
+    if(finder(*i)) {
+      serverStats_.erase(i++);
+    } else {
+      ++i;
+    }
+  }
 }
 
 } // namespace aria2

+ 5 - 2
src/ServerStatMan.h

@@ -37,10 +37,11 @@
 #include "common.h"
 
 #include <string>
-#include <deque>
+#include <set>
 
 #include "SharedHandle.h"
 #include "a2time.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -63,7 +64,9 @@ public:
 
   void removeStaleServerStat(time_t timeout);
 private:
-  std::deque<SharedHandle<ServerStat> > serverStats_;
+  typedef std::set<SharedHandle<ServerStat>,
+                   DerefLess<SharedHandle<ServerStat> > > ServerStatSet;
+  ServerStatSet serverStats_;
 };
 
 } // namespace aria2

+ 2 - 2
src/StreamFileAllocationEntry.cc

@@ -70,9 +70,9 @@ void StreamFileAllocationEntry::prepareForNextAction
       dctx->getFileEntries();
     for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
           fileEntries.begin(), eoi = fileEntries.end(); i != eoi; ++i) {
-      const std::deque<SharedHandle<Request> >& reqs =
+      const FileEntry::InFlightRequestSet& reqs =
         (*i)->getInFlightRequests();
-      for(std::deque<SharedHandle<Request> >::const_iterator j =
+      for(FileEntry::InFlightRequestSet::iterator j =
             reqs.begin(), eoj = reqs.end(); j != eoj; ++j) {
         const SharedHandle<PeerStat>& peerStat = (*j)->getPeerStat();
         if(peerStat) {

+ 6 - 0
src/a2functional.h

@@ -286,6 +286,12 @@ std::string strjoin(InputIterator first, InputIterator last,
 template<typename T>
 class LeastRecentAccess:public std::binary_function<T, T, bool> {
 public:
+  bool operator()(const SharedHandle<T>& lhs,
+                  const SharedHandle<T>& rhs) const
+  {
+    return lhs->getLastAccessTime() < rhs->getLastAccessTime();
+  }
+
   bool operator()(const T& lhs, const T& rhs) const
   {
     return lhs.getLastAccessTime() < rhs.getLastAccessTime();

+ 20 - 5
test/AuthConfigFactoryTest.cc

@@ -195,6 +195,21 @@ void AuthConfigFactoryTest::testCreateAuthConfig_ftp()
                        factory.createAuthConfig(req, &option)->getAuthText());
 }
 
+namespace {
+SharedHandle<AuthConfigFactory::BasicCred>
+createBasicCred(const std::string& user,
+                const std::string& password,
+                const std::string& host, uint16_t port,
+                const std::string& path,
+                bool activated = false)
+{
+  SharedHandle<AuthConfigFactory::BasicCred> bc
+    (new AuthConfigFactory::BasicCred(user, password, host, port, path,
+                                      activated));
+  return bc;
+}
+} // namespace
+
 void AuthConfigFactoryTest::testUpdateBasicCred()
 {
   Option option;
@@ -204,15 +219,15 @@ void AuthConfigFactoryTest::testUpdateBasicCred()
   AuthConfigFactory factory;
 
   factory.updateBasicCred
-    (AuthConfigFactory::BasicCred("myname", "mypass", "localhost", 80, "/", true));
+    (createBasicCred("myname", "mypass", "localhost", 80, "/", true));
   factory.updateBasicCred
-    (AuthConfigFactory::BasicCred("price", "j38jdc", "localhost", 80, "/download", true));
+    (createBasicCred("price", "j38jdc", "localhost", 80, "/download", true));
   factory.updateBasicCred
-    (AuthConfigFactory::BasicCred("soap", "planB", "localhost", 80, "/download/beta", true));
+    (createBasicCred("soap", "planB", "localhost", 80, "/download/beta", true));
   factory.updateBasicCred
-    (AuthConfigFactory::BasicCred("alice", "ium8", "localhost", 80, "/documents", true));
+    (createBasicCred("alice", "ium8", "localhost", 80, "/documents", true));
   factory.updateBasicCred
-    (AuthConfigFactory::BasicCred("jack", "jackx", "mirror", 80, "/doc", true));
+    (createBasicCred("jack", "jackx", "mirror", 80, "/doc", true));
 
   SharedHandle<Request> req(new Request());
   req->setUri("http://localhost/download/v2.6/Changelog");