summaryrefslogtreecommitdiffhomepage
path: root/src/hashmap.c
diff options
context:
space:
mode:
authorPeter H. Froehlich <peter.hans.froehlich@gmail.com>2014-11-02 22:27:45 -0500
committerMichael Adam <obnox@samba.org>2014-12-13 01:20:56 +0100
commitab6255393d7a983ae3d008f13c1350cf56d32c33 (patch)
treebdf2848b252805f383813e8dfceeb4dd1c4bed61 /src/hashmap.c
parent24087f743ae321e76430c171a69e86e8a9726382 (diff)
BB#110 Replace hash function with Dan Bernstein's.
This hash function distributes much better than the original one. The effect is not as visible with hashes taken modulo 32 than with a bigger modulus, but it is there. And larger number of buckets migh become possible in the future... Reviewed-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'src/hashmap.c')
-rw-r--r--src/hashmap.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/src/hashmap.c b/src/hashmap.c
index f46fdcb..0c911a8 100644
--- a/src/hashmap.c
+++ b/src/hashmap.c
@@ -63,6 +63,9 @@ struct hashmap_s {
* The contents of the key are converted to lowercase, so this function
* is not case-sensitive.
*
+ * This is Dan Bernstein's hash function as described, for example, here:
+ * http://www.cse.yorku.ca/~oz/hash.html
+ *
* If any of the arguments are invalid a negative number is returned.
*/
static int hashfunc (const char *key, unsigned int size)
@@ -74,12 +77,8 @@ static int hashfunc (const char *key, unsigned int size)
if (size == 0)
return -ERANGE;
- for (hash = tolower (*key++); *key != '\0'; key++) {
- uint32_t bit = (hash & 1) ? (1 << (sizeof (uint32_t) - 1)) : 0;
-
- hash >>= 1;
-
- hash += tolower (*key) + bit;
+ for (hash = 5381; *key != '\0'; key++) {
+ hash = ((hash << 5) + hash) ^ tolower (*key);
}
/* Keep the hash within the table limits */