object: hashmap: implement key/value destructors
This commit is contained in:
@@ -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(
|
static struct b_hashmap_bucket *create_bucket(void)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
/* 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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#define B_HASHMAP_ITEM_END \
|
#define B_HASHMAP_ITEM_END \
|
||||||
{ \
|
{ \
|
||||||
.key = {0}, .value = {0} \
|
.key = {0}, .value = { 0 } \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define b_hashmap_foreach(it, hashmap) \
|
#define b_hashmap_foreach(it, hashmap) \
|
||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user