Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
hash_fct_test.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
52#include <gtest/gtest.h>
53#include <hash-fct.H>
54
55#include <cstring>
56#include <random>
57#include <set>
58#include <string>
59#include <vector>
60
61using namespace Aleph;
62
63// JSW hash requires initialization (defined in Aleph namespace in hash-fct.C)
64namespace Aleph {
65 extern void init_jsw() noexcept;
66}
67
68class HashTestEnvironment : public ::testing::Environment
69{
70public:
71 void SetUp() override
72 {
73 init_jsw();
74 }
75};
76
77// Register the environment to initialize jsw_hash table before any tests run
78testing::Environment* const hash_env =
79 testing::AddGlobalTestEnvironment(new HashTestEnvironment);
80
81// ==================== Consistency Tests ====================
82// Hash functions must produce the same output for the same input
83
84class HashConsistencyTest : public ::testing::Test
85{
86protected:
87 const char* test_string = "test_string_for_hashing";
88 const std::string test_std_string = "test_string_for_hashing";
89 const int test_int = 42;
90 const double test_double = 3.14159265359;
91};
92
94{
95 auto h1 = add_hash(test_string);
96 auto h2 = add_hash(test_string);
97 EXPECT_EQ(h1, h2);
98
99 auto h3 = add_hash(test_std_string);
100 auto h4 = add_hash(test_std_string);
101 EXPECT_EQ(h3, h4);
102 EXPECT_EQ(h1, h3); // const char* and std::string should match
103
104 auto h5 = add_hash(test_int);
105 auto h6 = add_hash(test_int);
106 EXPECT_EQ(h5, h6);
107}
108
110{
111 auto h1 = xor_hash(test_string);
112 auto h2 = xor_hash(test_string);
113 EXPECT_EQ(h1, h2);
114
115 auto h3 = xor_hash(test_std_string);
116 auto h4 = xor_hash(test_std_string);
117 EXPECT_EQ(h3, h4);
118 EXPECT_EQ(h1, h3);
119
120 auto h5 = xor_hash(test_int);
121 auto h6 = xor_hash(test_int);
122 EXPECT_EQ(h5, h6);
123}
124
126{
127 auto h1 = rot_hash(test_string);
128 auto h2 = rot_hash(test_string);
129 EXPECT_EQ(h1, h2);
130
131 auto h3 = rot_hash(test_std_string);
132 EXPECT_EQ(h1, h3);
133
134 auto h5 = rot_hash(test_int);
135 auto h6 = rot_hash(test_int);
136 EXPECT_EQ(h5, h6);
137}
138
140{
141 auto h1 = djb_hash(test_string);
142 auto h2 = djb_hash(test_string);
143 EXPECT_EQ(h1, h2);
144
145 auto h3 = djb_hash(test_std_string);
146 EXPECT_EQ(h1, h3);
147
148 auto h5 = djb_hash(test_int);
149 auto h6 = djb_hash(test_int);
150 EXPECT_EQ(h5, h6);
151}
152
154{
155 auto h1 = sax_hash(test_string);
156 auto h2 = sax_hash(test_string);
157 EXPECT_EQ(h1, h2);
158
159 auto h3 = sax_hash(test_std_string);
160 EXPECT_EQ(h1, h3);
161
162 auto h5 = sax_hash(test_int);
163 auto h6 = sax_hash(test_int);
164 EXPECT_EQ(h5, h6);
165}
166
168{
169 auto h1 = fnv_hash(test_string);
170 auto h2 = fnv_hash(test_string);
171 EXPECT_EQ(h1, h2);
172
173 auto h3 = fnv_hash(test_std_string);
174 EXPECT_EQ(h1, h3);
175
176 auto h5 = fnv_hash(test_int);
177 auto h6 = fnv_hash(test_int);
178 EXPECT_EQ(h5, h6);
179}
180
182{
183 auto h1 = oat_hash(test_string);
184 auto h2 = oat_hash(test_string);
185 EXPECT_EQ(h1, h2);
186
187 auto h3 = oat_hash(test_std_string);
188 EXPECT_EQ(h1, h3);
189
190 auto h5 = oat_hash(test_int);
191 auto h6 = oat_hash(test_int);
192 EXPECT_EQ(h5, h6);
193}
194
196{
197 auto h1 = jsw_hash(test_string);
198 auto h2 = jsw_hash(test_string);
199 EXPECT_EQ(h1, h2);
200
201 auto h3 = jsw_hash(test_std_string);
202 EXPECT_EQ(h1, h3);
203
204 auto h5 = jsw_hash(test_int);
205 auto h6 = jsw_hash(test_int);
206 EXPECT_EQ(h5, h6);
207}
208
210{
211 auto h1 = elf_hash(test_string);
212 auto h2 = elf_hash(test_string);
213 EXPECT_EQ(h1, h2);
214
215 auto h3 = elf_hash(test_std_string);
216 EXPECT_EQ(h1, h3);
217
218 auto h5 = elf_hash(test_int);
219 auto h6 = elf_hash(test_int);
220 EXPECT_EQ(h5, h6);
221}
222
224{
225 unsigned seed = 12345;
226 // Use std::string for consistency - const char* would use template version
227 auto h1 = jen_hash(test_std_string, seed);
228 auto h2 = jen_hash(test_std_string, seed);
229 EXPECT_EQ(h1, h2);
230
231 // Also test via void* API directly
232 auto h3 = jen_hash((void*)test_string, strlen(test_string), seed);
233 auto h4 = jen_hash((void*)test_std_string.c_str(), test_std_string.size(), seed);
234 EXPECT_EQ(h3, h4);
235
236 auto h5 = jen_hash(test_int, seed);
237 auto h6 = jen_hash(test_int, seed);
238 EXPECT_EQ(h5, h6);
239}
240
242{
243 auto h1 = SuperFastHash(test_string);
244 auto h2 = SuperFastHash(test_string);
245 EXPECT_EQ(h1, h2);
246
247 auto h3 = SuperFastHash(test_std_string);
248 EXPECT_EQ(h1, h3);
249
250 auto h5 = SuperFastHash(test_int);
251 auto h6 = SuperFastHash(test_int);
252 EXPECT_EQ(h5, h6);
253}
254
256{
257 unsigned long seed = 42;
258 auto h1 = murmur3hash(test_std_string, seed);
259 auto h2 = murmur3hash(test_std_string, seed);
260 EXPECT_EQ(h1, h2);
261
262 auto h3 = murmur3hash(test_int, seed);
263 auto h4 = murmur3hash(test_int, seed);
264 EXPECT_EQ(h3, h4);
265}
266
268{
269 auto h1 = dft_hash_fct(test_std_string);
270 auto h2 = dft_hash_fct(test_std_string);
271 EXPECT_EQ(h1, h2);
272
273 auto h3 = dft_hash_fct(test_int);
274 auto h4 = dft_hash_fct(test_int);
275 EXPECT_EQ(h3, h4);
276}
277
278// ==================== Edge Case Tests ====================
279
280class HashEdgeCaseTest : public ::testing::Test
281{
282protected:
283 const char* empty_string = "";
284 const std::string empty_std_string = "";
285 const char* single_char = "a";
286 std::string large_string;
287
288 void SetUp() override
289 {
290 // Create a large string (1MB)
291 large_string.resize(1024 * 1024, 'x');
292 }
293};
294
296{
297 // Empty strings should hash consistently (though maybe to 0 for simple hashes)
298 EXPECT_EQ(add_hash(empty_string), add_hash(empty_std_string));
299 EXPECT_EQ(xor_hash(empty_string), xor_hash(empty_std_string));
300 EXPECT_EQ(rot_hash(empty_string), rot_hash(empty_std_string));
301 EXPECT_EQ(djb_hash(empty_string), djb_hash(empty_std_string));
302 EXPECT_EQ(sax_hash(empty_string), sax_hash(empty_std_string));
303 EXPECT_EQ(fnv_hash(empty_string), fnv_hash(empty_std_string));
304 EXPECT_EQ(oat_hash(empty_string), oat_hash(empty_std_string));
305 EXPECT_EQ(jsw_hash(empty_string), jsw_hash(empty_std_string));
306 EXPECT_EQ(elf_hash(empty_string), elf_hash(empty_std_string));
307 EXPECT_EQ(SuperFastHash(empty_string), SuperFastHash(empty_std_string));
308}
309
311{
312 const std::string single_std = "a";
313
314 // All hashes should produce non-zero for single char 'a'
315 EXPECT_NE(add_hash(single_char), 0u);
316 EXPECT_NE(xor_hash(single_char), 0u);
317 EXPECT_NE(rot_hash(single_char), 0u);
318 EXPECT_NE(djb_hash(single_char), 0u);
319 EXPECT_NE(sax_hash(single_char), 0u);
320 EXPECT_NE(fnv_hash(single_char), 0u);
321 EXPECT_NE(oat_hash(single_char), 0u);
322 EXPECT_NE(jsw_hash(single_char), 0u);
323 EXPECT_NE(elf_hash(single_char), 0u);
324 EXPECT_NE(SuperFastHash(single_char), 0u);
325
326 // Verify consistency
327 EXPECT_EQ(add_hash(single_char), add_hash(single_std));
328}
329
331{
332 // Large strings should hash correctly
333 auto h1 = fnv_hash(large_string);
334 auto h2 = fnv_hash(large_string);
335 EXPECT_EQ(h1, h2);
336
337 auto h3 = SuperFastHash(large_string);
338 auto h4 = SuperFastHash(large_string);
339 EXPECT_EQ(h3, h4);
340
341 auto h5 = oat_hash(large_string);
342 auto h6 = oat_hash(large_string);
343 EXPECT_EQ(h5, h6);
344
345 auto h7 = murmur3hash(large_string, 42ul);
346 auto h8 = murmur3hash(large_string, 42ul);
347 EXPECT_EQ(h7, h8);
348}
349
351{
352 // Test hashing data with embedded null bytes
353 char data1[] = {1, 0, 2, 0, 3};
354 char data2[] = {1, 0, 2, 0, 3};
355
361}
362
363// ==================== Different Inputs Produce Different Hashes ====================
364
365class HashDifferenceTest : public ::testing::Test
366{
367};
368
370{
371 const char* s1 = "hello";
372 const char* s2 = "world";
373 const char* s3 = "hello1"; // Very similar to s1
374
375 // Production-quality hashes should distinguish these
378
381
384
389}
390
404
406{
407 const std::string key = "test_key";
408
409 auto h1 = jen_hash(key, 1);
410 auto h2 = jen_hash(key, 2);
411 auto h3 = jen_hash(key, 100);
412
413 EXPECT_NE(h1, h2);
414 EXPECT_NE(h1, h3);
415 EXPECT_NE(h2, h3);
416
417 auto m1 = murmur3hash(key, 1ul);
418 auto m2 = murmur3hash(key, 2ul);
419 auto m3 = murmur3hash(key, 100ul);
420
421 EXPECT_NE(m1, m2);
422 EXPECT_NE(m1, m3);
423 EXPECT_NE(m2, m3);
424}
425
426// ==================== Void Pointer API Tests ====================
427
428class HashVoidPtrTest : public ::testing::Test
429{
430};
431
433{
434 int arr1[] = {1, 2, 3, 4, 5};
435 int arr2[] = {1, 2, 3, 4, 5};
436 int arr3[] = {1, 2, 3, 4, 6}; // Different
437
438 EXPECT_EQ(add_hash(arr1, sizeof(arr1)), add_hash(arr2, sizeof(arr2)));
439 EXPECT_NE(add_hash(arr1, sizeof(arr1)), add_hash(arr3, sizeof(arr3)));
440
441 EXPECT_EQ(fnv_hash(arr1, sizeof(arr1)), fnv_hash(arr2, sizeof(arr2)));
442 EXPECT_NE(fnv_hash(arr1, sizeof(arr1)), fnv_hash(arr3, sizeof(arr3)));
443
444 EXPECT_EQ(oat_hash(arr1, sizeof(arr1)), oat_hash(arr2, sizeof(arr2)));
445 EXPECT_EQ(SuperFastHash(arr1, sizeof(arr1)), SuperFastHash(arr2, sizeof(arr2)));
446 // jen_hash with void* requires explicit cast for arrays and explicit initval to avoid ambiguity with template overload
447 EXPECT_EQ(jen_hash((void*)arr1, sizeof(arr1), Default_Hash_Seed), jen_hash((void*)arr2, sizeof(arr2), Default_Hash_Seed));
448}
449
451{
452 // Use a packed struct or memset to ensure no padding issues
453 struct TestStruct
454 {
455 int a;
456 double b;
457 char c;
458 };
459
460 // Zero-initialize to avoid uninitialized padding bytes
461 TestStruct s1, s2, s3;
462 memset(&s1, 0, sizeof(s1));
463 memset(&s2, 0, sizeof(s2));
464 memset(&s3, 0, sizeof(s3));
465 s1.a = 1; s1.b = 2.5; s1.c = 'x';
466 s2.a = 1; s2.b = 2.5; s2.c = 'x';
467 s3.a = 1; s3.b = 2.5; s3.c = 'y';
468
469 EXPECT_EQ(fnv_hash(&s1, sizeof(s1)), fnv_hash(&s2, sizeof(s2)));
470 EXPECT_NE(fnv_hash(&s1, sizeof(s1)), fnv_hash(&s3, sizeof(s3)));
471
472 EXPECT_EQ(oat_hash(&s1, sizeof(s1)), oat_hash(&s2, sizeof(s2)));
473 EXPECT_EQ(SuperFastHash(&s1, sizeof(s1)), SuperFastHash(&s2, sizeof(s2)));
474}
475
476// ==================== Template API Tests ====================
477
478class HashTemplateTest : public ::testing::Test
479{
480};
481
483{
484 int val = 12345;
485
486 // Template versions should work
487 auto h1 = add_hash(val);
488 auto h2 = add_hash(&val, sizeof(val));
489 EXPECT_EQ(h1, h2);
490
491 auto h3 = fnv_hash(val);
492 auto h4 = fnv_hash(&val, sizeof(val));
493 EXPECT_EQ(h3, h4);
494}
495
497{
498 double val = 3.14159;
499
500 auto h1 = fnv_hash(val);
501 auto h2 = fnv_hash(&val, sizeof(val));
502 EXPECT_EQ(h1, h2);
503
504 auto h3 = oat_hash(val);
505 auto h4 = oat_hash(&val, sizeof(val));
506 EXPECT_EQ(h3, h4);
507}
508
510{
511 long long val = 9223372036854775807LL;
512
513 auto h1 = fnv_hash(val);
514 auto h2 = fnv_hash(&val, sizeof(val));
515 EXPECT_EQ(h1, h2);
516
517 auto h3 = SuperFastHash(val);
518 auto h4 = SuperFastHash(&val, sizeof(val));
519 EXPECT_EQ(h3, h4);
520}
521
522// ==================== Pair Hash Functions ====================
523
525{
526 std::pair<int, int> p1{1, 2};
527 std::pair<int, int> p2{1, 2};
528 std::pair<int, int> p3{2, 1};
529
530 auto h1 = pair_dft_hash_fct(p1);
531 auto h2 = pair_dft_hash_fct(p2);
532 auto h3 = pair_dft_hash_fct(p3);
533
534 EXPECT_EQ(h1, h2);
535 // Note: pair_dft_hash_fct uses addition, so {1,2} and {2,1} might collide
536 // This is a known limitation of simple combination functions
537 (void)h3; // Suppress unused variable warning - see comment above
538}
539
541{
542 std::pair<std::string, std::string> p1{"hello", "world"};
543 std::pair<std::string, std::string> p2{"hello", "world"};
544
545 auto h1 = pair_snd_hash_fct(p1);
546 auto h2 = pair_snd_hash_fct(p2);
547
548 EXPECT_EQ(h1, h2);
549}
550
551// ==================== Distribution Quality Tests ====================
552
553class HashDistributionTest : public ::testing::Test
554{
555protected:
556 static constexpr size_t NUM_KEYS = 10000;
557 std::vector<std::string> keys;
558
559 void SetUp() override
560 {
561 std::mt19937 gen(42); // Fixed seed for reproducibility
562 std::uniform_int_distribution<> len_dist(5, 20);
563 std::uniform_int_distribution<> char_dist('a', 'z');
564
565 for (size_t i = 0; i < NUM_KEYS; ++i)
566 {
567 int len = len_dist(gen);
568 std::string s;
569 s.reserve(len);
570 for (int j = 0; j < len; ++j)
571 s += static_cast<char>(char_dist(gen));
572 keys.push_back(std::move(s));
573 }
574 }
575
576 // Measure hash uniqueness (collision ratio without modulo)
577 // Good hash functions should have very few or no collisions
578 double measureHashUniqueness(const std::vector<size_t>& hashes)
579 {
580 std::set<size_t> unique_hashes(hashes.begin(), hashes.end());
581 return static_cast<double>(unique_hashes.size()) /
582 static_cast<double>(hashes.size());
583 }
584};
585
586// Test that production-quality hash functions produce mostly unique hashes
587// (without modulo). We expect >90% uniqueness for 10000 distinct random strings.
589{
590 std::vector<size_t> hashes;
591 hashes.reserve(NUM_KEYS);
592 for (const auto& key : keys)
593 hashes.push_back(fnv_hash(key));
594
595 double uniqueness = measureHashUniqueness(hashes);
596 EXPECT_GT(uniqueness, 0.90) << "FNV hash uniqueness: " << uniqueness;
597}
598
600{
601 std::vector<size_t> hashes;
602 hashes.reserve(NUM_KEYS);
603 for (const auto& key : keys)
604 hashes.push_back(oat_hash(key));
605
606 double uniqueness = measureHashUniqueness(hashes);
607 EXPECT_GT(uniqueness, 0.90) << "OAT hash uniqueness: " << uniqueness;
608}
609
611{
612 std::vector<size_t> hashes;
613 hashes.reserve(NUM_KEYS);
614 for (const auto& key : keys)
615 hashes.push_back(SuperFastHash(key));
616
617 double uniqueness = measureHashUniqueness(hashes);
618 EXPECT_GT(uniqueness, 0.90) << "SuperFastHash uniqueness: " << uniqueness;
619}
620
622{
623 std::vector<size_t> hashes;
624 hashes.reserve(NUM_KEYS);
625 for (const auto& key : keys)
626 hashes.push_back(jen_hash(key, 0));
627
628 double uniqueness = measureHashUniqueness(hashes);
629 EXPECT_GT(uniqueness, 0.90) << "Jenkins hash uniqueness: " << uniqueness;
630}
631
633{
634 std::vector<size_t> hashes;
635 hashes.reserve(NUM_KEYS);
636 for (const auto& key : keys)
637 hashes.push_back(murmur3hash(key, 42ul));
638
639 double uniqueness = measureHashUniqueness(hashes);
640 EXPECT_GT(uniqueness, 0.90) << "MurmurHash3 uniqueness: " << uniqueness;
641}
642
644{
645 std::vector<size_t> hashes;
646 hashes.reserve(NUM_KEYS);
647 for (const auto& key : keys)
648 hashes.push_back(dft_hash_fct(key));
649
650 double uniqueness = measureHashUniqueness(hashes);
651 EXPECT_GT(uniqueness, 0.90) << "dft_hash_fct uniqueness: " << uniqueness;
652}
653
654// ==================== Avalanche Property Tests ====================
655// Small changes in input should cause large changes in output
656
657class HashAvalancheTest : public ::testing::Test
658{
659protected:
660 // Count bit differences between two hash values
661 static int bitDifference(size_t h1, size_t h2)
662 {
663 size_t diff = h1 ^ h2;
664 int count = 0;
665 while (diff)
666 {
667 count += diff & 1;
668 diff >>= 1;
669 }
670 return count;
671 }
672};
673
675{
676 // Changing a single bit should cause ~50% of output bits to change
677 // for a good hash function
678 unsigned char data1[16] = {0};
679 unsigned char data2[16] = {0};
680 data2[0] = 1; // Single bit difference
681
682 auto h1 = jen_hash(data1, 16);
683 auto h2 = jen_hash(data2, 16);
684
685 int bit_diff = bitDifference(h1, h2);
686 // Good hash should have at least 20% of bits different
687 EXPECT_GT(bit_diff, (int)(sizeof(size_t) * 8 * 0.2))
688 << "Jenkins hash has poor avalanche property";
689}
690
692{
693 unsigned char data1[16] = {0};
694 unsigned char data2[16] = {0};
695 data2[0] = 1;
696
697 auto h1 = murmur3hash(std::string((char*)data1, 16), 42ul);
698 auto h2 = murmur3hash(std::string((char*)data2, 16), 42ul);
699
700 int bit_diff = bitDifference(h1, h2);
701 EXPECT_GT(bit_diff, (int)(sizeof(size_t) * 8 * 0.2))
702 << "MurmurHash3 has poor avalanche property";
703}
704
706{
707 unsigned char data1[16] = {0};
708 unsigned char data2[16] = {0};
709 data2[0] = 1;
710
711 auto h1 = oat_hash(data1, 16);
712 auto h2 = oat_hash(data2, 16);
713
714 int bit_diff = bitDifference(h1, h2);
715 EXPECT_GT(bit_diff, (int)(sizeof(size_t) * 8 * 0.2))
716 << "One-at-a-Time hash has poor avalanche property";
717}
718
719// ==================== Known Value Tests ====================
720// Test against known hash values for regression testing
721
723{
724 // "abc" = 97 + 98 + 99 = 294
725 EXPECT_EQ(add_hash("abc"), 294u);
726}
727
729{
730 // "abc" = 97 ^ 98 ^ 99 = 96
731 EXPECT_EQ(xor_hash("abc"), 96u);
732}
733
735{
736 // Empty string with fnv_hash should return the FNV offset basis
737 // Since our implementation iterates while (*p), empty string returns
738 // initial value
739 EXPECT_EQ(fnv_hash(""), 2166136261u);
740}
741
742// ==================== Seeded Hash Tests ====================
743
745{
746 const std::string data = "test";
747 auto h1 = jen_hash(data, Default_Hash_Seed);
748 auto h2 = jen_hash((void*)data.c_str(), data.size(), Default_Hash_Seed);
749 EXPECT_EQ(h1, h2);
750}
751
753{
754 const std::string key = "test_key";
755
756 auto h1 = dft_hash_fct(key, 1ul);
757 auto h2 = dft_hash_fct(key, 2ul);
758
759 EXPECT_NE(h1, h2); // Different seeds should produce different hashes
760}
761
762// ==================== Type Safety Tests ====================
763
765{
766 int signed_val = -1;
767 unsigned int unsigned_val = static_cast<unsigned int>(-1);
768
769 // These should hash the same as they have the same bit representation
770 auto h1 = fnv_hash(&signed_val, sizeof(signed_val));
771 auto h2 = fnv_hash(&unsigned_val, sizeof(unsigned_val));
772 EXPECT_EQ(h1, h2);
773}
774
776{
777 // Test that const char* and std::string versions produce same hashes
778 // Note: char arr[] uses template version which includes null terminator,
779 // so we test const char* and std::string which both hash the string content
780 const char* ptr = "hello";
781 std::string str = "hello";
782
783 EXPECT_EQ(fnv_hash(ptr), fnv_hash(str));
784 EXPECT_EQ(oat_hash(ptr), oat_hash(str));
785 EXPECT_EQ(djb_hash(ptr), djb_hash(str));
786 EXPECT_EQ(sax_hash(ptr), sax_hash(str));
788}
789
790// ==================== Performance Sanity Checks ====================
791// These are not rigorous benchmarks but ensure hashes complete in
792// reasonable time
793
795{
796 // 10MB of data
797 std::string large_data(10 * 1024 * 1024, 'x');
798
799 // These should complete without hanging
800 auto h1 = fnv_hash(large_data);
801 auto h2 = oat_hash(large_data);
803 auto h4 = murmur3hash(large_data, 42ul);
804
805 EXPECT_NE(h1, 0u);
806 EXPECT_NE(h2, 0u);
807 EXPECT_NE(h3, 0u);
808 EXPECT_NE(h4, 0u);
809}
810
812{
813 // Hash 100,000 small integers
814 size_t sum = 0;
815 for (int i = 0; i < 100000; ++i)
816 sum += fnv_hash(i);
817
818 EXPECT_NE(sum, 0u);
819}
TEST_F(StaticArenaFixture, simple_fail)
Definition ah-arena.cc:59
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
static int bitDifference(size_t h1, size_t h2)
void SetUp() override
double measureHashUniqueness(const std::vector< size_t > &hashes)
std::vector< std::string > keys
void SetUp() override
std::string large_string
void SetUp() override
#define TEST(name)
Collection of general-purpose hash functions.
testing::Environment *const hash_env
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t sax_hash(const void *key, const size_t len) noexcept
Shift-Add-XOR hash.
Definition hash-fct.H:333
size_t add_hash(const void *key, const size_t len) noexcept
Additive hash.
Definition hash-fct.H:220
size_t pair_dft_hash_fct(const std::pair< K1, K2 > &p) noexcept
Definition hash-fct.H:955
size_t jsw_hash(const void *key, size_t len)
JSW hash (Julienne Walker)
Definition hash-fct.C:83
size_t murmur3hash(const Key &key, unsigned long seed)
Definition hash-fct.H:563
size_t djb_hash(const void *key, const size_t len) noexcept
Modified Bernstein hash.
Definition hash-fct.H:308
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
size_t SuperFastHash(const void *key, size_t len) noexcept
Paul Hsieh super fast hash function.
Definition hash-fct.H:638
size_t jen_hash(const void *key, const size_t length, const unsigned initval=Default_Hash_Seed) noexcept
Jenkins hash.
Definition hash-fct.H:488
size_t dft_hash_fct(const Key &key) noexcept
Definition hash-fct.H:931
size_t pair_snd_hash_fct(const std::pair< K1, K2 > &p) noexcept
Definition hash-fct.H:961
const unsigned Default_Hash_Seed
Hash functions (implementaciones concretas).
Definition hash-fct.C:43
size_t xor_hash(const void *key, const size_t len) noexcept
XOR hash.
Definition hash-fct.H:241
size_t fnv_hash(const void *key, const size_t len) noexcept
Fowler-Noll-Vo (FNV-1) hash function.
Definition hash-fct.H:371
void init_jsw() noexcept
Definition hash-fct.C:49
size_t rot_hash(const void *key, const size_t len) noexcept
Rotating hash.
Definition hash-fct.H:268
size_t elf_hash(const void *key, const size_t len) noexcept
ELF hash.
Definition hash-fct.H:439
size_t oat_hash(const void *key, const size_t len) noexcept
One-at-a-Time hash by Bob Jenkins.
Definition hash-fct.H:404
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.