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