object: hashmap: implement key/value destructors

This commit is contained in:
2025-06-27 21:46:55 +01:00
parent 5634506433
commit 579a9e8505
3 changed files with 42 additions and 11 deletions

View File

@@ -11,8 +11,22 @@
#define HASH_OFFSET_BASIS 0xcbf29ce484222325 #define HASH_OFFSET_BASIS 0xcbf29ce484222325
#define HASH_PRIME 0x100000001b3 #define HASH_PRIME 0x100000001b3
/* clang-format off */
static B_BTREE_DEFINE_SIMPLE_GET(
struct b_hashmap_bucket,
uint64_t,
bk_node,
bk_hash,
get_bucket)
static B_BTREE_DEFINE_SIMPLE_INSERT(
struct b_hashmap_bucket,
bk_node,
bk_hash,
put_bucket)
static uint64_t hash_data(const void *p, size_t size) static uint64_t hash_data(const void *p, size_t size)
{ {
/* clang-format on */
const unsigned char *s = p; const unsigned char *s = p;
uint64_t hash = HASH_OFFSET_BASIS; uint64_t hash = HASH_OFFSET_BASIS;
@@ -34,7 +48,8 @@ static struct b_object_type hashmap_type = {
.t_release = hashmap_release, .t_release = hashmap_release,
}; };
struct b_hashmap *b_hashmap_create(void) struct b_hashmap *b_hashmap_create(
b_hashmap_key_destructor key_dtor, b_hashmap_value_destructor value_dtor)
{ {
struct b_hashmap *hashmap struct b_hashmap *hashmap
= (struct b_hashmap *)b_object_type_instantiate(&hashmap_type); = (struct b_hashmap *)b_object_type_instantiate(&hashmap_type);
@@ -47,7 +62,7 @@ struct b_hashmap *b_hashmap_create(void)
struct b_hashmap *b_hashmap_create_with_items(const b_hashmap_item *items) struct b_hashmap *b_hashmap_create_with_items(const b_hashmap_item *items)
{ {
struct b_hashmap *hashmap = b_hashmap_create(); struct b_hashmap *hashmap = b_hashmap_create(NULL, NULL);
if (!hashmap) { if (!hashmap) {
return NULL; return NULL;
} }
@@ -59,12 +74,9 @@ struct b_hashmap *b_hashmap_create_with_items(const b_hashmap_item *items)
return hashmap; return hashmap;
} }
static B_BTREE_DEFINE_SIMPLE_GET(
struct b_hashmap_bucket, uint64_t, bk_node, bk_hash,
get_bucket) static B_BTREE_DEFINE_SIMPLE_INSERT(struct b_hashmap_bucket, bk_node, bk_hash, put_bucket)
static struct b_hashmap_bucket *create_bucket(void) static struct b_hashmap_bucket *create_bucket(void)
{ {
/* clang-format on */
struct b_hashmap_bucket *bucket = malloc(sizeof *bucket); struct b_hashmap_bucket *bucket = malloc(sizeof *bucket);
if (!bucket) { if (!bucket) {
return NULL; return NULL;
@@ -221,6 +233,15 @@ static b_status delete_item(
struct b_hashmap_bucket_item *item) struct b_hashmap_bucket_item *item)
{ {
b_queue_delete(&bucket->bk_items, &item->bi_entry); b_queue_delete(&bucket->bk_items, &item->bi_entry);
if (hashmap->h_key_dtor) {
hashmap->h_key_dtor((void *)item->bi_key.key_data);
}
if (hashmap->h_value_dtor) {
hashmap->h_value_dtor((void *)item->bi_value.value_data);
}
free(item); free(item);
if (b_queue_empty(&bucket->bk_items)) { if (b_queue_empty(&bucket->bk_items)) {
@@ -426,6 +447,12 @@ bool b_hashmap_iterator_is_valid(const struct b_hashmap_iterator *it)
static void hashmap_release(struct b_object *obj) static void hashmap_release(struct b_object *obj)
{ {
struct b_hashmap *map = B_HASHMAP(obj); struct b_hashmap *map = B_HASHMAP(obj);
b_hashmap_iterator it;
b_hashmap_iterator_begin(map, &it);
while (b_hashmap_iterator_is_valid(&it)) {
b_hashmap_iterator_erase(&it);
}
} }
b_object_type_id b_hashmap_type_id(void) b_object_type_id b_hashmap_type_id(void)

View File

@@ -20,6 +20,8 @@ struct b_hashmap_bucket {
struct b_hashmap { struct b_hashmap {
struct b_object h_base; struct b_object h_base;
struct b_btree h_buckets; struct b_btree h_buckets;
b_hashmap_key_destructor h_key_dtor;
b_hashmap_value_destructor h_value_dtor;
}; };
#endif #endif

View File

@@ -35,16 +35,17 @@
typedef struct b_hashmap b_hashmap; typedef struct b_hashmap b_hashmap;
typedef void (*b_hashmap_key_destructor)(void *);
typedef void (*b_hashmap_value_destructor)(void *);
typedef struct b_hashmap_key { typedef struct b_hashmap_key {
const void *key_data; const void *key_data;
size_t key_size; size_t key_size;
bool key_owned;
} b_hashmap_key; } b_hashmap_key;
typedef struct b_hashmap_value { typedef struct b_hashmap_value {
void *value_data; void *value_data;
size_t value_size; size_t value_size;
bool value_owned;
} b_hashmap_value; } b_hashmap_value;
typedef struct b_hashmap_item { typedef struct b_hashmap_item {
@@ -63,7 +64,8 @@ typedef struct b_hashmap_iterator {
b_queue_entry *_cqe; b_queue_entry *_cqe;
} b_hashmap_iterator; } b_hashmap_iterator;
BLUE_API b_hashmap *b_hashmap_create(void); BLUE_API b_hashmap *b_hashmap_create(
b_hashmap_key_destructor key_dtor, b_hashmap_value_destructor value_dtor);
BLUE_API b_hashmap *b_hashmap_create_with_items(const b_hashmap_item *items); BLUE_API b_hashmap *b_hashmap_create_with_items(const b_hashmap_item *items);
static inline b_hashmap *b_hashmap_retain(b_hashmap *hashmap) static inline b_hashmap *b_hashmap_retain(b_hashmap *hashmap)