X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fhashmap.c;h=4ea1a0f4cb9d010dcbda92b3aa09c65de4af74ea;hb=69ab80881552d5f79ca95f6b3be48ad122ab1ec2;hp=ef78070f4c0854cd767e7a2803317fccb51b7691;hpb=d99ae53a7327e1520ea4b9a3408c2d7f938c4b37;p=elogind.git diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c index ef78070f4..4ea1a0f4c 100644 --- a/src/shared/hashmap.c +++ b/src/shared/hashmap.c @@ -103,7 +103,7 @@ static void deallocate_tile(void **first_tile, void *p) { *first_tile = p; } -#ifndef __OPTIMIZE__ +#ifdef VALGRIND static void drop_pool(struct pool *p) { while (p) { @@ -147,6 +147,25 @@ int trivial_compare_func(const void *a, const void *b) { return a < b ? -1 : (a > b ? 1 : 0); } +unsigned uint64_hash_func(const void *p) { + uint64_t u; + + assert_cc(sizeof(uint64_t) == 2*sizeof(unsigned)); + + u = *(const uint64_t*) p; + + return (unsigned) ((u >> 32) ^ u); +} + +int uint64_compare_func(const void *_a, const void *_b) { + uint64_t a, b; + + a = *(const uint64_t*) _a; + b = *(const uint64_t*) _b; + + return a < b ? -1 : (a > b ? 1 : 0); +} + Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { bool b; Hashmap *h; @@ -290,6 +309,17 @@ void hashmap_free_free(Hashmap *h) { hashmap_free(h); } +void hashmap_free_free_free(Hashmap *h) { + + /* Free the hashmap and all data and key objects in it */ + + if (!h) + return; + + hashmap_clear_free_free(h); + hashmap_free(h); +} + void hashmap_clear(Hashmap *h) { if (!h) return; @@ -308,6 +338,22 @@ void hashmap_clear_free(Hashmap *h) { free(p); } +void hashmap_clear_free_free(Hashmap *h) { + if (!h) + return; + + while (h->iterate_list_head) { + void *a, *b; + + a = h->iterate_list_head->value; + b = (void*) h->iterate_list_head->key; + remove_entry(h, h->iterate_list_head); + free(a); + free(b); + } +} + + static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) { struct hashmap_entry *e; assert(h); @@ -327,13 +373,10 @@ int hashmap_put(Hashmap *h, const void *key, void *value) { assert(h); hash = h->hash_func(key) % NBUCKETS; - e = hash_scan(h, hash, key); if (e) { - if (e->value == value) return 0; - return -EEXIST; } @@ -488,7 +531,6 @@ int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_ return -ENOENT; new_hash = h->hash_func(new_key) % NBUCKETS; - if ((k = hash_scan(h, new_hash, new_key))) if (e != k) remove_entry(h, k);