Improved hash function.

This commit is contained in:
LoRd_MuldeR 2022-11-20 16:48:14 +01:00
parent 9ff55cef2f
commit b8a6287e14
2 changed files with 23 additions and 19 deletions

View File

@ -39,15 +39,9 @@ int main()
const errno_t error = hash_set_insert(hash_set, next_rand() & 0x3FFFFFFFFFFFFFFllu);
if (error)
{
char message[128U];
if (strerror_s(message, 128U, error))
{
message[0U] = '\0';
}
printf("Insert has failed! (error: %d) [%s]\n", error, message);
printf("Insert operation has failed! (error: %d)\n", error);
break;
}
if (!(++spinner & 0x7F))
{
const clock_t now = clock();

View File

@ -15,8 +15,10 @@ typedef int bool_t;
#if defined(__GNUC__)
# define INLINE __inline__
# define FORCE_INLINE __attribute__((always_inline)) __inline__
#elif defined(_MSC_VER)
# define INLINE __inline
# define FORCE_INLINE __forceinline
#else
# define INLINE
#endif
@ -46,28 +48,35 @@ struct _hash_set
/* PRIVATE FUNCTIONS */
/* ========================================================================= */
static INLINE size_t hash(const uint64_t value, const size_t capacity)
static FORCE_INLINE void hash_u64(uint64_t *const h, uint64_t value)
{
return (size_t) (((UINT64_C(14695981039346656037) + value) * UINT64_C(1099511628211)) % capacity);
do
{
*h ^= value & 0xFF;
*h *= UINT64_C(1099511628211);
}
while (value >>= CHAR_BIT);
}
static INLINE size_t safe_mult2(const size_t value)
static INLINE size_t hash(const uint64_t value, const uint64_t tweak, const size_t capacity)
{
uint64_t h = UINT64_C(14695981039346656037);
hash_u64(&h, tweak);
hash_u64(&h, value);
return (size_t)(h % ((uint64_t)capacity));
}
static FORCE_INLINE size_t safe_mult2(const size_t value)
{
return (value < (SIZE_MAX >> 1)) ? (value << 1) : SIZE_MAX;
}
static INLINE size_t round_sz(double d)
static FORCE_INLINE size_t round_sz(double d)
{
return (d >= 0.0) ? ((size_t)(d + 0.5)) : ((size_t)(d - ((double)((size_t)(d - 1))) + 0.5)) + ((size_t)(d - 1));
}
static INLINE size_t increment(const size_t value, const size_t bound)
{
const size_t result = value + 1U;
return (result >= bound) ? 0U : result;
}
static INLINE size_t next_pow2(const size_t minimum)
static FORCE_INLINE size_t next_pow2(const size_t minimum)
{
size_t result = 2U;
@ -138,8 +147,9 @@ static INLINE bool_t find_slot(const struct _hash_set_data *const data, const ui
{
size_t index;
bool_t index_saved = FALSE;
uint64_t tweak = 0U;
for (index = hash(value, data->capacity); get_flag(data->used, index); index = increment(index, data->capacity))
for (index = hash(value, tweak, data->capacity); get_flag(data->used, index); index = hash(value, ++tweak, data->capacity))
{
if (!get_flag(data->deleted, index))
{