diff options
-rw-r--r-- | src/libudev/hashmap.c | 29 | ||||
-rw-r--r-- | src/libudev/hashmap.h | 37 |
2 files changed, 50 insertions, 16 deletions
diff --git a/src/libudev/hashmap.c b/src/libudev/hashmap.c index dcfbb67228..9f7db34397 100644 --- a/src/libudev/hashmap.c +++ b/src/libudev/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) { @@ -309,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; @@ -327,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); diff --git a/src/libudev/hashmap.h b/src/libudev/hashmap.h index 6fd71cf519..15b7e27585 100644 --- a/src/libudev/hashmap.h +++ b/src/libudev/hashmap.h @@ -23,6 +23,8 @@ #include <stdbool.h> +#include "macro.h" + /* Pretty straightforward hash table implementation. As a minor * optimization a NULL hashmap object will be treated as empty hashmap * for all read operations. That way it is not necessary to @@ -38,29 +40,33 @@ typedef _IteratorStruct* Iterator; typedef unsigned (*hash_func_t)(const void *p); typedef int (*compare_func_t)(const void *a, const void *b); -unsigned string_hash_func(const void *p); -int string_compare_func(const void *a, const void *b); +unsigned string_hash_func(const void *p) _pure_; +int string_compare_func(const void *a, const void *b) _pure_; -unsigned trivial_hash_func(const void *p); -int trivial_compare_func(const void *a, const void *b); +/* This will compare the passed pointers directly, and will not + * dereference them. This is hence not useful for strings or + * suchlike. */ +unsigned trivial_hash_func(const void *p) _const_; +int trivial_compare_func(const void *a, const void *b) _const_; -unsigned uint64_hash_func(const void *p); -int uint64_compare_func(const void *a, const void *b); +unsigned uint64_hash_func(const void *p) _pure_; +int uint64_compare_func(const void *a, const void *b) _pure_; Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func); void hashmap_free(Hashmap *h); void hashmap_free_free(Hashmap *h); +void hashmap_free_free_free(Hashmap *h); Hashmap *hashmap_copy(Hashmap *h); int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func); int hashmap_put(Hashmap *h, const void *key, void *value); int hashmap_update(Hashmap *h, const void *key, void *value); int hashmap_replace(Hashmap *h, const void *key, void *value); -void* hashmap_get(Hashmap *h, const void *key); -void* hashmap_get2(Hashmap *h, const void *key, void **rkey); +void *hashmap_get(Hashmap *h, const void *key); +void *hashmap_get2(Hashmap *h, const void *key, void **rkey); bool hashmap_contains(Hashmap *h, const void *key); -void* hashmap_remove(Hashmap *h, const void *key); -void* hashmap_remove_value(Hashmap *h, const void *key, void *value); +void *hashmap_remove(Hashmap *h, const void *key); +void *hashmap_remove_value(Hashmap *h, const void *key, void *value); int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value); int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value); @@ -68,8 +74,8 @@ int hashmap_merge(Hashmap *h, Hashmap *other); void hashmap_move(Hashmap *h, Hashmap *other); int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key); -unsigned hashmap_size(Hashmap *h); -bool hashmap_isempty(Hashmap *h); +unsigned hashmap_size(Hashmap *h) _pure_; +bool hashmap_isempty(Hashmap *h) _pure_; void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key); void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key); @@ -77,12 +83,13 @@ void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i); void hashmap_clear(Hashmap *h); void hashmap_clear_free(Hashmap *h); +void hashmap_clear_free_free(Hashmap *h); void *hashmap_steal_first(Hashmap *h); void *hashmap_steal_first_key(Hashmap *h); -void* hashmap_first(Hashmap *h); -void* hashmap_first_key(Hashmap *h); -void* hashmap_last(Hashmap *h); +void *hashmap_first(Hashmap *h) _pure_; +void *hashmap_first_key(Hashmap *h) _pure_; +void *hashmap_last(Hashmap *h) _pure_; void *hashmap_next(Hashmap *h, const void *key); |