diff options
author | Danny van Kooten <dannyvankooten@users.noreply.github.com> | 2020-03-18 20:57:49 +0100 |
---|---|---|
committer | Danny van Kooten <dannyvankooten@users.noreply.github.com> | 2020-03-18 20:57:49 +0100 |
commit | 303f93d34cfd8cc545b5c38c3a4712bc30e5177f (patch) | |
tree | 7ef08f752a8c01bb7b52a1642ce3df82c0c8c0b2 /src | |
parent | 8d74fd5b0e5fc9f319a5b7d2e0716afcc312fd75 (diff) | |
download | unja-303f93d34cfd8cc545b5c38c3a4712bc30e5177f.tar.gz unja-303f93d34cfd8cc545b5c38c3a4712bc30e5177f.zip |
change hash function to support filenames starting with a digit
Diffstat (limited to 'src')
-rw-r--r-- | src/hashmap.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/src/hashmap.c b/src/hashmap.c index 600a005..16a950f 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -3,14 +3,25 @@ #include <err.h> #include "hashmap.h" -#define HASH(v) (v[0] - 'a') % HASHMAP_CAP - struct node { char *key; void *value; struct node *next; }; +unsigned long +hash(char *str) +{ + unsigned long hash = 5381; + int c; + + while ((c = *str++)) { + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + } + + return hash; +} + /* allocate a new hashmap */ struct hashmap *hashmap_new() { struct hashmap *hm = malloc(sizeof *hm); @@ -24,7 +35,7 @@ struct hashmap *hashmap_new() { /* Inserts a key-value pair into the map. Returns NULL if map did not have key, old value if it did. */ void *hashmap_insert(struct hashmap *hm, char *key, void *value) { - int pos = HASH(key); + int pos = hash(key) % HASHMAP_CAP; struct node *head = hm->buckets[pos]; struct node *node = head; void *old_value; @@ -48,10 +59,10 @@ void *hashmap_insert(struct hashmap *hm, char *key, void *value) { /* Returns a pointer to the value corresponding to the key. */ void *hashmap_get(struct hashmap *hm, char *key) { - int pos = HASH(key); + unsigned int pos = hash(key) % HASHMAP_CAP; struct node *node = hm->buckets[pos]; - while (node) { - if (node->key && strcmp(node->key, key) == 0) { + while (node != NULL) { + if (strcmp(node->key, key) == 0) { return node->value; } @@ -88,7 +99,7 @@ void *hashmap_resolve(struct hashmap *hm, char *key) { /* Removes a key from the map, returning the value at the key if the key was previously in the map. */ void *hashmap_remove(struct hashmap *hm, char *key) { - int pos = HASH(key); + int pos = hash(key) % HASHMAP_CAP; struct node *node = hm->buckets[pos]; struct node *prev = NULL; void *old_value; |