From: bert hubert Date: Fri, 6 Nov 2015 12:14:30 +0000 (+0100) Subject: speed up DNSName hashing, create testcase for it. Close #2868 X-Git-Tag: dnsdist-1.0.0-alpha1~239^2~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76cca09f1e1e026427691d2980e6e66c10391a87;p=pdns speed up DNSName hashing, create testcase for it. Close #2868 --- diff --git a/pdns/dnsname.cc b/pdns/dnsname.cc index 65ca46e79..0d5ee168c 100644 --- a/pdns/dnsname.cc +++ b/pdns/dnsname.cc @@ -264,8 +264,7 @@ bool DNSName::operator==(const DNSName& rhs) const size_t hash_value(DNSName const& d) { - boost::hash hasher; - return hasher(toLower(d.toString())); // FIXME400 HACK - we rely on this lowercasing though in packetcache.hh + return d.hash(); } string DNSName::escapeLabel(const std::string& label) diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index 082249797..c3016c627 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -6,6 +6,8 @@ #include #include +uint32_t burtleCI(const unsigned char* k, uint32_t lengh, uint32_t init); + // #include "dns.hh" // #include "logger.hh" @@ -53,6 +55,10 @@ public: bool isRoot() const { return d_storage.size()==1 && d_storage[0]==0; } void clear() { d_storage.clear(); } void trimToLabels(unsigned int); + size_t hash() const + { + return burtleCI((const unsigned char*)d_storage.c_str(), d_storage.size(), 0); + } DNSName& operator+=(const DNSName& rhs) { if(d_storage.size() + rhs.d_storage.size() > 256) // reserve one byte for the root label diff --git a/pdns/misc.hh b/pdns/misc.hh index 9dbad019b..3462c46be 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -608,7 +608,6 @@ unsigned int getFilenumLimit(bool hardOrSoft=0); void setFilenumLimit(unsigned int lim); bool readFileIfThere(const char* fname, std::string* line); uint32_t burtle(const unsigned char* k, uint32_t lengh, uint32_t init); -uint32_t burtleCI(const unsigned char* k, uint32_t lengh, uint32_t init); bool setSocketTimestamps(int fd); //! Sets the socket into blocking mode. diff --git a/pdns/packetcache.hh b/pdns/packetcache.hh index 1a28689be..2863b1d42 100644 --- a/pdns/packetcache.hh +++ b/pdns/packetcache.hh @@ -126,7 +126,7 @@ private: vector d_maps; MapCombo& getMap(const DNSName& qname) { - return d_maps[hash_value(qname) % d_maps.size()]; + return d_maps[qname.hash() % d_maps.size()]; } AtomicCounter d_ops; diff --git a/pdns/test-dnsname_cc.cc b/pdns/test-dnsname_cc.cc index c0b12f5e9..485fdb978 100644 --- a/pdns/test-dnsname_cc.cc +++ b/pdns/test-dnsname_cc.cc @@ -240,6 +240,31 @@ BOOST_AUTO_TEST_CASE(test_PacketParse) { } +BOOST_AUTO_TEST_CASE(test_hash) { + DNSName a("wwW.Ds9A.Nl"), b("www.ds9a.nl"); + BOOST_CHECK_EQUAL(a.hash(), b.hash()); + + vector counts(1500); + + for(unsigned int n=0; n < 100000; ++n) { + DNSName dn(std::to_string(n)+"."+std::to_string(n*2)+"ds9a.nl"); + DNSName dn2(std::to_string(n)+"."+std::to_string(n*2)+"Ds9a.nL"); + BOOST_CHECK_EQUAL(dn.hash(), dn2.hash()); + counts[dn.hash() % counts.size()]++; + } + + double sum = std::accumulate(std::begin(counts), std::end(counts), 0.0); + double m = sum / counts.size(); + + double accum = 0.0; + std::for_each (std::begin(counts), std::end(counts), [&](const double d) { + accum += (d - m) * (d - m); + }); + + double stdev = sqrt(accum / (counts.size()-1)); + BOOST_CHECK(stdev < 10); +} + BOOST_AUTO_TEST_CASE(test_QuestionHash) { vector packet; reportBasicTypes();