31 #include <boost/functional/hash.hpp> 32 #include <boost/lexical_cast.hpp> 37 using boost::lexical_cast;
69 typedef boost::hash<string> BoostStringHasher;
70 typedef std::map<size_t, string> StringsTable;
86 BoostStringHasher hashFunction;
87 StringsTable hashValues;
88 string prefix =
"Entry.";
90 for (uint i=0; i<100000; ++i)
92 string candidate = prefix + lexical_cast<
string> (i);
93 size_t hashVal = hashFunction(candidate);
95 if (contains (hashValues, hashVal))
98 string other = hashValues[hashVal];
99 cout <<
"Duplicate at "<< i << endl;
100 cout <<
"existing--->" << other << endl;
101 cout <<
"new-------->" << candidate << endl;
103 size_t exHash = hashFunction(other);
104 size_t newHash = hashFunction(candidate);
105 cout <<
"hash-ex---->" << exHash << endl;
106 cout <<
"hash_new--->" << newHash << endl;
108 hashValues[hashVal] = candidate;
111 cout <<
"boost::hash for strings produced "<<collisions<<
" collisions. This is a known problem."<<endl;
113 cout <<
"SURPRISE. No collisions with the boost::hash function." <<endl;
134 StringsTable hashValues;
135 string prefix =
"Entry.";
136 const size_t seed = rand();
141 for (uint i=0; i<20000; ++i)
143 string candidate = prefix + lexical_cast<
string> (i);
144 size_t l = candidate.length();
145 size_t hashVal = seed;
147 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-1]);
148 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-2]);
149 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-3]);
150 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-4]);
151 boost::hash_combine(hashVal, candidate);
153 if (contains (hashValues, hashVal))
156 string other = hashValues[hashVal];
157 cout <<
"Hash collision between " << i <<
" and " << other <<endl;
159 hashValues[hashVal] = candidate;
161 CHECK (!collisions,
"the Knuth trick failed to spread our hash values evenly enough, what a shame...");
void demonstrate_boost_hash_weakness()
const size_t KNUTH_MAGIC
lousy old tinkerer's trick: hash values with poor distribution can be improved by spreading the input...
Implementation namespace for support and library code.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void verify_Knuth_workaround()
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container