blob: f5d6aed5b9931c45e804e4891e429727cf051d36 [file] [log] [blame]
Talin1a4b19e2012-02-18 21:00:49 +00001//===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Hashing.h unit tests.
11//
12//===----------------------------------------------------------------------===//
13
14#include "gtest/gtest.h"
15#include "llvm/ADT/Hashing.h"
Chandler Carruth0b66c6f2012-03-01 18:55:25 +000016#include "llvm/Support/DataTypes.h"
17#include <deque>
18#include <list>
19#include <map>
20#include <vector>
21
22namespace llvm {
23
24// Helper for test code to print hash codes.
25void PrintTo(const hash_code &code, std::ostream *os) {
26 *os << static_cast<size_t>(code);
27}
28
29// Fake an object that is recognized as hashable data to test super large
30// objects.
31struct LargeTestInteger { uint64_t arr[8]; };
32
Francois Pichet5fa6f5b2012-03-03 09:39:54 +000033struct NonPOD {
34 uint64_t x, y;
35 NonPOD(uint64_t x, uint64_t y) : x(x), y(y) {}
36 ~NonPOD() {}
37 friend hash_code hash_value(const NonPOD &obj) {
38 return hash_combine(obj.x, obj.y);
39 }
40};
41
Chandler Carruth0b66c6f2012-03-01 18:55:25 +000042namespace hashing {
43namespace detail {
44template <> struct is_hashable_data<LargeTestInteger> : true_type {};
45} // namespace detail
46} // namespace hashing
47
48} // namespace llvm
Talin1a4b19e2012-02-18 21:00:49 +000049
50using namespace llvm;
51
52namespace {
53
Chandler Carruth1c144892012-03-02 10:56:40 +000054
Chandler Carruth0b66c6f2012-03-01 18:55:25 +000055TEST(HashingTest, HashValueBasicTest) {
56 int x = 42, y = 43, c = 'x';
57 void *p = 0;
58 uint64_t i = 71;
59 const unsigned ci = 71;
60 volatile int vi = 71;
61 const volatile int cvi = 71;
62 uintptr_t addr = reinterpret_cast<uintptr_t>(&y);
Francois Pichet5fa6f5b2012-03-03 09:39:54 +000063 EXPECT_EQ(hash_value(42), hash_value(x));
64 EXPECT_NE(hash_value(42), hash_value(y));
65 EXPECT_NE(hash_value(42), hash_value(p));
66 EXPECT_EQ(hash_value(71), hash_value(i));
67 EXPECT_EQ(hash_value(71), hash_value(ci));
68 EXPECT_EQ(hash_value(71), hash_value(vi));
69 EXPECT_EQ(hash_value(71), hash_value(cvi));
70 EXPECT_EQ(hash_value(c), hash_value('x'));
71 EXPECT_EQ(hash_value('4'), hash_value('0' + 4));
72 EXPECT_EQ(hash_value(addr), hash_value(&y));
Chandler Carruth21d60d52012-03-04 10:23:11 +000073}
Chandler Carruthc7384cf2012-03-02 08:32:29 +000074
Chandler Carruth21d60d52012-03-04 10:23:11 +000075TEST(HashingTest, HashValueStdPair) {
Francois Pichet5fa6f5b2012-03-03 09:39:54 +000076 EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
77 EXPECT_NE(hash_combine(43, 42), hash_value(std::make_pair(42, 43)));
78 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43ull)));
79 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42, 43ull)));
80 EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43)));
Chandler Carruth4d628e22012-03-02 09:26:36 +000081
82 // Note that pairs are implicitly flattened to a direct sequence of data and
83 // hashed efficiently as a consequence.
Francois Pichet5fa6f5b2012-03-03 09:39:54 +000084 EXPECT_EQ(hash_combine(42, 43, 44),
85 hash_value(std::make_pair(42, std::make_pair(43, 44))));
86 EXPECT_EQ(hash_value(std::make_pair(42, std::make_pair(43, 44))),
87 hash_value(std::make_pair(std::make_pair(42, 43), 44)));
Chandler Carruth1c144892012-03-02 10:56:40 +000088
89 // Ensure that pairs which have padding bytes *inside* them don't get treated
90 // this way.
Francois Pichet5fa6f5b2012-03-03 09:39:54 +000091 EXPECT_EQ(hash_combine('0', hash_combine(1ull, '2')),
92 hash_value(std::make_pair('0', std::make_pair(1ull, '2'))));
Chandler Carruth1c144892012-03-02 10:56:40 +000093
94 // Ensure that non-POD pairs don't explode the traits used.
95 NonPOD obj1(1, 2), obj2(3, 4), obj3(5, 6);
Francois Pichet5fa6f5b2012-03-03 09:39:54 +000096 EXPECT_EQ(hash_combine(obj1, hash_combine(obj2, obj3)),
97 hash_value(std::make_pair(obj1, std::make_pair(obj2, obj3))));
Talin1a4b19e2012-02-18 21:00:49 +000098}
99
Chandler Carruth9406da62012-03-04 10:23:15 +0000100TEST(HashingTest, HashValueStdString) {
101 std::string s = "Hello World!";
102 EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size()), hash_value(s));
103 EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size() - 1),
104 hash_value(s.substr(0, s.size() - 1)));
105 EXPECT_EQ(hash_combine_range(s.c_str() + 1, s.c_str() + s.size() - 1),
106 hash_value(s.substr(1, s.size() - 2)));
107
108 std::wstring ws = L"Hello Wide World!";
109 EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size()),
110 hash_value(ws));
111 EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size() - 1),
112 hash_value(ws.substr(0, ws.size() - 1)));
113 EXPECT_EQ(hash_combine_range(ws.c_str() + 1, ws.c_str() + ws.size() - 1),
114 hash_value(ws.substr(1, ws.size() - 2)));
115}
116
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000117template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
118template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
119
120// Provide a dummy, hashable type designed for easy verification: its hash is
121// the same as its value.
122struct HashableDummy { size_t value; };
123hash_code hash_value(HashableDummy dummy) { return dummy.value; }
124
125TEST(HashingTest, HashCombineRangeBasicTest) {
126 // Leave this uninitialized in the hope that valgrind will catch bad reads.
127 int dummy;
128 hash_code dummy_hash = hash_combine_range(&dummy, &dummy);
Chandler Carruth41669892012-03-02 00:48:38 +0000129 EXPECT_NE(hash_code(0), dummy_hash);
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000130
131 const int arr1[] = { 1, 2, 3 };
132 hash_code arr1_hash = hash_combine_range(begin(arr1), end(arr1));
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000133 EXPECT_NE(dummy_hash, arr1_hash);
134 EXPECT_EQ(arr1_hash, hash_combine_range(begin(arr1), end(arr1)));
135
136 const std::vector<int> vec(begin(arr1), end(arr1));
137 EXPECT_EQ(arr1_hash, hash_combine_range(vec.begin(), vec.end()));
138
139 const std::list<int> list(begin(arr1), end(arr1));
140 EXPECT_EQ(arr1_hash, hash_combine_range(list.begin(), list.end()));
141
142 const std::deque<int> deque(begin(arr1), end(arr1));
143 EXPECT_EQ(arr1_hash, hash_combine_range(deque.begin(), deque.end()));
144
145 const int arr2[] = { 3, 2, 1 };
146 hash_code arr2_hash = hash_combine_range(begin(arr2), end(arr2));
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000147 EXPECT_NE(dummy_hash, arr2_hash);
148 EXPECT_NE(arr1_hash, arr2_hash);
149
150 const int arr3[] = { 1, 1, 2, 3 };
151 hash_code arr3_hash = hash_combine_range(begin(arr3), end(arr3));
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000152 EXPECT_NE(dummy_hash, arr3_hash);
153 EXPECT_NE(arr1_hash, arr3_hash);
154
155 const int arr4[] = { 1, 2, 3, 3 };
156 hash_code arr4_hash = hash_combine_range(begin(arr4), end(arr4));
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000157 EXPECT_NE(dummy_hash, arr4_hash);
158 EXPECT_NE(arr1_hash, arr4_hash);
159
160 const size_t arr5[] = { 1, 2, 3 };
161 const HashableDummy d_arr5[] = { {1}, {2}, {3} };
162 hash_code arr5_hash = hash_combine_range(begin(arr5), end(arr5));
163 hash_code d_arr5_hash = hash_combine_range(begin(d_arr5), end(d_arr5));
164 EXPECT_EQ(arr5_hash, d_arr5_hash);
Talin1a4b19e2012-02-18 21:00:49 +0000165}
166
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000167TEST(HashingTest, HashCombineRangeLengthDiff) {
168 // Test that as only the length varies, we compute different hash codes for
169 // sequences.
170 std::map<size_t, size_t> code_to_size;
171 std::vector<char> all_one_c(256, '\xff');
172 for (unsigned Idx = 1, Size = all_one_c.size(); Idx < Size; ++Idx) {
173 hash_code code = hash_combine_range(&all_one_c[0], &all_one_c[0] + Idx);
174 std::map<size_t, size_t>::iterator
175 I = code_to_size.insert(std::make_pair(code, Idx)).first;
176 EXPECT_EQ(Idx, I->second);
177 }
178 code_to_size.clear();
179 std::vector<char> all_zero_c(256, '\0');
180 for (unsigned Idx = 1, Size = all_zero_c.size(); Idx < Size; ++Idx) {
181 hash_code code = hash_combine_range(&all_zero_c[0], &all_zero_c[0] + Idx);
182 std::map<size_t, size_t>::iterator
183 I = code_to_size.insert(std::make_pair(code, Idx)).first;
184 EXPECT_EQ(Idx, I->second);
185 }
186 code_to_size.clear();
187 std::vector<unsigned> all_one_int(512, -1);
188 for (unsigned Idx = 1, Size = all_one_int.size(); Idx < Size; ++Idx) {
189 hash_code code = hash_combine_range(&all_one_int[0], &all_one_int[0] + Idx);
190 std::map<size_t, size_t>::iterator
191 I = code_to_size.insert(std::make_pair(code, Idx)).first;
192 EXPECT_EQ(Idx, I->second);
193 }
194 code_to_size.clear();
195 std::vector<unsigned> all_zero_int(512, 0);
196 for (unsigned Idx = 1, Size = all_zero_int.size(); Idx < Size; ++Idx) {
197 hash_code code = hash_combine_range(&all_zero_int[0], &all_zero_int[0] + Idx);
198 std::map<size_t, size_t>::iterator
199 I = code_to_size.insert(std::make_pair(code, Idx)).first;
200 EXPECT_EQ(Idx, I->second);
201 }
Talin1a4b19e2012-02-18 21:00:49 +0000202}
203
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000204TEST(HashingTest, HashCombineRangeGoldenTest) {
205 struct { const char *s; uint64_t hash; } golden_data[] = {
Chandler Carruth97312942012-03-01 23:06:19 +0000206#if SIZE_MAX == UINT64_MAX
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000207 { "a", 0xaeb6f9d5517c61f8ULL },
208 { "ab", 0x7ab1edb96be496b4ULL },
209 { "abc", 0xe38e60bf19c71a3fULL },
210 { "abcde", 0xd24461a66de97f6eULL },
211 { "abcdefgh", 0x4ef872ec411dec9dULL },
212 { "abcdefghijklm", 0xe8a865539f4eadfeULL },
213 { "abcdefghijklmnopqrstu", 0x261cdf85faaf4e79ULL },
214 { "abcdefghijklmnopqrstuvwxyzabcdef", 0x43ba70e4198e3b2aULL },
215 { "abcdefghijklmnopqrstuvwxyzabcdef"
216 "abcdefghijklmnopqrstuvwxyzghijkl"
217 "abcdefghijklmnopqrstuvwxyzmnopqr"
218 "abcdefghijklmnopqrstuvwxyzstuvwx"
219 "abcdefghijklmnopqrstuvwxyzyzabcd", 0xdcd57fb2afdf72beULL },
220 { "a", 0xaeb6f9d5517c61f8ULL },
221 { "aa", 0xf2b3b69a9736a1ebULL },
222 { "aaa", 0xf752eb6f07b1cafeULL },
223 { "aaaaa", 0x812bd21e1236954cULL },
224 { "aaaaaaaa", 0xff07a2cff08ac587ULL },
225 { "aaaaaaaaaaaaa", 0x84ac949d54d704ecULL },
226 { "aaaaaaaaaaaaaaaaaaaaa", 0xcb2c8fb6be8f5648ULL },
227 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xcc40ab7f164091b6ULL },
228 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
229 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
230 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
231 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
232 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xc58e174c1e78ffe9ULL },
233 { "z", 0x1ba160d7e8f8785cULL },
234 { "zz", 0x2c5c03172f1285d7ULL },
235 { "zzz", 0x9d2c4f4b507a2ac3ULL },
236 { "zzzzz", 0x0f03b9031735693aULL },
237 { "zzzzzzzz", 0xe674147c8582c08eULL },
238 { "zzzzzzzzzzzzz", 0x3162d9fa6938db83ULL },
239 { "zzzzzzzzzzzzzzzzzzzzz", 0x37b9a549e013620cULL },
240 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x8921470aff885016ULL },
241 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
242 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
243 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
244 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
245 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0xf60fdcd9beb08441ULL },
246 { "a", 0xaeb6f9d5517c61f8ULL },
247 { "ab", 0x7ab1edb96be496b4ULL },
248 { "aba", 0x3edb049950884d0aULL },
249 { "ababa", 0x8f2de9e73a97714bULL },
250 { "abababab", 0xee14a29ddf0ce54cULL },
251 { "ababababababa", 0x38b3ddaada2d52b4ULL },
252 { "ababababababababababa", 0xd3665364219f2b85ULL },
Chandler Carruthc3f99182012-03-02 10:01:29 +0000253 { "abababababababababababababababab", 0xa75cd6afbf1bc972ULL },
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000254 { "abababababababababababababababab"
255 "abababababababababababababababab"
256 "abababababababababababababababab"
257 "abababababababababababababababab"
258 "abababababababababababababababab", 0x840192d129f7a22bULL }
Chandler Carruth97312942012-03-01 23:06:19 +0000259#elif SIZE_MAX == UINT32_MAX
Chandler Carruth4fc5bdf2012-03-02 10:01:27 +0000260 { "a", 0x000000004605f745ULL },
261 { "ab", 0x00000000d5f06301ULL },
262 { "abc", 0x00000000559fe1eeULL },
263 { "abcde", 0x00000000424028d7ULL },
264 { "abcdefgh", 0x000000007bb119f8ULL },
265 { "abcdefghijklm", 0x00000000edbca513ULL },
266 { "abcdefghijklmnopqrstu", 0x000000007c15712eULL },
267 { "abcdefghijklmnopqrstuvwxyzabcdef", 0x000000000b3aad66ULL },
268 { "abcdefghijklmnopqrstuvwxyzabcdef"
269 "abcdefghijklmnopqrstuvwxyzghijkl"
270 "abcdefghijklmnopqrstuvwxyzmnopqr"
271 "abcdefghijklmnopqrstuvwxyzstuvwx"
272 "abcdefghijklmnopqrstuvwxyzyzabcd", 0x000000008c758c8bULL },
273 { "a", 0x000000004605f745ULL },
274 { "aa", 0x00000000dc0a52daULL },
275 { "aaa", 0x00000000b309274fULL },
276 { "aaaaa", 0x00000000203b5ef6ULL },
277 { "aaaaaaaa", 0x00000000a429e18fULL },
278 { "aaaaaaaaaaaaa", 0x000000008662070bULL },
279 { "aaaaaaaaaaaaaaaaaaaaa", 0x000000003f11151cULL },
280 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000008600fe20ULL },
281 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
282 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
283 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
284 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
285 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000004e0e0804ULL },
286 { "z", 0x00000000c5e405e9ULL },
287 { "zz", 0x00000000a8d8a2c6ULL },
288 { "zzz", 0x00000000fc2af672ULL },
289 { "zzzzz", 0x0000000047d9efe6ULL },
290 { "zzzzzzzz", 0x0000000080d77794ULL },
291 { "zzzzzzzzzzzzz", 0x00000000405f93adULL },
292 { "zzzzzzzzzzzzzzzzzzzzz", 0x00000000fc72838dULL },
293 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x000000007ce160f1ULL },
294 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
295 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
296 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
297 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
298 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x00000000aed9ed1bULL },
299 { "a", 0x000000004605f745ULL },
300 { "ab", 0x00000000d5f06301ULL },
301 { "aba", 0x00000000a85cd91bULL },
302 { "ababa", 0x000000009e3bb52eULL },
303 { "abababab", 0x000000002709b3b9ULL },
304 { "ababababababa", 0x000000003a234174ULL },
305 { "ababababababababababa", 0x000000005c63e5ceULL },
306 { "abababababababababababababababab", 0x0000000013f74334ULL },
307 { "abababababababababababababababab"
308 "abababababababababababababababab"
309 "abababababababababababababababab"
310 "abababababababababababababababab"
311 "abababababababababababababababab", 0x00000000c1a6f135ULL },
Chandler Carruth97312942012-03-01 23:06:19 +0000312#else
313#error This test only supports 64-bit and 32-bit systems.
314#endif
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000315 };
316 for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) {
317 StringRef str = golden_data[i].s;
318 hash_code hash = hash_combine_range(str.begin(), str.end());
Chandler Carruth5a491ca2012-03-01 23:20:45 +0000319#if 0 // Enable this to generate paste-able text for the above structure.
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000320 std::string member_str = "\"" + str.str() + "\",";
Chandler Carruth97312942012-03-01 23:06:19 +0000321 fprintf(stderr, " { %-35s 0x%016llxULL },\n",
322 member_str.c_str(), static_cast<uint64_t>(hash));
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000323#endif
324 EXPECT_EQ(static_cast<size_t>(golden_data[i].hash),
325 static_cast<size_t>(hash));
326 }
Talin1a4b19e2012-02-18 21:00:49 +0000327}
328
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000329TEST(HashingTest, HashCombineBasicTest) {
330 // Hashing a sequence of homogenous types matches range hashing.
331 const int i1 = 42, i2 = 43, i3 = 123, i4 = 999, i5 = 0, i6 = 79;
332 const int arr1[] = { i1, i2, i3, i4, i5, i6 };
333 EXPECT_EQ(hash_combine_range(arr1, arr1 + 1), hash_combine(i1));
334 EXPECT_EQ(hash_combine_range(arr1, arr1 + 2), hash_combine(i1, i2));
335 EXPECT_EQ(hash_combine_range(arr1, arr1 + 3), hash_combine(i1, i2, i3));
336 EXPECT_EQ(hash_combine_range(arr1, arr1 + 4), hash_combine(i1, i2, i3, i4));
337 EXPECT_EQ(hash_combine_range(arr1, arr1 + 5),
338 hash_combine(i1, i2, i3, i4, i5));
339 EXPECT_EQ(hash_combine_range(arr1, arr1 + 6),
340 hash_combine(i1, i2, i3, i4, i5, i6));
Talin1a4b19e2012-02-18 21:00:49 +0000341
Chandler Carruth0b66c6f2012-03-01 18:55:25 +0000342 // Hashing a sequence of heterogenous types which *happen* to all produce the
343 // same data for hashing produces the same as a range-based hash of the
344 // fundamental values.
345 const size_t s1 = 1024, s2 = 8888, s3 = 9000000;
346 const HashableDummy d1 = { 1024 }, d2 = { 8888 }, d3 = { 9000000 };
347 const size_t arr2[] = { s1, s2, s3 };
348 EXPECT_EQ(hash_combine_range(begin(arr2), end(arr2)),
349 hash_combine(s1, s2, s3));
350 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, s2, d3));
351 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, d2, s3));
352 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, s2, s3));
353 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, s3));
354 EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, d3));
355
356 // Permuting values causes hashes to change.
357 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i1, i2));
358 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i2, i1));
359 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i1, i1));
360 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i1));
361 EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i2));
362 EXPECT_NE(hash_combine(i2, i1, i1), hash_combine(i1, i1, i2));
363 EXPECT_NE(hash_combine(i1, i1, i2), hash_combine(i1, i2, i1));
364 EXPECT_NE(hash_combine(i1, i2, i1), hash_combine(i2, i1, i1));
365
366 // Changing type w/o changing value causes hashes to change.
367 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine((char)i1, i2, i3));
368 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, (char)i2, i3));
369 EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, i2, (char)i3));
370
371 // This is array of uint64, but it should have the exact same byte pattern as
372 // an array of LargeTestIntegers.
373 const uint64_t bigarr[] = {
374 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
375 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
376 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
377 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
378 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
379 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
380 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
381 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
382 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
383 };
384 // Hash a preposterously large integer, both aligned with the buffer and
385 // misaligned.
386 const LargeTestInteger li = { {
387 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
388 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
389 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
390 } };
391 // Rotate the storage from 'li'.
392 const LargeTestInteger l2 = { {
393 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL,
394 0xfefefefededededeULL, 0xafafafafededededULL, 0xffffeeeeddddccccULL,
395 0xaaaacbcbffffababULL, 0xaaaaaaaaababababULL
396 } };
397 const LargeTestInteger l3 = { {
398 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL,
399 0xafafafafededededULL, 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
400 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL
401 } };
402 EXPECT_EQ(hash_combine_range(begin(bigarr), end(bigarr)),
403 hash_combine(li, li, li));
404 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 9),
405 hash_combine(bigarr[0], l2));
406 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 10),
407 hash_combine(bigarr[0], bigarr[1], l3));
408 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 17),
409 hash_combine(li, bigarr[0], l2));
410 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
411 hash_combine(li, bigarr[0], bigarr[1], l3));
412 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
413 hash_combine(bigarr[0], l2, bigarr[9], l3));
414 EXPECT_EQ(hash_combine_range(bigarr, bigarr + 20),
415 hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19]));
Talin1a4b19e2012-02-18 21:00:49 +0000416}
417
418}