Fixing hashtables and added hashmap init and release

This commit is contained in:
Leonardo committed 2020-04-29 20:08:42 -03:00
1 parent 5d68dcc538
commit 9ade952392
18 files changed
+821 -296

No files matched your search

+8
View File
@@ -832,6 +832,10 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> "
\
if (!e1 || !e2) \
{ \
/* Prevent the map from freeing the data */ \
_new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
_new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
\
_map_->alloc->free(_new_map_->buffer); \
_map_->alloc->free(_new_map_); \
\
@@ -846,6 +850,10 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> "
\
if (_map_->count != _new_map_->count) \
{ \
/* Prevent the map from freeing the data */ \
_new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
_new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
\
_map_->alloc->free(_new_map_->buffer); \
_map_->alloc->free(_new_map_); \
\
+80 -69
View File
@@ -89,12 +89,6 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
\
/* Custom callback functions */ \
struct cmc_callbacks *callbacks; \
\
/* Function that returns an iterator to the start of the hashmap */ \
struct SNAME##_iter (*it_start)(struct SNAME *); \
\
/* Function that returns an iterator to the end of the hashmap */ \
struct SNAME##_iter (*it_end)(struct SNAME *); \
}; \
\
/* Hashmap Entry */ \
@@ -192,8 +186,16 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
size_t capacity, double load, struct SNAME##_fkey *f_key, \
struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
struct cmc_callbacks *callbacks); \
struct SNAME PFX##_init(size_t capacity, double load, \
struct SNAME##_fkey *f_key, \
struct SNAME##_fval *f_val); \
struct SNAME PFX##_init_custom( \
size_t capacity, double load, struct SNAME##_fkey *f_key, \
struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
struct cmc_callbacks *callbacks); \
void PFX##_clear(struct SNAME *_map_); \
void PFX##_free(struct SNAME *_map_); \
void PFX##_release(struct SNAME _map_); \
/* Customization of Allocation and Callbacks */ \
void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
struct cmc_callbacks *callbacks); \
@@ -253,53 +255,12 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, \
K key); \
static size_t PFX##_impl_calculate_size(size_t required); \
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_map_); \
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_); \
\
struct SNAME *PFX##_new(size_t capacity, double load, \
struct SNAME##_fkey *f_key, \
struct SNAME##_fval *f_val) \
{ \
struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
\
if (capacity == 0 || load <= 0 || load >= 1) \
return NULL; \
\
/* Prevent integer overflow */ \
if (capacity >= UINTMAX_MAX * load) \
return NULL; \
\
if (!f_key || !f_val) \
return NULL; \
\
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
\
struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
\
if (!_map_) \
return NULL; \
\
_map_->buffer = \
alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
\
if (!_map_->buffer) \
{ \
alloc->free(_map_); \
return NULL; \
} \
\
_map_->count = 0; \
_map_->capacity = real_capacity; \
_map_->load = load; \
_map_->flag = cmc_flags.OK; \
_map_->f_key = f_key; \
_map_->f_val = f_val; \
_map_->alloc = alloc; \
_map_->callbacks = NULL; \
_map_->it_start = PFX##_impl_it_start; \
_map_->it_end = PFX##_impl_it_end; \
\
return _map_; \
return PFX##_new_custom(capacity, load, f_key, f_val, NULL, NULL); \
} \
\
struct SNAME *PFX##_new_custom( \
@@ -344,8 +305,52 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
_map_->f_val = f_val; \
_map_->alloc = alloc; \
_map_->callbacks = callbacks; \
_map_->it_start = PFX##_impl_it_start; \
_map_->it_end = PFX##_impl_it_end; \
\
return _map_; \
} \
struct SNAME PFX##_init(size_t capacity, double load, \
struct SNAME##_fkey *f_key, \
struct SNAME##_fval *f_val) \
{ \
return PFX##_init_custom(capacity, load, f_key, f_val, NULL, NULL); \
} \
\
struct SNAME PFX##_init_custom( \
size_t capacity, double load, struct SNAME##_fkey *f_key, \
struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
struct cmc_callbacks *callbacks) \
{ \
struct SNAME _map_ = { 0 }; \
\
if (capacity == 0 || load <= 0 || load >= 1) \
return _map_; \
\
/* Prevent integer overflow */ \
if (capacity >= UINTMAX_MAX * load) \
return _map_; \
\
if (!f_key || !f_val) \
return _map_; \
\
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
\
if (!alloc) \
alloc = &cmc_alloc_node_default; \
\
_map_.buffer = \
alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
\
if (!_map_.buffer) \
return _map_; \
\
_map_.count = 0; \
_map_.capacity = real_capacity; \
_map_.load = load; \
_map_.flag = cmc_flags.OK; \
_map_.f_key = f_key; \
_map_.f_val = f_val; \
_map_.alloc = alloc; \
_map_.callbacks = callbacks; \
\
return _map_; \
} \
@@ -397,6 +402,27 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
_map_->alloc->free(_map_); \
} \
\
void PFX##_release(struct SNAME _map_) \
{ \
if (_map_.f_key->free || _map_.f_val->free) \
{ \
for (size_t i = 0; i < _map_.capacity; i++) \
{ \
struct SNAME##_entry *entry = &(_map_.buffer[i]); \
\
if (entry->state == CMC_ES_FILLED) \
{ \
if (_map_.f_key->free) \
_map_.f_key->free(entry->key); \
if (_map_.f_val->free) \
_map_.f_val->free(entry->value); \
} \
} \
} \
\
_map_.alloc->free(_map_.buffer); \
} \
\
void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
struct cmc_callbacks *callbacks) \
{ \
@@ -779,6 +805,10 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
_map_->capacity = _new_map_->capacity; \
_new_map_->capacity = tmp_c; \
\
/* Prevent the map from freeing the data */ \
_new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
_new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
\
PFX##_free(_new_map_); \
\
success: \
@@ -1161,25 +1191,6 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
i++; \
\
return cmc_hashtable_primes[i]; \
} \
\
static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_map_) \
{ \
struct SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _map_); \
\
return iter; \
} \
\
static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_) \
{ \
struct SNAME##_iter iter; \
\
PFX##_iter_init(&iter, _map_); \
PFX##_iter_to_end(&iter); \
\
return iter; \
}
#endif /* CMC_HASHMAP_H */
+3
View File
@@ -649,6 +649,9 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> "
_set_->capacity = _new_set_->capacity; \
_new_set_->capacity = tmp_c; \
\
/* Prevent the set from freeing the data */ \
_new_set_->f_val = &(struct SNAME##_fval){ NULL }; \
\
PFX##_free(_new_set_); \
\
success: \
+4
View File
@@ -1027,6 +1027,10 @@ static const char *cmc_string_fmt_multimap = "struct %s<%s, %s> "
_map_->capacity = _new_map_->capacity; \
_new_map_->capacity = tmp_c; \
\
/* Prevent the map from freeing the data */ \
_new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
_new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
\
PFX##_free(_new_map_); \
\
success: \
+3
View File
@@ -769,6 +769,9 @@ static const char *cmc_string_fmt_multiset = "struct %s<%s> "
_set_->capacity = _new_set_->capacity; \
_new_set_->capacity = tmp_c; \
\
/* Prevent the set from freeing the data */ \
_new_set_->f_val = &(struct SNAME##_fval){ NULL }; \
\
PFX##_free(_new_set_); \
\
success: \