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:
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;
}