commit 2cc02a318e3c42e536715e1af1213f25a2440da2
parent e4746507ef06d7380d113c3fea7303c7bc891049
Author: Louis Burda <quent.burda@gmail.com>
Date: Fri, 17 Mar 2023 19:27:20 +0100
Use liballoc for allocations
Diffstat:
6 files changed, 67 insertions(+), 46 deletions(-)
diff --git a/.gitmodules b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "lib/liballoc"]
+ path = lib/liballoc
+ url = git@sinitax.com:snx/liballoc
diff --git a/Makefile b/Makefile
@@ -2,7 +2,7 @@ PREFIX ?= /usr/local
INCLDIR ?= /include
LIBDIR ?= /lib
-CFLAGS = -I include -Wno-prototype -Wunused-function
+CFLAGS = -I include -I lib/liballoc/include -Wno-prototype -Wunused-function
CFLAGS += -Wunused-variable -Wconversion
ifeq "$(DEBUG)" "1"
@@ -17,6 +17,9 @@ clean:
build:
mkdir build
+lib/liballoc/build/liballoc.a:
+ make -C lib/liballoc build/liballoc.a
+
build/libhashmap.a: src/hashmap.c include/hashmap.h | build
$(CC) -o build/tmp.o src/hashmap.c $(CFLAGS) -r
objcopy --keep-global-symbols=libhashmap.api build/tmp.o build/fixed.o
@@ -26,8 +29,8 @@ build/libhashmap.so: src/hashmap.c include/hashmap.h | build
$(CC) -o $@ src/hashmap.c -fPIC $(CFLAGS) -shared \
-Wl,-version-script libhashmap.lds
-build/test: src/test.c build/libhashmap.a | build
- $(CC) -o $@ $^ -I include -g
+build/test: src/test.c build/libhashmap.a lib/liballoc/build/liballoc.a | build
+ $(CC) -o $@ $^ -I include -I lib/liballoc/include -g
install:
install -m 644 include/hashmap.h -t "$(DESTDIR)$(PREFIX)$(INCLDIR)"
diff --git a/include/hashmap.h b/include/hashmap.h
@@ -1,8 +1,10 @@
#pragma once
+#include "allocator.h"
+
#include <stdint.h>
#include <stdbool.h>
-#include <stdlib.h>
+#include <stddef.h>
#define HASHMAP_ITER(map, iter) \
hashmap_iter_init(iter); hashmap_iter_next(map, iter);
@@ -26,12 +28,15 @@ struct hashmap {
map_hash_func hash;
struct hashmap_link **buckets;
size_t size;
+ const struct allocator *allocator;
};
-int hashmap_init(struct hashmap *map, size_t size, map_hash_func hasher);
+int hashmap_init(struct hashmap *map, size_t size, map_hash_func hasher,
+ const struct allocator *allocator);
void hashmap_deinit(struct hashmap *map);
-int hashmap_alloc(struct hashmap **map, size_t size, map_hash_func hasher);
+int hashmap_alloc(struct hashmap **map, size_t size, map_hash_func hasher,
+ const struct allocator *allocator);
void hashmap_free(struct hashmap *map);
void hashmap_clear(struct hashmap *map);
@@ -41,7 +46,8 @@ struct hashmap_link *hashmap_get(struct hashmap *map,
struct hashmap_link *hashmap_pop(struct hashmap *map,
const void *key, size_t size);
-void hashmap_link_set(struct hashmap_link *link, void *key, size_t key_size,
+void hashmap_link_set(struct hashmap *map,
+ struct hashmap_link *link, void *key, size_t key_size,
void *value, size_t value_size);
int hashmap_set(struct hashmap *map, void *key, size_t key_size,
void *value, size_t value_size);
diff --git a/lib/liballoc b/lib/liballoc
@@ -0,0 +1 @@
+Subproject commit 322bdbc251ccb21e967c75ee1b88ce152fc99982
diff --git a/src/hashmap.c b/src/hashmap.c
@@ -1,25 +1,13 @@
#include "hashmap.h"
#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
static struct hashmap_link **hashmap_get_linkp(struct hashmap *map,
const void *key, size_t size);
-static int hashmap_link_alloc(struct hashmap_link **link,
+static int hashmap_link_alloc(struct hashmap *map, struct hashmap_link **link,
void *key, size_t key_size, void *value, size_t value_size);
-static inline void libhashmap_assert(int cond,
- const char *file, int line, const char *condstr)
-{
- if (cond) return;
-
- fprintf(stderr, "libhashmap: Assertion failed at %s:%i (%s)\n",
- file, line, condstr);
- abort();
-}
-
static inline size_t
hashmap_key_bucket(struct hashmap *map, const void *key, size_t size)
{
@@ -49,13 +37,14 @@ hashmap_get_linkp(struct hashmap *map, const void *key, size_t size)
}
int
-hashmap_link_alloc(struct hashmap_link **out, void *key, size_t key_size,
- void *value, size_t value_size)
+hashmap_link_alloc(struct hashmap *map, struct hashmap_link **out,
+ void *key, size_t key_size, void *value, size_t value_size)
{
struct hashmap_link *link;
+ int rc;
- link = malloc(sizeof(struct hashmap_link));
- if (!link) return -errno;
+ rc = map->allocator->alloc((void **)&link, sizeof(struct hashmap_link));
+ if (rc) return -rc;
link->key = key;
link->key_size = key_size;
link->value = value;
@@ -67,13 +56,20 @@ hashmap_link_alloc(struct hashmap_link **out, void *key, size_t key_size,
}
int
-hashmap_init(struct hashmap *map, size_t size, map_hash_func hasher)
+hashmap_init(struct hashmap *map, size_t size, map_hash_func hasher,
+ const struct allocator *allocator)
{
- map->buckets = calloc(size, sizeof(struct hashmap_link *));
- if (!map->buckets) return -errno;
+ int rc;
+
+ map->allocator = allocator;
map->size = size;
map->hash = hasher;
+ rc = map->allocator->alloc((void **)&map->buckets,
+ sizeof(void *) * size);
+ if (rc) return -rc;
+ memset(map->buckets, 0, size * sizeof(void *));
+
return 0;
}
@@ -81,20 +77,21 @@ void
hashmap_deinit(struct hashmap *map)
{
hashmap_clear(map);
- free(map->buckets);
+ map->allocator->free(map->buckets);
}
int
-hashmap_alloc(struct hashmap **map, size_t size, map_hash_func hasher)
+hashmap_alloc(struct hashmap **map, size_t size, map_hash_func hasher,
+ const struct allocator *allocator)
{
int rc;
- *map = malloc(sizeof(struct hashmap));
- if (!*map) return -errno;
+ rc = allocator->alloc((void **)map, sizeof(struct hashmap));
+ if (rc) return -rc;
- rc = hashmap_init(*map, size, hasher);
+ rc = hashmap_init(*map, size, hasher, allocator);
if (rc) {
- free(*map);
+ allocator->free(*map);
return rc;
}
@@ -104,21 +101,28 @@ hashmap_alloc(struct hashmap **map, size_t size, map_hash_func hasher)
void
hashmap_free(struct hashmap *map)
{
+ const struct allocator *allocator;
+
+ allocator = map->allocator;
hashmap_deinit(map);
- free(map);
+ allocator->free(map);
}
void
hashmap_clear(struct hashmap *map)
{
struct hashmap_iter iter;
+ struct hashmap_link *prev;
size_t i;
+ prev = NULL;
for (HASHMAP_ITER(map, &iter)) {
- free(iter.link->key);
- free(iter.link->value);
- free(iter.link);
+ free(prev);
+ map->allocator->free(iter.link->key);
+ map->allocator->free(iter.link->value);
+ prev = iter.link;
}
+ free(prev);
for (i = 0; i < map->size; i++)
map->buckets[i] = NULL;
@@ -149,14 +153,14 @@ hashmap_pop(struct hashmap *map, const void *key, size_t size)
}
void
-hashmap_link_set(struct hashmap_link *link, void *key, size_t key_size,
- void *value, size_t value_size)
+hashmap_link_set(struct hashmap *map, struct hashmap_link *link,
+ void *key, size_t key_size, void *value, size_t value_size)
{
- free(link->key);
+ map->allocator->free(link->key);
link->key = key;
link->key_size = key_size;
- free(link->value);
+ map->allocator->free(link->value);
link->value = value;
link->value_size = value_size;
}
@@ -175,9 +179,11 @@ hashmap_set(struct hashmap *map, void *key, size_t key_size,
}
if (*iter) {
- hashmap_link_set(*iter, key, key_size, value, value_size);
+ hashmap_link_set(map, *iter,
+ key, key_size, value, value_size);
} else {
- rc = hashmap_link_alloc(iter, key, key_size, value, value_size);
+ rc = hashmap_link_alloc(map, iter,
+ key, key_size, value, value_size);
if (rc) return rc;
}
diff --git a/src/test.c b/src/test.c
@@ -15,7 +15,7 @@ main(int argc, const char **argv)
void *key, *value;
int i, rc;
- rc = hashmap_init(&hashmap, 10, hashmap_str_hasher);
+ rc = hashmap_init(&hashmap, 10, hashmap_str_hasher, &stdlib_heap_allocator);
if (rc) LIBHASHMAP_ERR(rc);
for (i = 1; i < argc; i++) {
@@ -27,8 +27,10 @@ main(int argc, const char **argv)
if (rc) LIBHASHMAP_ERR(rc);
}
- for (HASHMAP_ITER(&hashmap, &iter))
- printf("%s: %i\n", iter.link->key, *(int*)iter.link->value);
+ for (HASHMAP_ITER(&hashmap, &iter)) {
+ printf("%s: %i\n", (char *)iter.link->key,
+ *(int*)iter.link->value);
+ }
hashmap_deinit(&hashmap);
}