Use an integer hash function to derive the index from the key. This should reduce the number of collisions.
* libihash/ihash.c (hash_int32): New function. (find_index): Use hash_int32 on the key to derive the index. (add_one): Likewise. --- libihash/ihash.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libihash/ihash.c b/libihash/ihash.c index d670fee..1de4c35 100644 --- a/libihash/ihash.c +++ b/libihash/ihash.c @@ -81,6 +81,25 @@ static const unsigned int ihash_nsizes = (sizeof ihash_sizes / sizeof ihash_sizes[0]); +/* Integer hashing follows Thomas Wang's paper about his 32/64-bits + mix functions : + - http://www.concentric.net/~Ttwang/tech/inthash.htm */ +static inline uint32_t +hash_int32(uint32_t n, unsigned int bits) +{ + uint32_t hash; + + hash = n; + hash = ~hash + (hash << 15); + hash ^= (hash >> 12); + hash += (hash << 2); + hash ^= (hash >> 4); + hash += (hash << 3) + (hash << 11); + hash ^= (hash >> 16); + + return hash >> (32 - bits); +} + /* Return 1 if the slot with the index IDX in the hash table HT is empty, and 0 otherwise. */ static inline int @@ -111,7 +130,7 @@ find_index (hurd_ihash_t ht, hurd_ihash_key_t key) unsigned int up_idx; unsigned int down_idx; - idx = key % ht->size; + idx = hash_int32 (key, 32) % ht->size; if (ht->items[idx].value == _HURD_IHASH_EMPTY || ht->items[idx].key == key) return idx; @@ -264,7 +283,7 @@ add_one (hurd_ihash_t ht, hurd_ihash_key_t key, hurd_ihash_value_t value) unsigned int idx; unsigned int first_free; - idx = key % ht->size; + idx = hash_int32 (key, 32) % ht->size; first_free = idx; if (ht->items[idx].value != _HURD_IHASH_EMPTY && ht->items[idx].key != key) -- 2.0.0.rc0