80 lines
1.8 KiB
C++
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);
|
|
} |