From: Francesco Chemolli Date: Mon, 27 Jul 2015 17:41:03 +0000 (+0200) Subject: Implement std::hash X-Git-Tag: merge-candidate-3-v1~24^2^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bf7550ff17ed1bf76eabb3d46763a675c81ded05;p=thirdparty%2Fsquid.git Implement std::hash --- diff --git a/src/SBuf.cc b/src/SBuf.cc index 412f2fde39..27432bde1e 100644 --- a/src/SBuf.cc +++ b/src/SBuf.cc @@ -17,6 +17,7 @@ #include "util.h" #include +#include #include #include @@ -952,3 +953,16 @@ SBuf::cow(SBuf::size_type newsize) reAlloc(newsize); } +std::size_t std::hash::operator() (const SBuf & sbuf) const noexcept +{ + //ripped and adapted from hash_string + const char *s = sbuf.rawContent(); + size_t rv = 0; + SBuf::size_type len=sbuf.length(); + while (len != 0) { + rv ^= 271 * *s; + ++s; + --len; + } + return rv ^ (sbuf.length() * 271); +} diff --git a/src/SBuf.h b/src/SBuf.h index 6f39f4bd17..5858a1ff0d 100644 --- a/src/SBuf.h +++ b/src/SBuf.h @@ -722,6 +722,15 @@ ToLower(SBuf buf) return buf; } +namespace std { + /// default hash functor to support std::unordered_map + template <> + struct hash + { + size_t operator()(const SBuf &) const noexcept; + }; +} + inline SBufIterator::SBufIterator(const SBuf &s, size_type pos) : iter(s.rawContent()+pos) @@ -742,4 +751,3 @@ SBufIterator::operator!=(const SBufIterator &s) const } #endif /* SQUID_SBUF_H */ - diff --git a/src/tests/testSBuf.cc b/src/tests/testSBuf.cc index b7858ed985..e406e459ed 100644 --- a/src/tests/testSBuf.cc +++ b/src/tests/testSBuf.cc @@ -17,6 +17,7 @@ #include #include +#include CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf ); @@ -952,3 +953,31 @@ testSBuf::testIterators() } } +void +testSBuf::testSBufHash() +{ + // same SBuf must have same hash + auto hasher=std::hash(); + CPPUNIT_ASSERT_EQUAL(hasher(literal),hasher(literal)); + + // same content must have same hash + CPPUNIT_ASSERT_EQUAL(hasher(literal),hasher(SBuf(fox))); + CPPUNIT_ASSERT_EQUAL(hasher(SBuf(fox)),hasher(SBuf(fox))); + + //differen content should have different hash + CPPUNIT_ASSERT(hasher(SBuf(fox)) != hasher(SBuf(fox1))); + + { + std::unordered_map um; + um[SBuf("one")] = 1; + um[SBuf("two")] = 2; + + auto i = um.find(SBuf("one")); + CPPUNIT_ASSERT(i != um.end()); + CPPUNIT_ASSERT(i->second == 1); + + i = um.find(SBuf("eleventy")); + CPPUNIT_ASSERT(i == um.end()); + + } +} diff --git a/src/tests/testSBuf.h b/src/tests/testSBuf.h index 838356c727..a3a04e6f65 100644 --- a/src/tests/testSBuf.h +++ b/src/tests/testSBuf.h @@ -53,6 +53,7 @@ class testSBuf : public CPPUNIT_NS::TestFixture CPPUNIT_TEST( testAutoFind ); CPPUNIT_TEST( testStdStringOps ); CPPUNIT_TEST( testIterators ); + CPPUNIT_TEST( testSBufHash ); // CPPUNIT_TEST( testDumpStats ); //fake test, to print alloc stats CPPUNIT_TEST_SUITE_END(); protected: @@ -93,6 +94,7 @@ protected: void testAutoFind(); void testStdStringOps(); void testIterators(); + void testSBufHash(); }; #endif