From 8fb5b29a817dabd5013e46f894b8ba7d73fee008 Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Mon, 5 Aug 2013 09:42:35 +0200 Subject: [PATCH] pdns_ilexicographical_compare() and dns_iequals() optimization --- pdns/misc.hh | 41 +++++++++++++++-------------- pdns/test-misc_hh.cc | 61 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 26 deletions(-) diff --git a/pdns/misc.hh b/pdns/misc.hh index 4da76e684..3a665fc11 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -311,36 +311,35 @@ inline bool operator<(const struct timeval& lhs, const struct timeval& rhs) } inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) __attribute__((pure)); -inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) +inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) { - string::size_type aLen = a.length(), bLen = b.length(), n; const unsigned char *aPtr = (const unsigned char*)a.c_str(), *bPtr = (const unsigned char*)b.c_str(); - int result; - - for(n = 0 ; n < aLen && n < bLen ; ++n) { - if((result = dns_tolower(*aPtr++) - dns_tolower(*bPtr++))) { - return result < 0; - } + + while(*aPtr && *bPtr) { + if ((*aPtr != *bPtr) && (dns_tolower(*aPtr) - dns_tolower(*bPtr))) + return (dns_tolower(*aPtr) - dns_tolower(*bPtr)) < 0; + aPtr++; + bPtr++; } - if(n == aLen && n == bLen) // strings are equal (in length) - return 0; - if(n == aLen) // first string was shorter - return true; - return false; + if(!*aPtr && !*bPtr) // strings are equal (in length) + return false; + return !*aPtr; // true if first string was shorter } inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure)); - -inline bool pdns_iequals(const std::string& a, const std::string& b) +inline bool pdns_iequals(const std::string& a, const std::string& b) { - string::size_type aLen = a.length(), bLen = b.length(), n; + if (a.length() != b.length()) + return false; + const char *aPtr = a.c_str(), *bPtr = b.c_str(); - - for(n = 0 ; n < aLen && n < bLen ; ++n) { - if(dns_tolower(*aPtr++) != dns_tolower(*bPtr++)) - return false; + while(*aPtr) { + if((*aPtr != *bPtr) && (dns_tolower(*aPtr) != dns_tolower(*bPtr))) + return false; + aPtr++; + bPtr++; } - return aLen == bLen; // strings are equal (in length) + return true; } // lifted from boost, with thanks diff --git a/pdns/test-misc_hh.cc b/pdns/test-misc_hh.cc index d50201e65..0e7f37b70 100644 --- a/pdns/test-misc_hh.cc +++ b/pdns/test-misc_hh.cc @@ -2,6 +2,9 @@ #define BOOST_TEST_NO_MAIN #include +#include +#include +#include #include "misc.hh" #include "dns.hh" #include @@ -12,7 +15,7 @@ BOOST_AUTO_TEST_SUITE(misc_hh) typedef pair typedns_t; BOOST_AUTO_TEST_CASE(test_CIStringCompare) { - set nsset; + set nsset; nsset.insert("abc"); nsset.insert("ns.example.com"); nsset.insert(""); @@ -29,7 +32,7 @@ BOOST_AUTO_TEST_CASE(test_CIStringCompare) { } BOOST_AUTO_TEST_CASE(test_CIStringPairCompare) { - set nsset2; + set nsset2; nsset2.insert(make_pair("ns.example.com", 1)); nsset2.insert(make_pair("abc", 1)); nsset2.insert(make_pair("", 1)); @@ -37,9 +40,8 @@ BOOST_AUTO_TEST_CASE(test_CIStringPairCompare) { nsset2.insert(make_pair("abc", 2)); nsset2.insert(make_pair("abc", 1)); nsset2.insert(make_pair("ns.example.com", 0)); - nsset2.insert(make_pair("abc", 2)); + nsset2.insert(make_pair("abc", 2)); nsset2.insert(make_pair("ABC", 2)); - BOOST_CHECK_EQUAL(nsset2.size(), 6); ostringstream s; @@ -49,8 +51,57 @@ BOOST_AUTO_TEST_CASE(test_CIStringPairCompare) { BOOST_CHECK_EQUAL(s.str(), "(|1)(abc|1)(abc|2)(def|1)(ns.example.com|0)(ns.example.com|1)"); } +BOOST_AUTO_TEST_CASE(test_pdns_ilexicographical_compare) { + typedef boost::tuple case_t; + typedef std::list cases_t; + + cases_t cases = boost::assign::list_of + (case_t(std::string(""), std::string(""), false)) + (case_t(std::string(""), std::string("abc"), true)) + (case_t(std::string("abc"), std::string(""), false)) + (case_t(std::string("abc"), std::string("abcd"), true)) + (case_t(std::string("abcd"), std::string("abc"), false)) + (case_t(std::string("abd"), std::string("abc"), false)) + (case_t(std::string("abc"), std::string("abd"), true)) + (case_t(std::string("abc"), std::string("Abc"), false)) + (case_t(std::string("Abc"), std::string("abc"), false)) + ; + + BOOST_FOREACH(const case_t& val, cases) { + bool res; + res = pdns_ilexicographical_compare(val.get<0>(), val.get<1>()); + BOOST_CHECK_EQUAL(res, val.get<2>()); + } +} + +BOOST_AUTO_TEST_CASE(test_pdns_iequals) { + typedef boost::tuple case_t; + typedef std::list cases_t; + + cases_t cases = boost::assign::list_of + (case_t(std::string(""), std::string(""), true)) + (case_t(std::string(""), std::string("abc"), false)) + (case_t(std::string("abc"), std::string(""), false)) + (case_t(std::string("abc"), std::string("abcd"), false)) + (case_t(std::string("abcd"), std::string("abc"), false)) + (case_t(std::string("abd"), std::string("abc"), false)) + (case_t(std::string("abc"), std::string("abd"), false)) + (case_t(std::string("abc"), std::string("Abc"), true)) + (case_t(std::string("Abc"), std::string("abc"), true)) + ; + + BOOST_FOREACH(const case_t& val, cases) { + bool res; + res = pdns_iequals(val.get<0>(), val.get<1>()); + BOOST_CHECK_EQUAL(res, val.get<2>()); + } +} + BOOST_AUTO_TEST_CASE(test_stripDot) { - BOOST_CHECK_EQUAL(stripDot("www.powerdns.com."), "www.powerdns.com"); + BOOST_CHECK_EQUAL(stripDot("."), ""); + BOOST_CHECK_EQUAL(stripDot(""), ""); + BOOST_CHECK_EQUAL(stripDot("www.powerdns.com."), "www.powerdns.com"); + BOOST_CHECK_EQUAL(stripDot("www.powerdns.com"), "www.powerdns.com"); } BOOST_AUTO_TEST_CASE(test_labelReverse) { -- 2.49.0