taisei/src/hashtable.h

82 lines
1.9 KiB
C

/*
* This software is licensed under the terms of the MIT License.
* See COPYING for further information.
* ---
* Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
*/
#pragma once
#include "taisei.h"
/*
* hash_t
*
* Type of the hash values.
*/
typedef uint32_t hash_t;
#define HT_HASH_LIVE_BIT ((hash_t)(1) << (sizeof(hash_t) * CHAR_BIT - 1))
typedef hash_t ht_size_t;
// for hashsets
struct ht_empty { };
#define HT_EMPTY ((struct ht_empty) {})
/*
* htutil_hashfunc_uint32
*
* Hash function for 32-bit integers
* NOTE: assuming hash_t stays uint32_t, this function has no collisions.
*/
INLINE hash_t htutil_hashfunc_uint32(uint32_t x) {
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return (hash_t)x;
}
/*
* htutil_hashfunc_uint64
*
* Hash function for 64-bit integers.
*/
INLINE hash_t htutil_hashfunc_uint64(uint64_t x) {
x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
x = x ^ (x >> 31);
return (hash_t)x;
}
/*
* htutil_hashfunc_string
*
* Hash function for null-terminated strings.
*/
INLINE uint32_t htutil_hashfunc_string(const char *str) {
// FNV1a hash
//
// Not looking for '\0' in the for loop because apparently compilers optimize this better.
// Both GCC and clang can fold this entire function into a constant with a constant str.
// GCC fails that if strlen is not used.
uint32_t hash = 0x811c9dc5;
uint32_t prime = 0x1000193;
size_t len = strlen(str);
for(int i = 0; i < len; ++i) {
uint8_t value = str[i];
hash = hash ^ value;
hash *= prime;
}
return hash;
}
// Import public declarations for the predefined hashtable types.
#define HT_DECL
#include "hashtable_predefs.inc.h"
// NOTE: For the hashtable API, see hashtable.inc.h
// NOTE: For type-generic wrappers around the API, see hashtable_predefs.inc.h