hash-func: add destructors for key and value
If they are set, then they are called in hashmap_clear() or hashmap_free().
This commit is contained in:
+23
-61
@@ -864,47 +864,38 @@ static void hashmap_free_no_clear(HashmapBase *h) {
|
||||
free(h);
|
||||
}
|
||||
|
||||
HashmapBase *internal_hashmap_free(HashmapBase *h) {
|
||||
|
||||
/* Free the hashmap, but nothing in it */
|
||||
|
||||
HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
|
||||
if (h) {
|
||||
internal_hashmap_clear(h);
|
||||
internal_hashmap_clear(h, default_free_key, default_free_value);
|
||||
hashmap_free_no_clear(h);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HashmapBase *internal_hashmap_free_free(HashmapBase *h) {
|
||||
|
||||
/* Free the hashmap and all data objects in it, but not the
|
||||
* keys */
|
||||
|
||||
if (h) {
|
||||
internal_hashmap_clear_free(h);
|
||||
hashmap_free_no_clear(h);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Hashmap *hashmap_free_free_free(Hashmap *h) {
|
||||
|
||||
/* Free the hashmap and all data and key objects in it */
|
||||
|
||||
if (h) {
|
||||
hashmap_clear_free_free(h);
|
||||
hashmap_free_no_clear(HASHMAP_BASE(h));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void internal_hashmap_clear(HashmapBase *h) {
|
||||
void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
|
||||
free_func_t free_key, free_value;
|
||||
if (!h)
|
||||
return;
|
||||
|
||||
free_key = h->hash_ops->free_key ?: default_free_key;
|
||||
free_value = h->hash_ops->free_value ?: default_free_value;
|
||||
|
||||
if (free_key || free_value) {
|
||||
unsigned idx;
|
||||
|
||||
for (idx = skip_free_buckets(h, 0); idx != IDX_NIL;
|
||||
idx = skip_free_buckets(h, idx + 1)) {
|
||||
struct hashmap_base_entry *e = bucket_at(h, idx);
|
||||
|
||||
if (free_key)
|
||||
free_key((void *) e->key);
|
||||
|
||||
if (free_value)
|
||||
free_value(entry_value(h, e));
|
||||
}
|
||||
}
|
||||
|
||||
if (h->has_indirect) {
|
||||
free(h->indirect.storage);
|
||||
h->has_indirect = false;
|
||||
@@ -921,35 +912,6 @@ void internal_hashmap_clear(HashmapBase *h) {
|
||||
base_set_dirty(h);
|
||||
}
|
||||
|
||||
void internal_hashmap_clear_free(HashmapBase *h) {
|
||||
unsigned idx;
|
||||
|
||||
if (!h)
|
||||
return;
|
||||
|
||||
for (idx = skip_free_buckets(h, 0); idx != IDX_NIL;
|
||||
idx = skip_free_buckets(h, idx + 1))
|
||||
free(entry_value(h, bucket_at(h, idx)));
|
||||
|
||||
internal_hashmap_clear(h);
|
||||
}
|
||||
|
||||
void hashmap_clear_free_free(Hashmap *h) {
|
||||
unsigned idx;
|
||||
|
||||
if (!h)
|
||||
return;
|
||||
|
||||
for (idx = skip_free_buckets(HASHMAP_BASE(h), 0); idx != IDX_NIL;
|
||||
idx = skip_free_buckets(HASHMAP_BASE(h), idx + 1)) {
|
||||
struct plain_hashmap_entry *e = plain_bucket_at(h, idx);
|
||||
free((void*)e->b.key);
|
||||
free(e->value);
|
||||
}
|
||||
|
||||
internal_hashmap_clear(HASHMAP_BASE(h));
|
||||
}
|
||||
|
||||
static int resize_buckets(HashmapBase *h, unsigned entries_add);
|
||||
|
||||
/*
|
||||
@@ -1740,7 +1702,7 @@ HashmapBase *internal_hashmap_copy(HashmapBase *h) {
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
internal_hashmap_free(copy);
|
||||
internal_hashmap_free(copy, false, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user