Musa-Cpp-Lib-V2/lib/Base/Hash_Functions.h

80 lines
1.8 KiB
C++

#include "MString.h"
constexpr u32 HASH_INIT = 5381;
u32 sdbm_hash (void* data, s64 size) {
u32 h = HASH_INIT;
for (s64 i = 0; i < size; i += 1) {
h = (h << 16) + (h << 6) - h + ((u8*)data)[i];
}
return (u32)h;
}
u64 knuth_hash (u64 x) {
constexpr u64 KNUTH_GOLDEN_RATIO_64 = 11400714819323198485ULL;
return (KNUTH_GOLDEN_RATIO_64 * x);
}
u32 knuth_hash_u32 (u64 x) {
u32 h = HASH_INIT;
return (u32)((knuth_hash(x) ^ h) >> 32);
}
constexpr u64 FNV_64_PRIME = 0x100000001b3ULL;
constexpr u64 FNV_64_OFFSET_BIAS = 0xcbf29ce484222325ULL;
u64 fnv1a_hash (u64 x, u64 h = FNV_64_OFFSET_BIAS) {
h ^= x;
return h * FNV_64_PRIME;
}
// Good for hashing strings.
u64 fnv1a_hash_any (void* data, s64 size, u64 h = FNV_64_OFFSET_BIAS) {
for (s64 i = 0; i < size; i += 1) {
h = fnv1a_hash( ((u8*)data)[i], h);
}
return h;
}
u32 table_hash_function_fnv1a (void* key, s64 size) {
return (u32)fnv1a_hash_any(key, size);
}
u32 table_hash_function_knuth (void* key, s64 size) {
Assert(size == 8);
return knuth_hash_u32(*(u64*)key);
}
u32 string_hash_function_fnv1a (void* key, s64 size) {
Assert(size == sizeof(string));
string key_as_string = *((string*)key);
u64 hash_u64 = fnv1a_hash_any(key_as_string.data, key_as_string.count);
// It should be xor folded to the desired range rather than shifted:
return (u32)(hash_u64 ^ (hash_u64 >> 32));
}
bool u32_keys_match (void* key1, void* key2) {
u32 key1_u32 = *(u32*)key1;
u32 key2_u32 = *(u32*)key2;
return key1_u32 == key2_u32;
}
bool u64_keys_match (void* key1, void* key2) {
u64 key1_u64 = *(u64*)key1;
u64 key2_u64 = *(u64*)key2;
return key1_u64 == key2_u64;
}
bool string_keys_match (void* key1, void* key2) {
string key1_s = *((string*)key1);
string key2_s = *((string*)key2);
return strings_match(key1_s, key2_s);
}