Small tweak to hash function.
This commit is contained in:
parent
4c4b9a5a31
commit
9cd9ef3600
@ -37,7 +37,7 @@ int main()
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t r = 0; r < 5; ++r)
|
for (size_t r = 0U; r < 5U; ++r)
|
||||||
{
|
{
|
||||||
for (uint64_t i = 0; i < MAXIMUM; ++i)
|
for (uint64_t i = 0; i < MAXIMUM; ++i)
|
||||||
{
|
{
|
||||||
@ -161,12 +161,13 @@ int main()
|
|||||||
if (error != EEXIST)
|
if (error != EEXIST)
|
||||||
{
|
{
|
||||||
printf("Insert operation has failed! (error: %d)\n", error);
|
printf("Insert operation has failed! (error: %d)\n", error);
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Collision detected! [%016llX]\n", rnd);
|
printf("Collision detected! [%016llX]\n", rnd);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (!(++spinner & 0x7F))
|
if (!(++spinner & 0x7F))
|
||||||
{
|
{
|
||||||
|
@ -101,22 +101,20 @@ static FORCE_INLINE size_t next_pow2(const size_t target)
|
|||||||
/* Hash function */
|
/* Hash function */
|
||||||
/* ------------------------------------------------- */
|
/* ------------------------------------------------- */
|
||||||
|
|
||||||
static FORCE_INLINE void hash_u64(uint64_t *const h, uint64_t value)
|
#define HASH_OFFSET UINT64_C(14695981039346656037)
|
||||||
|
|
||||||
|
#define INDEX(X,Y) ((size_t)((X) % (Y)))
|
||||||
|
|
||||||
|
static FORCE_INLINE uint64_t hash_compute(uint64_t hash, uint64_t value)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*h ^= value & 0xFF;
|
hash ^= value & 0xFF;
|
||||||
*h *= UINT64_C(1099511628211);
|
hash *= UINT64_C(1099511628211);
|
||||||
}
|
}
|
||||||
while (value >>= CHAR_BIT);
|
while (value >>= CHAR_BIT);
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE size_t hash(const uint64_t value, const uint64_t tweak, const size_t capacity)
|
return hash;
|
||||||
{
|
|
||||||
uint64_t h = UINT64_C(14695981039346656037);
|
|
||||||
hash_u64(&h, tweak);
|
|
||||||
hash_u64(&h, value);
|
|
||||||
return (size_t)(h % ((uint64_t)capacity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------- */
|
/* ------------------------------------------------- */
|
||||||
@ -192,7 +190,9 @@ static INLINE bool_t find_slot(const struct _hash_set_data *const data, const ui
|
|||||||
bool_t index_saved = FALSE;
|
bool_t index_saved = FALSE;
|
||||||
uint64_t tweak = 0U;
|
uint64_t tweak = 0U;
|
||||||
|
|
||||||
for (index = hash(value, tweak, data->capacity); get_flag(data->used, index); index = hash(value, ++tweak, data->capacity))
|
const uint64_t hash = hash_compute(HASH_OFFSET, value);
|
||||||
|
|
||||||
|
for (index = INDEX(hash, data->capacity); get_flag(data->used, index); index = INDEX(hash_compute(hash, tweak++), data->capacity))
|
||||||
{
|
{
|
||||||
if (!get_flag(data->deleted, index))
|
if (!get_flag(data->deleted, index))
|
||||||
{
|
{
|
||||||
@ -295,7 +295,7 @@ hash_set_t *hash_set_create(const size_t initial_capacity, const double load_fac
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance->load_factor = (load_factor > 0.0) ? BOUND(0.1, load_factor, 1.0) : 0.75;
|
instance->load_factor = (load_factor > 0.0) ? BOUND(0.125, load_factor, 1.0) : 0.8;
|
||||||
instance->options = options;
|
instance->options = options;
|
||||||
instance->limit = round_sz(instance->data.capacity * instance->load_factor);
|
instance->limit = round_sz(instance->data.capacity * instance->load_factor);
|
||||||
|
|
||||||
@ -431,7 +431,7 @@ errno_t hash_set_shrink(hash_set_t *const instance)
|
|||||||
if (instance->data.capacity > MINIMUM_CAPACITY)
|
if (instance->data.capacity > MINIMUM_CAPACITY)
|
||||||
{
|
{
|
||||||
const size_t target_capacity = next_pow2(round_sz(safe_add(instance->valid, MINIMUM_CAPACITY) / instance->load_factor));
|
const size_t target_capacity = next_pow2(round_sz(safe_add(instance->valid, MINIMUM_CAPACITY) / instance->load_factor));
|
||||||
if (instance->data.capacity > target_capacity)
|
if ((instance->data.capacity > target_capacity) || (instance->deleted > 0U))
|
||||||
{
|
{
|
||||||
return rebuild_set(instance, target_capacity);
|
return rebuild_set(instance, target_capacity);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user