]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Implement std::hash<SBuf>
authorFrancesco Chemolli <kinkie@squid-cache.org>
Mon, 27 Jul 2015 17:41:03 +0000 (19:41 +0200)
committerFrancesco Chemolli <kinkie@squid-cache.org>
Mon, 27 Jul 2015 17:41:03 +0000 (19:41 +0200)
src/SBuf.cc
src/SBuf.h
src/tests/testSBuf.cc
src/tests/testSBuf.h

index 412f2fde393669024ac7a3c494a847cef0107fba..27432bde1e00e23f70fb269ad3256a3f11fa691d 100644 (file)
@@ -17,6 +17,7 @@
 #include "util.h"
 
 #include <cstring>
+#include <functional>
 #include <iostream>
 #include <sstream>
 
@@ -952,3 +953,16 @@ SBuf::cow(SBuf::size_type newsize)
     reAlloc(newsize);
 }
 
+std::size_t std::hash<SBuf>::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);
+}
index 6f39f4bd17a7af1b706d69dbd7e101b161f829a2..5858a1ff0d2340706c18ed5f1dba275717d3f5c9 100644 (file)
@@ -722,6 +722,15 @@ ToLower(SBuf buf)
     return buf;
 }
 
+namespace std {
+    /// default hash functor to support std::unordered_map<SBuf,*>
+    template <>
+    struct hash<SBuf>
+    {
+        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 */
-
index b7858ed9859540161bbfbfff994443dc2008f4b1..e406e459ed3db1c050867e8e0aa554a8af479281 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <iostream>
 #include <stdexcept>
+#include <unordered_map>
 
 CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf );
 
@@ -952,3 +953,31 @@ testSBuf::testIterators()
     }
 }
 
+void
+testSBuf::testSBufHash()
+{
+    // same SBuf must have same hash
+    auto hasher=std::hash<SBuf>();
+    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<SBuf, int> 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());
+
+    }
+}
index 838356c7276dadc234fd68a73f1484770c867635..a3a04e6f65673e543944a50e15df11b04c6828c4 100644 (file)
@@ -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