Skip to content

Commit e9a9415

Browse files
committed
Better implementation of hashing on 32/64 bit platforms.
Because function overloading didn't work the way I had hoped.
1 parent d92188a commit e9a9415

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

CesiumUtility/src/Hash.cpp

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <CesiumUtility/Hash.h>
22

3+
#include <climits>
34
#include <cstddef>
45
#include <cstdint>
56

@@ -60,43 +61,50 @@ namespace CesiumUtility {
6061
// (https://mostlymangling.blogspot.com/2019/12/stronger-better-morer-moremur-better.html)
6162
namespace {
6263

63-
inline uint64_t mix(uint64_t x) {
64-
uint64_t const m = 0xe9846af9b1a615d;
64+
template <size_t Bits> struct hash_mix_impl;
6565

66-
x ^= x >> 32;
67-
x *= m;
68-
x ^= x >> 32;
69-
x *= m;
70-
x ^= x >> 28;
66+
template <> struct hash_mix_impl<64> {
67+
inline static uint64_t fn(uint64_t x) {
68+
uint64_t const m = 0xe9846af9b1a615d;
7169

72-
return x;
73-
}
70+
x ^= x >> 32;
71+
x *= m;
72+
x ^= x >> 32;
73+
x *= m;
74+
x ^= x >> 28;
75+
76+
return x;
77+
}
78+
};
7479

7580
// This function is adapted from Boost v1.86.0, `hash_mix_impl<32>` function.
7681
//
7782
// hash_mix for 32 bit size_t
7883
//
7984
// We use the "best xmxmx" implementation from
8085
// https://github.com/skeeto/hash-prospector/issues/19
81-
inline uint32_t mix(uint32_t x) {
82-
uint32_t const m1 = 0x21f0aaad;
83-
uint32_t const m2 = 0x735a2d97;
86+
template <> struct hash_mix_impl<32> {
87+
inline static uint32_t fn(uint32_t x) {
88+
uint32_t const m1 = 0x21f0aaad;
89+
uint32_t const m2 = 0x735a2d97;
8490

85-
x ^= x >> 16;
86-
x *= m1;
87-
x ^= x >> 15;
88-
x *= m2;
89-
x ^= x >> 15;
91+
x ^= x >> 16;
92+
x *= m1;
93+
x ^= x >> 15;
94+
x *= m2;
95+
x ^= x >> 15;
9096

91-
return x;
92-
}
97+
return x;
98+
}
99+
};
93100

94101
} // namespace
95102

96103
// This function is adapted from Boost's `hash_combine`.
97104
size_t Hash::combine(size_t first, size_t second) {
98105
// This will truncate bits on 32-bit builds.
99-
return mix(first + 0x9e3779b9 + second);
106+
return hash_mix_impl<sizeof(size_t) * CHAR_BIT>::fn(
107+
first + size_t(0x9e3779b9) + second);
100108
}
101109

102110
} // namespace CesiumUtility

0 commit comments

Comments
 (0)