]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Speed up the consistent hashing policies with large weights
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 22 Jan 2020 17:59:40 +0000 (18:59 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 11 Feb 2020 10:49:58 +0000 (11:49 +0100)
Using a sorted vector provides a much faster lookup time than a
std::set when the number of points on the circle (weight of the
backend) is huge.
A boost::flat_set is almost as fast as a sorted vector but the
insertion time is quite bad.

pdns/dnsdist.hh
pdns/dnsdistdist/dnsdist-backend.cc
pdns/dnsdistdist/dnsdist-lbpolicies.cc

index ce27a4e0fee49a42e9bd646a09a6b3014faa781f..bf54a89aebb4dc43aca7ae2775e3ccf6377a5990 100644 (file)
@@ -772,7 +772,7 @@ struct DownstreamState
     pthread_rwlock_destroy(&d_lock);
   }
   boost::uuids::uuid id;
-  std::set<unsigned int> hashes;
+  std::vector<unsigned int> hashes;
   mutable pthread_rwlock_t d_lock;
   std::vector<int> sockets;
   const std::string sourceItfName;
index af9439dc0813a1c41fc9ae01019c3aa77903da7b..606977c098fe4c8c3b93e242165fd6c234b46ca8 100644 (file)
@@ -98,12 +98,14 @@ void DownstreamState::hash()
   auto w = weight;
   WriteLock wl(&d_lock);
   hashes.clear();
+  hashes.reserve(w);
   while (w > 0) {
     std::string uuid = boost::str(boost::format("%s-%d") % id % w);
-    unsigned int wshash = burtleCI((const unsigned char*)uuid.c_str(), uuid.size(), g_hashperturb);
-    hashes.insert(wshash);
+    unsigned int wshash = burtleCI(reinterpret_cast<const unsigned char*>(uuid.c_str()), uuid.size(), g_hashperturb);
+    hashes.push_back(wshash);
     --w;
   }
+  std::sort(hashes.begin(), hashes.end());
 }
 
 void DownstreamState::setId(const boost::uuids::uuid& newId)
index a3175e4e59f83756b7e0799246f347433796ccb3..aa08a32d236178bc3deeb2a33d2826d9630e90eb 100644 (file)
@@ -147,7 +147,7 @@ shared_ptr<DownstreamState> chashedFromHash(const ServerPolicy::NumberedServerVe
           first = server;
         }
 
-        auto hash_it = server->hashes.lower_bound(qhash);
+        auto hash_it = std::lower_bound(server->hashes.begin(), server->hashes.end(), qhash);
         if (hash_it != server->hashes.end()) {
           if (*hash_it < sel) {
             sel = *hash_it;