libhmap-c

C hashmap library
git clone https://git.sinitax.com/sinitax/libhmap-c
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit a104a2e0a0287e7d75fa7408634485b8d0c24f1b
parent 16dda86b2ff36e5da8e836a4d106d0bfaf0e638d
Author: Louis Burda <quent.burda@gmail.com>
Date:   Mon, 20 Mar 2023 02:13:20 +0100

Expose link manipulation functions

Diffstat:
Minclude/hashmap.h | 15+++++++++++----
Mlibhashmap.api | 9++++++---
Mlibhashmap.lds | 9++++++---
Msrc/hashmap.c | 88+++++++++++++++++++++++++++++++++++++++++--------------------------------------
4 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/include/hashmap.h b/include/hashmap.h @@ -15,7 +15,7 @@ typedef bool (*hashmap_keycmp_func)(const void *key1, size_t size1, struct hashmap_link { void *key; - size_t key_size; + size_t keysize; void *value; struct hashmap_link *next; }; @@ -45,12 +45,19 @@ int hashmap_copy(struct hashmap *dst, const struct hashmap *src); void hashmap_swap(struct hashmap *m1, struct hashmap *m2); void hashmap_clear(struct hashmap *map); -struct hashmap_link *hashmap_get(struct hashmap *map, +struct hashmap_link **hashmap_link_get(struct hashmap *map, const void *key, size_t size); -struct hashmap_link *hashmap_pop(struct hashmap *map, +struct hashmap_link *hashmap_link_pop(struct hashmap *map, const void *key, size_t size); +void hashmap_link_set(struct hashmap *map, struct hashmap_link *link, + void *key, size_t keysize, void *value); +int hashmap_link_alloc(struct hashmap *map, struct hashmap_link **out, + void *key, size_t keysize, void *value); -int hashmap_set(struct hashmap *map, void *key, size_t key_size, void *value); +struct hashmap_link *hashmap_get(struct hashmap *map, + const void *key, size_t size); +void hashmap_rm(struct hashmap *map, const void *key, size_t size); +int hashmap_set(struct hashmap *map, void *key, size_t keysize, void *value); void hashmap_iter_init(struct hashmap_iter *iter); bool hashmap_iter_next(const struct hashmap *map, struct hashmap_iter *iter); diff --git a/libhashmap.api b/libhashmap.api @@ -7,10 +7,13 @@ hashmap_copy hashmap_swap hashmap_clear -hashmap_get -hashmap_pop - +hashmap_link_get +hashmap_link_pop hashmap_link_set +hashmap_link_alloc + +hashmap_get +hashmap_rm hashmap_set hashmap_iter_init diff --git a/libhashmap.lds b/libhashmap.lds @@ -8,10 +8,13 @@ LIBHASHMAP_1.3 { hashmap_swap; hashmap_clear; - hashmap_get; - hashmap_pop; - + hashmap_link_get; + hashmap_link_pop; hashmap_link_set; + hashmap_link_alloc; + + hashmap_get; + hashmap_rm; hashmap_set; hashmap_iter_init; diff --git a/src/hashmap.c b/src/hashmap.c @@ -9,22 +9,6 @@ hashmap_key_bucket(struct hashmap *map, const void *key, size_t size) return map->hash(key, size) % map->size; } -static struct hashmap_link ** -hashmap_get_linkp(struct hashmap *map, const void *key, size_t size) -{ - struct hashmap_link **iter, *link; - - iter = &map->buckets[hashmap_key_bucket(map, key, size)]; - while (*iter != NULL) { - link = *iter; - if (map->keycmp(link->key, link->key_size, key, size)) - return iter; - iter = &(*iter)->next; - } - - return NULL; -} - int hashmap_init(struct hashmap *map, size_t size, hashmap_hash_func hasher, hashmap_keycmp_func keycmp, const struct allocator *allocator) @@ -85,8 +69,8 @@ hashmap_copy(struct hashmap *dst, const struct hashmap *src) int rc; for (HASHMAP_ITER(src, &iter)) { - rc = hashmap_set(dst, NULL, iter.link->key, - iter.link->key_size, iter.link->value); + rc = hashmap_set(dst, iter.link->key, + iter.link->keysize, iter.link->value); if (rc) return rc; } @@ -121,22 +105,28 @@ hashmap_clear(struct hashmap *map) map->buckets[i] = NULL; } -struct hashmap_link * -hashmap_get(struct hashmap *map, const void *key, size_t size) +struct hashmap_link ** +hashmap_link_get(struct hashmap *map, const void *key, size_t size) { - struct hashmap_link **iter; + struct hashmap_link **iter, *link; - iter = hashmap_get_linkp(map, key, size); + iter = &map->buckets[hashmap_key_bucket(map, key, size)]; + while (*iter != NULL) { + link = *iter; + if (map->keycmp(link->key, link->keysize, key, size)) + return iter; + iter = &(*iter)->next; + } - return iter ? *iter : NULL; + return NULL; } struct hashmap_link * -hashmap_pop(struct hashmap *map, const void *key, size_t size) +hashmap_link_pop(struct hashmap *map, const void *key, size_t size) { struct hashmap_link **iter; - iter = hashmap_get_linkp(map, key, size); + iter = hashmap_link_get(map, key, size); if (iter) { *iter = (*iter)->next; return *iter; @@ -145,20 +135,18 @@ hashmap_pop(struct hashmap *map, const void *key, size_t size) return NULL; } -static int +void hashmap_link_set(struct hashmap *map, struct hashmap_link *link, - void *key, size_t key_size, void *value) + void *key, size_t keysize, void *value) { link->key = key; - link->key_size = key_size; + link->keysize = keysize; link->value = value; - - return 0; } -static int +int hashmap_link_alloc(struct hashmap *map, struct hashmap_link **out, - void *key, size_t key_size, void *value) + void *key, size_t keysize, void *value) { struct hashmap_link *link; int rc; @@ -166,7 +154,7 @@ hashmap_link_alloc(struct hashmap *map, struct hashmap_link **out, rc = map->allocator->alloc((void **)&link, sizeof(struct hashmap_link)); if (rc) return -rc; link->key = key; - link->key_size = key_size; + link->keysize = keysize; link->value = value; link->next = NULL; *out = link; @@ -174,29 +162,45 @@ hashmap_link_alloc(struct hashmap *map, struct hashmap_link **out, return 0; } +struct hashmap_link * +hashmap_get(struct hashmap *map, const void *key, size_t size) +{ + struct hashmap_link **iter; + + iter = hashmap_link_get(map, key, size); + + return iter ? *iter : NULL; +} + +void +hashmap_rm(struct hashmap *map, const void *key, size_t size) +{ + struct hashmap_link *link; + + link = hashmap_link_pop(map, key, size); + if (!link) return; + map->allocator->free(link); +} + int -hashmap_set(struct hashmap *map, struct hashmap_link **link, - void *key, size_t key_size, void *value) +hashmap_set(struct hashmap *map, void *key, size_t keysize, void *value) { struct hashmap_link **iter; int rc; - iter = hashmap_get_linkp(map, key, key_size); + iter = hashmap_link_get(map, key, keysize); if (iter == NULL) { - iter = &map->buckets[hashmap_key_bucket(map, key, key_size)]; + iter = &map->buckets[hashmap_key_bucket(map, key, keysize)]; while (*iter) iter = &((*iter)->next); } if (*iter) { - rc = hashmap_link_set(map, *iter, key, key_size, value); - if (rc) return rc; + hashmap_link_set(map, *iter, key, keysize, value); } else { - rc = hashmap_link_alloc(map, iter, key, key_size, value); + rc = hashmap_link_alloc(map, iter, key, keysize, value); if (rc) return rc; } - if (link) *link = *iter; - return 0; }