libhmap-c

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

commit a19022e72147a169610d70cd6d1c5a4a94988983
parent aacdb178718fe4a5fc7562ddb4017e0e405d85cf
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sat, 13 May 2023 22:17:08 +0200

Update liballoc

Diffstat:
M.gitmodules | 2+-
Minclude/hmap.h | 12++++++------
Msrc/hmap.c | 74+++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc/test.c | 4++--
4 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/.gitmodules b/.gitmodules @@ -1,3 +1,3 @@ [submodule "lib/liballoc"] path = lib/liballoc - url = git@sinitax.com:snx/liballoc + url = git@sinitax.com:sinitax/liballoc diff --git a/include/hmap.h b/include/hmap.h @@ -88,11 +88,11 @@ struct hmap { int hmap_init(struct hmap *map, size_t buckets, hmap_hash_func hasher, hmap_keycmp_func keycmp, const struct allocator *allocator); -void hmap_deinit(struct hmap *map); +int hmap_deinit(struct hmap *map); -int hmap_alloc(struct hmap **map, size_t buckets, hmap_hash_func hasher, - hmap_keycmp_func keycmp, const struct allocator *allocator); -void hmap_free(struct hmap *map); +struct hmap *hmap_alloc(size_t buckets, hmap_hash_func hasher, + hmap_keycmp_func keycmp, const struct allocator *allocator, int *rc); +int hmap_free(struct hmap *map); int hmap_copy(const struct hmap *dst, const struct hmap *src); void hmap_swap(struct hmap *m1, struct hmap *m2); @@ -101,8 +101,8 @@ void hmap_clear(const struct hmap *map); struct hmap_link **hmap_link_get(const struct hmap *map, struct hmap_key key); struct hmap_link **hmap_link_pos(const struct hmap *map, struct hmap_key key); struct hmap_link *hmap_link_pop(const struct hmap *map, struct hmap_link **linkp); -int hmap_link_alloc(const struct hmap *map, struct hmap_link **out, - struct hmap_key key, struct hmap_val value); +struct hmap_link *hmap_link_alloc(const struct hmap *map, + struct hmap_key key, struct hmap_val value, int *rc); struct hmap_link *hmap_get(const struct hmap *map, struct hmap_key key); int hmap_set(const struct hmap *map, struct hmap_key key, struct hmap_val value); diff --git a/src/hmap.c b/src/hmap.c @@ -16,57 +16,69 @@ hmap_init(struct hmap *map, size_t size, hmap_hash_func hasher, { int rc; - LIBHMAP_ABORT_ON_ARGS(!map || !size || !hasher || !keycmp || !allocator); + LIBHMAP_ABORT_ON_ARGS(!size || !hasher || !keycmp || !allocator); map->allocator = allocator; map->keycmp = keycmp; map->bucketcnt = size; map->hash = hasher; - rc = map->allocator->alloc((void **)&map->buckets, - sizeof(void *) * size); - if (rc) return -rc; + map->buckets = map->allocator->alloc(sizeof(void *) * size, &rc); + if (!map->buckets) return -rc; memset(map->buckets, 0, size * sizeof(void *)); return 0; } -void +int hmap_deinit(struct hmap *map) { LIBHMAP_ABORT_ON_ARGS(!map); hmap_clear(map); - map->allocator->free(map->buckets); + return map->allocator->free(map->buckets); } -int -hmap_alloc(struct hmap **map, size_t size, hmap_hash_func hasher, - hmap_keycmp_func keycmp, const struct allocator *allocator) +struct hmap * +hmap_alloc(size_t size, hmap_hash_func hasher, + hmap_keycmp_func keycmp, const struct allocator *allocator, int *_rc) { - int rc; + struct hmap *map; + int *rc, stub; LIBHMAP_ABORT_ON_ARGS(!allocator); - rc = allocator->alloc((void **)map, sizeof(struct hmap)); - if (rc) return -rc; + rc = _rc ? _rc : &stub; - rc = hmap_init(*map, size, hasher, keycmp, allocator); - if (rc) return rc; + map = allocator->alloc(sizeof(struct hmap), rc); + if (!map && _rc) *rc = -*rc; + if (!map) return NULL; - return 0; + *rc = hmap_init(map, size, hasher, keycmp, allocator); + if (*rc) { + allocator->free(map); + return NULL; + } + + return map; } -void +int hmap_free(struct hmap *map) { const struct allocator *allocator; + int rc; LIBHMAP_ABORT_ON_ARGS(!map); allocator = map->allocator; - hmap_deinit(map); - allocator->free(map); + rc = hmap_deinit(map); + if (rc) return rc; + + rc = allocator->free(map); + if (rc) return -rc; + + return 0; } int @@ -77,7 +89,7 @@ hmap_copy(const struct hmap *dst, const struct hmap *src) LIBHMAP_ABORT_ON_ARGS(!dst || !src); - for (HMAP_ITER(src, &iter)) { + for (HMAP_ITER(src, iter)) { rc = hmap_set(dst, iter.link->key, iter.link->value); if (rc) return rc; } @@ -107,7 +119,7 @@ hmap_clear(const struct hmap *map) LIBHMAP_ABORT_ON_ARGS(!map); prev = NULL; - for (HMAP_ITER(map, &iter)) { + for (HMAP_ITER(map, iter)) { map->allocator->free(prev); prev = iter.link; } @@ -166,23 +178,23 @@ hmap_link_pop(const struct hmap *map, struct hmap_link **link) return tmp; } -int -hmap_link_alloc(const struct hmap *map, struct hmap_link **out, - struct hmap_key key, struct hmap_val value) +struct hmap_link * +hmap_link_alloc(const struct hmap *map, + struct hmap_key key, struct hmap_val value, int *rc) { struct hmap_link *link; - int rc; - LIBHMAP_ABORT_ON_ARGS(!map || !out); + LIBHMAP_ABORT_ON_ARGS(!map); + + link = map->allocator->alloc(sizeof(struct hmap_link), rc); + if (!link && rc) *rc = -*rc; + if (!link) return NULL; - rc = map->allocator->alloc((void **)&link, sizeof(struct hmap_link)); - if (rc) return -rc; link->key = key; link->value = value; link->next = NULL; - *out = link; - return 0; + return link; } struct hmap_link * @@ -241,8 +253,8 @@ hmap_add(const struct hmap *map, struct hmap_key key, struct hmap_val value) iter = hmap_link_pos(map, key); if (*iter) return HMAP_KEY_EXISTS; - rc = hmap_link_alloc(map, iter, key, value); - if (rc) return rc; + *iter = hmap_link_alloc(map, key, value, &rc); + if (!*iter) return rc; return 0; } diff --git a/src/test.c b/src/test.c @@ -31,12 +31,12 @@ main(int argc, const char **argv) if (rc) LIBHMAP_ERR(rc); } - for (HMAP_ITER(&hmap, &iter)) { + for (HMAP_ITER(&hmap, iter)) { printf("%s: %i\n", (char *)iter.link->key.p, iter.link->value.i); } - for (HMAP_ITER(&hmap, &iter)) + for (HMAP_ITER(&hmap, iter)) free(iter.link->key._p); hmap_deinit(&hmap); }