1 //===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Hashing.h unit tests.
12 //===----------------------------------------------------------------------===//
14 #include "gtest/gtest.h"
15 #include "llvm/ADT/Hashing.h"
16 #include "llvm/Support/DataTypes.h"
24 // Helper for test code to print hash codes.
25 void PrintTo(const hash_code &code, std::ostream *os) {
26 *os << static_cast<size_t>(code);
29 // Fake an object that is recognized as hashable data to test super large
31 struct LargeTestInteger { uint64_t arr[8]; };
35 template <> struct is_hashable_data<LargeTestInteger> : true_type {};
37 } // namespace hashing
45 TEST(HashingTest, HashValueBasicTest) {
46 int x = 42, y = 43, c = 'x';
49 const unsigned ci = 71;
51 const volatile int cvi = 71;
52 uintptr_t addr = reinterpret_cast<uintptr_t>(&y);
53 EXPECT_EQ(hash_value(42), hash_value(x));
54 EXPECT_NE(hash_value(42), hash_value(y));
55 EXPECT_NE(hash_value(42), hash_value(p));
56 EXPECT_EQ(hash_value(71), hash_value(i));
57 EXPECT_EQ(hash_value(71), hash_value(ci));
58 EXPECT_EQ(hash_value(71), hash_value(vi));
59 EXPECT_EQ(hash_value(71), hash_value(cvi));
60 EXPECT_EQ(hash_value(c), hash_value('x'));
61 EXPECT_EQ(hash_value('4'), hash_value('0' + 4));
62 EXPECT_EQ(hash_value(addr), hash_value(&y));
64 EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
65 EXPECT_NE(hash_combine(43, 42), hash_value(std::make_pair(42, 43)));
66 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43ull)));
67 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42, 43ull)));
68 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43)));
69 EXPECT_EQ(hash_combine(42, hash_combine(43, hash_combine(44, 45))),
71 std::make_pair(42, std::make_pair(43, std::make_pair(44, 45)))));
72 EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
73 EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
76 template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
77 template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
79 // Provide a dummy, hashable type designed for easy verification: its hash is
80 // the same as its value.
81 struct HashableDummy { size_t value; };
82 hash_code hash_value(HashableDummy dummy) { return dummy.value; }
84 TEST(HashingTest, HashCombineRangeBasicTest) {
85 // Leave this uninitialized in the hope that valgrind will catch bad reads.
87 hash_code dummy_hash = hash_combine_range(&dummy, &dummy);
88 EXPECT_NE(hash_code(0), dummy_hash);
90 const int arr1[] = { 1, 2, 3 };
91 hash_code arr1_hash = hash_combine_range(begin(arr1), end(arr1));
92 EXPECT_NE(dummy_hash, arr1_hash);
93 EXPECT_EQ(arr1_hash, hash_combine_range(begin(arr1), end(arr1)));
95 const std::vector<int> vec(begin(arr1), end(arr1));
96 EXPECT_EQ(arr1_hash, hash_combine_range(vec.begin(), vec.end()));
98 const std::list<int> list(begin(arr1), end(arr1));
99 EXPECT_EQ(arr1_hash, hash_combine_range(list.begin(), list.end()));
101 const std::deque<int> deque(begin(arr1), end(arr1));
102 EXPECT_EQ(arr1_hash, hash_combine_range(deque.begin(), deque.end()));
104 const int arr2[] = { 3, 2, 1 };
105 hash_code arr2_hash = hash_combine_range(begin(arr2), end(arr2));
106 EXPECT_NE(dummy_hash, arr2_hash);
107 EXPECT_NE(arr1_hash, arr2_hash);
109 const int arr3[] = { 1, 1, 2, 3 };
110 hash_code arr3_hash = hash_combine_range(begin(arr3), end(arr3));
111 EXPECT_NE(dummy_hash, arr3_hash);
112 EXPECT_NE(arr1_hash, arr3_hash);
114 const int arr4[] = { 1, 2, 3, 3 };
115 hash_code arr4_hash = hash_combine_range(begin(arr4), end(arr4));
116 EXPECT_NE(dummy_hash, arr4_hash);
117 EXPECT_NE(arr1_hash, arr4_hash);
119 const size_t arr5[] = { 1, 2, 3 };
120 const HashableDummy d_arr5[] = { {1}, {2}, {3} };
121 hash_code arr5_hash = hash_combine_range(begin(arr5), end(arr5));
122 hash_code d_arr5_hash = hash_combine_range(begin(d_arr5), end(d_arr5));
123 EXPECT_EQ(arr5_hash, d_arr5_hash);
126 TEST(HashingTest, HashCombineRangeLengthDiff) {
127 // Test that as only the length varies, we compute different hash codes for
129 std::map<size_t, size_t> code_to_size;
130 std::vector<char> all_one_c(256, '\xff');
131 for (unsigned Idx = 1, Size = all_one_c.size(); Idx < Size; ++Idx) {
132 hash_code code = hash_combine_range(&all_one_c[0], &all_one_c[0] + Idx);
133 std::map<size_t, size_t>::iterator
134 I = code_to_size.insert(std::make_pair(code, Idx)).first;
135 EXPECT_EQ(Idx, I->second);
137 code_to_size.clear();
138 std::vector<char> all_zero_c(256, '\0');
139 for (unsigned Idx = 1, Size = all_zero_c.size(); Idx < Size; ++Idx) {
140 hash_code code = hash_combine_range(&all_zero_c[0], &all_zero_c[0] + Idx);
141 std::map<size_t, size_t>::iterator
142 I = code_to_size.insert(std::make_pair(code, Idx)).first;
143 EXPECT_EQ(Idx, I->second);
145 code_to_size.clear();
146 std::vector<unsigned> all_one_int(512, -1);
147 for (unsigned Idx = 1, Size = all_one_int.size(); Idx < Size; ++Idx) {
148 hash_code code = hash_combine_range(&all_one_int[0], &all_one_int[0] + Idx);
149 std::map<size_t, size_t>::iterator
150 I = code_to_size.insert(std::make_pair(code, Idx)).first;
151 EXPECT_EQ(Idx, I->second);
153 code_to_size.clear();
154 std::vector<unsigned> all_zero_int(512, 0);
155 for (unsigned Idx = 1, Size = all_zero_int.size(); Idx < Size; ++Idx) {
156 hash_code code = hash_combine_range(&all_zero_int[0], &all_zero_int[0] + Idx);
157 std::map<size_t, size_t>::iterator
158 I = code_to_size.insert(std::make_pair(code, Idx)).first;
159 EXPECT_EQ(Idx, I->second);
163 TEST(HashingTest, HashCombineRangeGoldenTest) {
164 struct { const char *s; uint64_t hash; } golden_data[] = {
165 #if SIZE_MAX == UINT64_MAX
166 { "a", 0xaeb6f9d5517c61f8ULL },
167 { "ab", 0x7ab1edb96be496b4ULL },
168 { "abc", 0xe38e60bf19c71a3fULL },
169 { "abcde", 0xd24461a66de97f6eULL },
170 { "abcdefgh", 0x4ef872ec411dec9dULL },
171 { "abcdefghijklm", 0xe8a865539f4eadfeULL },
172 { "abcdefghijklmnopqrstu", 0x261cdf85faaf4e79ULL },
173 { "abcdefghijklmnopqrstuvwxyzabcdef", 0x43ba70e4198e3b2aULL },
174 { "abcdefghijklmnopqrstuvwxyzabcdef"
175 "abcdefghijklmnopqrstuvwxyzghijkl"
176 "abcdefghijklmnopqrstuvwxyzmnopqr"
177 "abcdefghijklmnopqrstuvwxyzstuvwx"
178 "abcdefghijklmnopqrstuvwxyzyzabcd", 0xdcd57fb2afdf72beULL },
179 { "a", 0xaeb6f9d5517c61f8ULL },
180 { "aa", 0xf2b3b69a9736a1ebULL },
181 { "aaa", 0xf752eb6f07b1cafeULL },
182 { "aaaaa", 0x812bd21e1236954cULL },
183 { "aaaaaaaa", 0xff07a2cff08ac587ULL },
184 { "aaaaaaaaaaaaa", 0x84ac949d54d704ecULL },
185 { "aaaaaaaaaaaaaaaaaaaaa", 0xcb2c8fb6be8f5648ULL },
186 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xcc40ab7f164091b6ULL },
187 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
188 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
189 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
190 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
191 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xc58e174c1e78ffe9ULL },
192 { "z", 0x1ba160d7e8f8785cULL },
193 { "zz", 0x2c5c03172f1285d7ULL },
194 { "zzz", 0x9d2c4f4b507a2ac3ULL },
195 { "zzzzz", 0x0f03b9031735693aULL },
196 { "zzzzzzzz", 0xe674147c8582c08eULL },
197 { "zzzzzzzzzzzzz", 0x3162d9fa6938db83ULL },
198 { "zzzzzzzzzzzzzzzzzzzzz", 0x37b9a549e013620cULL },
199 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x8921470aff885016ULL },
200 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
201 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
202 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
203 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
204 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0xf60fdcd9beb08441ULL },
205 { "a", 0xaeb6f9d5517c61f8ULL },
206 { "ab", 0x7ab1edb96be496b4ULL },
207 { "aba", 0x3edb049950884d0aULL },
208 { "ababa", 0x8f2de9e73a97714bULL },
209 { "abababab", 0xee14a29ddf0ce54cULL },
210 { "ababababababa", 0x38b3ddaada2d52b4ULL },
211 { "ababababababababababa", 0xd3665364219f2b85ULL },
212 { "abababababababababababababababab"
213 "abababababababababababababababab"
214 "abababababababababababababababab"
215 "abababababababababababababababab"
216 "abababababababababababababababab", 0x840192d129f7a22bULL }
217 #elif SIZE_MAX == UINT32_MAX
218 { "a", 0x000000004605f745ULL },
219 { "ab", 0x00000000d5f06301ULL },
220 { "abc", 0x00000000559fe1eeULL },
221 { "abcde", 0x00000000424028d7ULL },
222 { "abcdefgh", 0x000000007bb119f8ULL },
223 { "abcdefghijklm", 0x00000000edbca513ULL },
224 { "abcdefghijklmnopqrstu", 0x000000007c15712eULL },
225 { "abcdefghijklmnopqrstuvwxyzabcdef", 0x000000000b3aad66ULL },
226 { "abcdefghijklmnopqrstuvwxyzabcdef"
227 "abcdefghijklmnopqrstuvwxyzghijkl"
228 "abcdefghijklmnopqrstuvwxyzmnopqr"
229 "abcdefghijklmnopqrstuvwxyzstuvwx"
230 "abcdefghijklmnopqrstuvwxyzyzabcd", 0x000000008c758c8bULL },
231 { "a", 0x000000004605f745ULL },
232 { "aa", 0x00000000dc0a52daULL },
233 { "aaa", 0x00000000b309274fULL },
234 { "aaaaa", 0x00000000203b5ef6ULL },
235 { "aaaaaaaa", 0x00000000a429e18fULL },
236 { "aaaaaaaaaaaaa", 0x000000008662070bULL },
237 { "aaaaaaaaaaaaaaaaaaaaa", 0x000000003f11151cULL },
238 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000008600fe20ULL },
239 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
240 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
241 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
242 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
243 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000004e0e0804ULL },
244 { "z", 0x00000000c5e405e9ULL },
245 { "zz", 0x00000000a8d8a2c6ULL },
246 { "zzz", 0x00000000fc2af672ULL },
247 { "zzzzz", 0x0000000047d9efe6ULL },
248 { "zzzzzzzz", 0x0000000080d77794ULL },
249 { "zzzzzzzzzzzzz", 0x00000000405f93adULL },
250 { "zzzzzzzzzzzzzzzzzzzzz", 0x00000000fc72838dULL },
251 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x000000007ce160f1ULL },
252 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
253 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
254 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
255 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
256 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x00000000aed9ed1bULL },
257 { "a", 0x000000004605f745ULL },
258 { "ab", 0x00000000d5f06301ULL },
259 { "aba", 0x00000000a85cd91bULL },
260 { "ababa", 0x000000009e3bb52eULL },
261 { "abababab", 0x000000002709b3b9ULL },
262 { "ababababababa", 0x000000003a234174ULL },
263 { "ababababababababababa", 0x000000005c63e5ceULL },
264 { "abababababababababababababababab", 0x0000000013f74334ULL },
265 { "abababababababababababababababab"
266 "abababababababababababababababab"
267 "abababababababababababababababab"
268 "abababababababababababababababab"
269 "abababababababababababababababab", 0x00000000c1a6f135ULL },
271 #error This test only supports 64-bit and 32-bit systems.
274 for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) {
275 StringRef str = golden_data[i].s;
276 hash_code hash = hash_combine_range(str.begin(), str.end());
277 #if 0 // Enable this to generate paste-able text for the above structure.
278 std::string member_str = "\"" + str.str() + "\",";
279 fprintf(stderr, " { %-35s 0x%016llxULL },\n",
280 member_str.c_str(), static_cast<uint64_t>(hash));
282 EXPECT_EQ(static_cast<size_t>(golden_data[i].hash),
283 static_cast<size_t>(hash));
287 TEST(HashingTest, HashCombineBasicTest) {
288 // Hashing a sequence of homogenous types matches range hashing.
289 const int i1 = 42, i2 = 43, i3 = 123, i4 = 999, i5 = 0, i6 = 79;
290 const int arr1[] = { i1, i2, i3, i4, i5, i6 };
291 EXPECT_EQ(hash_combine_range(arr1, arr1 + 1), hash_combine(i1));
292 EXPECT_EQ(hash_combine_range(arr1, arr1 + 2), hash_combine(i1, i2));
293 EXPECT_EQ(hash_combine_range(arr1, arr1 + 3), hash_combine(i1, i2, i3));
294 EXPECT_EQ(hash_combine_range(arr1, arr1 + 4), hash_combine(i1, i2, i3, i4));
295 EXPECT_EQ(hash_combine_range(arr1, arr1 + 5),
296 hash_combine(i1, i2, i3, i4, i5));
297 EXPECT_EQ(hash_combine_range(arr1, arr1 + 6),
298 hash_combine(i1, i2, i3, i4, i5, i6));
300 // Hashing a sequence of heterogenous types which *happen* to all produce the
301 // same data for hashing produces the same as a range-based hash of the
302 // fundamental values.
303 const size_t s1 = 1024, s2 = 8888, s3 = 9000000;
304 const HashableDummy d1 = { 1024 }, d2 = { 8888 }, d3 = { 9000000 };
305 const size_t arr2[] = { s1, s2, s3 };
306 EXPECT_EQ(hash_combine_range(begin(arr2), end(arr2)),
307 hash_combine(s1, s2, s3));
308 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, s2, d3));
309 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, d2, s3));
310 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, s2, s3));
311 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, s3));
312 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, d3));
314 // Permuting values causes hashes to change.
315 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i1, i2));
316 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i2, i1));
317 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i1, i1));
318 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i1));
319 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i2));
320 EXPECT_NE(hash_combine(i2, i1, i1), hash_combine(i1, i1, i2));
321 EXPECT_NE(hash_combine(i1, i1, i2), hash_combine(i1, i2, i1));
322 EXPECT_NE(hash_combine(i1, i2, i1), hash_combine(i2, i1, i1));
324 // Changing type w/o changing value causes hashes to change.
325 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine((char)i1, i2, i3));
326 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, (char)i2, i3));
327 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, i2, (char)i3));
329 // This is array of uint64, but it should have the exact same byte pattern as
330 // an array of LargeTestIntegers.
331 const uint64_t bigarr[] = {
332 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
333 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
334 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
335 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
336 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
337 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
338 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
339 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
340 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
342 // Hash a preposterously large integer, both aligned with the buffer and
344 const LargeTestInteger li = { {
345 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
346 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
347 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
349 // Rotate the storage from 'li'.
350 const LargeTestInteger l2 = { {
351 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL,
352 0xfefefefededededeULL, 0xafafafafededededULL, 0xffffeeeeddddccccULL,
353 0xaaaacbcbffffababULL, 0xaaaaaaaaababababULL
355 const LargeTestInteger l3 = { {
356 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL,
357 0xafafafafededededULL, 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
358 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL
360 EXPECT_EQ(hash_combine_range(begin(bigarr), end(bigarr)),
361 hash_combine(li, li, li));
362 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 9),
363 hash_combine(bigarr[0], l2));
364 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 10),
365 hash_combine(bigarr[0], bigarr[1], l3));
366 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 17),
367 hash_combine(li, bigarr[0], l2));
368 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
369 hash_combine(li, bigarr[0], bigarr[1], l3));
370 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
371 hash_combine(bigarr[0], l2, bigarr[9], l3));
372 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 20),
373 hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19]));