summaryrefslogtreecommitdiffhomepage
path: root/compat/int-hash.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-10-11 10:33:21 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-10-11 11:28:59 +0200
commitca4b2e8796e8f0031c71b002e6416b89c17f1e56 (patch)
tree7c89fb35eae906e1046a6d3a9c5ecfeb135a925c /compat/int-hash.cpp
parent67a2d708dc4b29da8ae0bf039e25081e87c8d55a (diff)
compat: mess around with fnv hash
Diffstat (limited to 'compat/int-hash.cpp')
-rw-r--r--compat/int-hash.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/compat/int-hash.cpp b/compat/int-hash.cpp
index 5c009b4e..79b5dfad 100644
--- a/compat/int-hash.cpp
+++ b/compat/int-hash.cpp
@@ -35,15 +35,34 @@ fm_UNROLL_8
} // namespace
+#define fnvhash_64_ROUND() do { hash *= 0x01000193u; hash ^= (uint8_t)*str++; } while(false)
+
uint64_t fnvhash_64(const void* str_, size_t size)
{
- const auto *str = (const char*)str_, *end = str + size;
+ const auto *str = (const char*)str_;
uint32_t hash = 0x811c9dc5u;
-fm_UNROLL_4
- for (; str != end; ++str)
+ size_t full = size / 8;
+ for (size_t i = 0; i < full; i++)
{
- hash *= 0x01000193u;
- hash ^= (uint8_t)*str;
+ fnvhash_64_ROUND();
+ fnvhash_64_ROUND();
+ fnvhash_64_ROUND();
+ fnvhash_64_ROUND();
+ fnvhash_64_ROUND();
+ fnvhash_64_ROUND();
+ fnvhash_64_ROUND();
+ fnvhash_64_ROUND();
+ }
+ switch (size & 7u)
+ {
+ case 7: fnvhash_64_ROUND(); [[fallthrough]];
+ case 6: fnvhash_64_ROUND(); [[fallthrough]];
+ case 5: fnvhash_64_ROUND(); [[fallthrough]];
+ case 4: fnvhash_64_ROUND(); [[fallthrough]];
+ case 3: fnvhash_64_ROUND(); [[fallthrough]];
+ case 2: fnvhash_64_ROUND(); [[fallthrough]];
+ case 1: fnvhash_64_ROUND(); [[fallthrough]];
+ case 0: break;
}
return hash;
}