summaryrefslogtreecommitdiffhomepage
path: root/compat
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-18 23:22:41 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-18 23:22:41 +0100
commit3264ef85e50add2db3c54291540bde7e8411cb70 (patch)
tree9c26f478c73dfcd83e5a49f4a8fb188d3b86be62 /compat
parent848f3a16b95be89a1d639ae9ee4ea64e77625e39 (diff)
c
Diffstat (limited to 'compat')
-rw-r--r--compat/defs.hpp2
-rw-r--r--compat/int-hash.cpp42
-rw-r--r--compat/int-hash.hpp12
3 files changed, 47 insertions, 9 deletions
diff --git a/compat/defs.hpp b/compat/defs.hpp
index d14832d0..fe72dda6 100644
--- a/compat/defs.hpp
+++ b/compat/defs.hpp
@@ -74,7 +74,7 @@
#define fm_UNROLL_2 _Pragma("GCC unroll 2")
#define fm_UNROLL_4 _Pragma("GCC unroll 4")
#define fm_UNROLL_8 _Pragma("GCC unroll 8")
-#if __SIZEOF_POINTER__ >= 8
+#if __SIZEOF_POINTER__ > 4
#define fm_UNROLL _Pragma("GCC unroll 8")
#else
#define fm_UNROLL _Pragma("GCC unroll 4")
diff --git a/compat/int-hash.cpp b/compat/int-hash.cpp
index c6ca7d3d..3c85a436 100644
--- a/compat/int-hash.cpp
+++ b/compat/int-hash.cpp
@@ -6,11 +6,9 @@ namespace floormat {
namespace {
-template<size_t N> struct fnvhash_params;
-
-template<> struct fnvhash_params<32> { uint32_t a = 0x811c9dc5u, b = 0x01000193u; };
-template<> struct fnvhash_params<64> { uint64_t a = 0xcbf29ce484222325u, b = 0x100000001b3u; };
+using namespace floormat::Hash;
+// todo implement in terms of fnvhash_buf()
[[maybe_unused]]
CORRADE_ALWAYS_INLINE size_t fnvhash_uint_32(uint32_t x)
{
@@ -91,3 +89,39 @@ size_t hash_int(uint64_t x) noexcept
}
} // namespace floormat
+
+namespace floormat::Hash {
+
+size_t fnvhash_buf(const void* __restrict buf, size_t size, size_t seed) noexcept
+{
+ constexpr size_t b{fnvhash_params<sizeof nullptr*8>::b};
+ size_t full_rounds = size / 8, rest = size % 8;
+ size_t hash = seed;
+ const char* str = (const char*)buf;
+
+ while (full_rounds--)
+ {
+ hash *= b; hash ^= (uint8_t)*str++; // 0
+ hash *= b; hash ^= (uint8_t)*str++; // 1
+ hash *= b; hash ^= (uint8_t)*str++; // 2
+ hash *= b; hash ^= (uint8_t)*str++; // 3
+ hash *= b; hash ^= (uint8_t)*str++; // 4
+ hash *= b; hash ^= (uint8_t)*str++; // 5
+ hash *= b; hash ^= (uint8_t)*str++; // 6
+ hash *= b; hash ^= (uint8_t)*str++; // 7
+ }
+ switch (rest)
+ {
+ case 7: hash *= b; hash ^= (uint8_t)*str++; [[fallthrough]];
+ case 6: hash *= b; hash ^= (uint8_t)*str++; [[fallthrough]];
+ case 5: hash *= b; hash ^= (uint8_t)*str++; [[fallthrough]];
+ case 4: hash *= b; hash ^= (uint8_t)*str++; [[fallthrough]];
+ case 3: hash *= b; hash ^= (uint8_t)*str++; [[fallthrough]];
+ case 2: hash *= b; hash ^= (uint8_t)*str++; [[fallthrough]];
+ case 1: hash *= b; hash ^= (uint8_t)*str++; [[fallthrough]];
+ case 0: break;
+ }
+ return hash;
+}
+
+} // namespace floormat::Hash
diff --git a/compat/int-hash.hpp b/compat/int-hash.hpp
index b3dd7616..752c3597 100644
--- a/compat/int-hash.hpp
+++ b/compat/int-hash.hpp
@@ -1,12 +1,16 @@
#pragma once
-namespace floormat::impl_hash {
+namespace floormat::Hash {
-template<size_t N> size_t hash_buf(const void* buf, size_t size) noexcept = delete;
+template<size_t N = sizeof nullptr * 4> struct fnvhash_params;
+template<> struct fnvhash_params<32> { static constexpr uint32_t a = 0x811c9dc5u, b = 0x01000193u; };
+template<> struct fnvhash_params<64> { static constexpr uint64_t a = 0xcbf29ce484222325u, b = 0x100000001b3u; };
-} // namespace floormat::impl_hash
+size_t fnvhash_buf(const void* __restrict buf, size_t size, size_t seed = fnvhash_params<>::a) noexcept;
-namespace floormat {
+} // namespace floormat::Hash
+
+namespace floormat { // todo
uint64_t hash_64(const void* buf, size_t size) noexcept;
uint32_t hash_32(const void* buf, size_t size) noexcept;