Lumiera  0.pre.03
»edit your freedom«
hash-generator-test.cpp
Go to the documentation of this file.
1 /*
2  HashGenerator(Test) - hash value generation details
3 
4  Copyright (C) Lumiera.org
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/util.hpp"
30 
31 #include <boost/functional/hash.hpp>
32 #include <boost/lexical_cast.hpp>
33 #include <iostream>
34 #include <string>
35 #include <map>
36 
37 using boost::lexical_cast;
38 using util::contains;
39 using std::string;
40 using std::cout;
41 using std::endl;
42 
43 
44 namespace lib {
45 namespace test{
46 
47 
48 
49 
50 
51  /***********************************************************************/
58  class HashGenerator_test : public Test
59  {
60 
61  virtual void
62  run (Arg)
63  {
66  }
67 
68 
69  typedef boost::hash<string> BoostStringHasher;
70  typedef std::map<size_t, string> StringsTable;
71 
72 
83  void
85  {
86  BoostStringHasher hashFunction;
87  StringsTable hashValues;
88  string prefix = "Entry.";
89  uint collisions(0);
90  for (uint i=0; i<100000; ++i)
91  {
92  string candidate = prefix + lexical_cast<string> (i);
93  size_t hashVal = hashFunction(candidate);
94 
95  if (contains (hashValues, hashVal))
96  {
97  ++collisions;
98  string other = hashValues[hashVal];
99  cout << "Duplicate at "<< i << endl;
100  cout << "existing--->" << other << endl;
101  cout << "new-------->" << candidate << endl;
102 
103  size_t exHash = hashFunction(other);
104  size_t newHash = hashFunction(candidate);
105  cout << "hash-ex---->" << exHash << endl;
106  cout << "hash_new--->" << newHash << endl;
107  }
108  hashValues[hashVal] = candidate;
109  }
110  if (0 < collisions)
111  cout << "boost::hash for strings produced "<<collisions<<" collisions. This is a known problem."<<endl;
112  else
113  cout << "SURPRISE. No collisions with the boost::hash function." <<endl;
114  }
115 
116 
117 
131  void
133  {
134  StringsTable hashValues;
135  string prefix = "Entry.";
136  const size_t seed = rand();
137 
138  const size_t KNUTH_MAGIC = 2654435761;
139 
140  uint collisions(0);
141  for (uint i=0; i<20000; ++i)
142  {
143  string candidate = prefix + lexical_cast<string> (i);
144  size_t l = candidate.length();
145  size_t hashVal = seed;
146 
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);
152 
153  if (contains (hashValues, hashVal))
154  {
155  ++collisions;
156  string other = hashValues[hashVal];
157  cout << "Hash collision between " << i << " and " << other <<endl;
158  }
159  hashValues[hashVal] = candidate;
160  }
161  CHECK (!collisions, "the Knuth trick failed to spread our hash values evenly enough, what a shame...");
162  }
163 
164  };
165 
166 
168  LAUNCHER (HashGenerator_test, "unit common");
169 
170 
171 }} // namespace lib::test
Definition: run.hpp:49
const size_t KNUTH_MAGIC
lousy old tinkerer&#39;s trick: hash values with poor distribution can be improved by spreading the input...
Definition: entry-id.hpp:92
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...
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255