diff --git a/autogen.py b/autogen.py index 85f7ea9..bb443cc 100644 --- a/autogen.py +++ b/autogen.py @@ -26,6 +26,7 @@ OUTPUT_DIR = './tests/main/src' collections = [ # type, header, pfx, sname, key, val {'t': 'BIDIMAP', 'h': '"cmc/bidimap.h"', 'pfx': 'bm', 'sname': 'bidimap', 'key': 'size_t', 'val': 'size_t'}, + {'t': 'BITSET', 'h': '"cmc/bitset.h"', 'pfx': 'bs', 'sname': 'bitset', 'key': '', 'val': '' }, {'t': 'DEQUE', 'h': '"cmc/deque.h"', 'pfx': 'd', 'sname': 'deque', 'key': '', 'val': 'size_t'}, {'t': 'HASHMAP', 'h': '"cmc/hashmap.h"', 'pfx': 'hm', 'sname': 'hashmap', 'key': 'size_t', 'val': 'size_t'}, {'t': 'HASHSET', 'h': '"cmc/hashset.h"', 'pfx': 'hs', 'sname': 'hashset', 'key': '', 'val': 'size_t'}, @@ -49,13 +50,23 @@ if not os.path.exists(OUTPUT_DIR): for data in collections: file = open(TMP_FILE, 'w') + if data['key'] == '' and data['val'] == '': + # bitset, no K and no V + type_params = '' + elif data['key'] != '': + # maps, K and V + type_params = f', {data["key"]}, {data["val"]}' + else: + # only V + type_params = f', {data["val"]}' + file.write( f''' #include {data['h']} {UNIQUE_FLAG} - CMC_GENERATE_{data['t']}({data['pfx']}, {data['sname']}, {f'{data["key"]}, {data["val"]}' if data['key'] != '' else data['val']}) + CMC_GENERATE_{data['t']}({data['pfx']}, {data['sname']}{type_params}) {UNIQUE_FLAG} ''') diff --git a/src/cmc/bidimap.h b/src/cmc/bidimap.h index 3404907..1bf7e86 100644 --- a/src/cmc/bidimap.h +++ b/src/cmc/bidimap.h @@ -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_); \ \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index d6503ce..52ba203 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -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 */ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 1d26811..a5d8163 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -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: \ diff --git a/src/cmc/multimap.h b/src/cmc/multimap.h index fafa6bd..9a73f93 100644 --- a/src/cmc/multimap.h +++ b/src/cmc/multimap.h @@ -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: \ diff --git a/src/cmc/multiset.h b/src/cmc/multiset.h index a728e10..ff6045c 100644 --- a/src/cmc/multiset.h +++ b/src/cmc/multiset.h @@ -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: \ diff --git a/tests/main/src/bidimap.c b/tests/main/src/bidimap.c index 69dcd37..e3e9dc5 100644 --- a/tests/main/src/bidimap.c +++ b/tests/main/src/bidimap.c @@ -509,6 +509,8 @@ _Bool bm_resize(struct bidimap *_map_, size_t capacity) bm_impl_add_entry_to_val(_new_map_, scan); if (!e1 || !e2) { + _new_map_->f_key = &(struct bidimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct bidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = cmc_flags.ERROR; @@ -519,6 +521,8 @@ _Bool bm_resize(struct bidimap *_map_, size_t capacity) } if (_map_->count != _new_map_->count) { + _new_map_->f_key = &(struct bidimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct bidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = cmc_flags.ERROR; diff --git a/tests/main/src/hashmap.c b/tests/main/src/hashmap.c index fa8b76e..b7490c1 100644 --- a/tests/main/src/hashmap.c +++ b/tests/main/src/hashmap.c @@ -11,8 +11,6 @@ struct hashmap struct hashmap_fval *f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; - struct hashmap_iter (*it_start)(struct hashmap *); - struct hashmap_iter (*it_end)(struct hashmap *); }; struct hashmap_entry { @@ -56,8 +54,16 @@ struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, + struct hashmap_fval *f_val); +struct hashmap hm_init_custom(size_t capacity, double load, + struct hashmap_fkey *f_key, + struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); void hm_clear(struct hashmap *_map_); void hm_free(struct hashmap *_map_); +void hm_release(struct hashmap _map_); void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); @@ -99,39 +105,11 @@ size_t hm_iter_index(struct hashmap_iter *iter); static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key); static size_t hm_impl_calculate_size(size_t required); -static struct hashmap_iter hm_impl_it_start(struct hashmap *_map_); -static struct hashmap_iter hm_impl_it_end(struct hashmap *_map_); struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hm_impl_calculate_size(capacity / load); - struct hashmap *_map_ = alloc->malloc(sizeof(struct hashmap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); - if (!_map_->buffer) - { - alloc->free(_map_); - return ((void *)0); - } - _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 = ((void *)0); - _map_->it_start = hm_impl_it_start; - _map_->it_end = hm_impl_it_end; - return _map_; + return hm_new_custom(capacity, load, f_key, f_val, ((void *)0), + ((void *)0)); } struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, @@ -165,8 +143,41 @@ struct hashmap *hm_new_custom(size_t capacity, double load, _map_->f_val = f_val; _map_->alloc = alloc; _map_->callbacks = callbacks; - _map_->it_start = hm_impl_it_start; - _map_->it_end = hm_impl_it_end; + return _map_; +} +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, + struct hashmap_fval *f_val) +{ + return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), + ((void *)0)); +} +struct hashmap hm_init_custom(size_t capacity, double load, + struct hashmap_fkey *f_key, + struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + struct hashmap _map_ = { 0 }; + if (capacity == 0 || load <= 0 || load >= 1) + return _map_; + if (capacity >= 0xffffffffffffffffULL * load) + return _map_; + if (!f_key || !f_val) + return _map_; + size_t real_capacity = hm_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_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_; } void hm_clear(struct hashmap *_map_) @@ -208,6 +219,24 @@ void hm_free(struct hashmap *_map_) _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } +void hm_release(struct hashmap _map_) +{ + if (_map_.f_key->free || _map_.f_val->free) + { + for (size_t i = 0; i < _map_.capacity; i++) + { + struct hashmap_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 hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { @@ -496,6 +525,8 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) size_t tmp_c = _map_->capacity; _map_->capacity = _new_map_->capacity; _new_map_->capacity = tmp_c; + _new_map_->f_key = &(struct hashmap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; hm_free(_new_map_); success: if (_map_->callbacks && _map_->callbacks->resize) @@ -786,16 +817,3 @@ static size_t hm_impl_calculate_size(size_t required) i++; return cmc_hashtable_primes[i]; } -static struct hashmap_iter hm_impl_it_start(struct hashmap *_map_) -{ - struct hashmap_iter iter; - hm_iter_init(&iter, _map_); - return iter; -} -static struct hashmap_iter hm_impl_it_end(struct hashmap *_map_) -{ - struct hashmap_iter iter; - hm_iter_init(&iter, _map_); - hm_iter_to_end(&iter); - return iter; -} diff --git a/tests/main/src/hashset.c b/tests/main/src/hashset.c index acf09fd..11a3dcc 100644 --- a/tests/main/src/hashset.c +++ b/tests/main/src/hashset.c @@ -400,6 +400,7 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) size_t tmp_c = _set_->capacity; _set_->capacity = _new_set_->capacity; _new_set_->capacity = tmp_c; + _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; hs_free(_new_set_); success: if (_set_->callbacks && _set_->callbacks->resize) diff --git a/tests/main/src/multimap.c b/tests/main/src/multimap.c index a034a62..2238cf6 100644 --- a/tests/main/src/multimap.c +++ b/tests/main/src/multimap.c @@ -668,6 +668,8 @@ _Bool mm_resize(struct multimap *_map_, size_t capacity) size_t tmp_c = _map_->capacity; _map_->capacity = _new_map_->capacity; _new_map_->capacity = tmp_c; + _new_map_->f_key = &(struct multimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct multimap_fval){ ((void *)0) }; mm_free(_new_map_); success: if (_map_->callbacks && _map_->callbacks->resize) diff --git a/tests/main/src/multiset.c b/tests/main/src/multiset.c index 892ed79..6ee26c8 100644 --- a/tests/main/src/multiset.c +++ b/tests/main/src/multiset.c @@ -483,6 +483,7 @@ _Bool ms_resize(struct multiset *_set_, size_t capacity) size_t tmp_c = _set_->capacity; _set_->capacity = _new_set_->capacity; _new_set_->capacity = tmp_c; + _new_set_->f_val = &(struct multiset_fval){ ((void *)0) }; ms_free(_new_set_); success: if (_set_->callbacks && _set_->callbacks->resize) diff --git a/tests/main/unt/bidimap.c b/tests/main/unt/bidimap.c index 4072d89..f00ed8a 100644 --- a/tests/main/unt/bidimap.c +++ b/tests/main/unt/bidimap.c @@ -32,19 +32,29 @@ struct bidimap_fval *bm_fval_counter = &(struct bidimap_fval){ .cmp = v_c_cmp, .hash = v_c_hash, .pri = v_c_pri }; +struct cmc_alloc_node *bm_alloc_node = &(struct cmc_alloc_node){ + .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +}; + CMC_CREATE_UNIT(BidiMap, true, { - CMC_CREATE_TEST(new, { - struct bidimap *map = bm_new(100, 0.6, bm_fkey, bm_fval); + CMC_CREATE_TEST(PFX##_new(), { + struct bidimap *map = bm_new(943722, 0.6, bm_fkey, bm_fval); cmc_assert_not_equals(ptr, NULL, map); - + cmc_assert_not_equals(ptr, NULL, map->buffer); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(double, 0.6, map->load); cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(ptr, bm_fkey, map->f_key); + cmc_assert_equals(ptr, bm_fval, map->f_val); + cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, NULL, map->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), bm_capacity(map)); bm_free(map); - }); - CMC_CREATE_TEST(new[null buffer], { - struct bidimap *map = bm_new(100, 0.6, bm_fkey, bm_fval); + map = bm_new(100, 0.6, bm_fkey, bm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -55,121 +65,112 @@ CMC_CREATE_UNIT(BidiMap, true, { } bm_free(map); + + map = bm_new(0, 0.6, bm_fkey, bm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new(UINT64_MAX, 0.99, bm_fkey, bm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new(1000, 0.6, bm_fkey, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new(1000, 0.6, NULL, bm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new(1000, 0.6, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); }); - CMC_CREATE_TEST(new_custom, { - struct bidimap *map = - bm_new_custom(100, 0.6, bm_fkey, bm_fval, - &(struct cmc_alloc_node){ .malloc = malloc, - .calloc = calloc, - .realloc = realloc, - .free = free }, - &(struct cmc_callbacks){ 0 }); + CMC_CREATE_TEST(PFX##_new_custom(), { + struct bidimap *map = bm_new_custom(943722, 0.6, bm_fkey, bm_fval, + bm_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_not_equals(ptr, NULL, map->buffer); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(double, 0.6, map->load); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(ptr, bm_fkey, map->f_key); + cmc_assert_equals(ptr, bm_fval, map->f_val); + cmc_assert_equals(ptr, bm_alloc_node, map->alloc); + cmc_assert_equals(ptr, callbacks, map->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), bm_capacity(map)); bm_free(map); + + map = bm_new_custom(0, 0.6, bm_fkey, bm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new_custom(UINT64_MAX, 0.99, bm_fkey, bm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new_custom(1000, 0.6, bm_fkey, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new_custom(1000, 0.6, NULL, bm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = bm_new_custom(1000, 0.6, NULL, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); }); - CMC_CREATE_TEST(new_custom[insert remove], { - struct bidimap *map = - bm_new_custom(500, 0.6, bm_fkey, bm_fval, - &(struct cmc_alloc_node){ .malloc = malloc, - .calloc = calloc, - .realloc = realloc, - .free = free }, - &(struct cmc_callbacks){ 0 }); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 500; i++) - cmc_assert(bm_insert(map, i, i)); - - cmc_assert_equals(size_t, 500, bm_count(map)); - - for (size_t i = 0; i < 500; i++) - { - if (i % 2 == 0) - { - cmc_assert(bm_remove_by_key(map, i, NULL, NULL)); - } - else - { - cmc_assert(bm_remove_by_val(map, i, NULL, NULL)); - } - } - - cmc_assert_equals(size_t, 0, bm_count(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(clear[ftab free calls], { - struct bidimap *map = - bm_new(1000, 0.6, bm_fkey_counter, bm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - + CMC_CREATE_TEST(PFX##_clear(), { k_total_free = 0; v_total_free = 0; + struct bidimap *map = + bm_new(100, 0.6, bm_fkey_counter, bm_fval_counter); + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + bm_insert(map, i, i); + + cmc_assert_equals(size_t, 1000, map->count); + + map->flag = cmc_flags.ERROR; bm_clear(map); - cmc_assert_equals(int32_t, 0, k_total_free); - cmc_assert_equals(int32_t, 0, v_total_free); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); - for (size_t i = 0; i < 1000; i++) - cmc_assert(bm_insert(map, i, i)); + bm_free(map); + k_total_free = 0; + v_total_free = 0; + }); - bm_clear(map); + CMC_CREATE_TEST(PFX##_free(), { + k_total_free = 0; + v_total_free = 0; + struct bidimap *map = + bm_new(100, 0.6, bm_fkey_counter, bm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + bm_insert(map, i, i); + + cmc_assert_equals(size_t, 1000, map->count); + + bm_free(map); cmc_assert_equals(int32_t, 1000, k_total_free); cmc_assert_equals(int32_t, 1000, v_total_free); - bm_fval_counter->free = NULL; - - for (size_t i = 0; i < 1000; i++) - cmc_assert(bm_insert(map, i, i)); - - bm_clear(map); - - cmc_assert_equals(int32_t, 2000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - bm_fval_counter->free = v_c_free; - bm_fkey_counter->free = NULL; - - for (size_t i = 0; i < 1000; i++) - cmc_assert(bm_insert(map, i, i)); - - bm_clear(map); - - cmc_assert_equals(int32_t, 2000, k_total_free); - cmc_assert_equals(int32_t, 2000, v_total_free); - - bm_fkey_counter->free = k_c_free; - - bm_free(map); - - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(clear[count], { - struct bidimap *map = bm_new(100, 0.6, bm_fkey, bm_fval); + map = bm_new(1000, 0.6, bm_fkey_counter, bm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 500; i++) - cmc_assert(bm_insert(map, i, i)); - - cmc_assert_equals(size_t, 500, bm_count(map)); - - bm_clear(map); - - cmc_assert_equals(size_t, 0, bm_count(map)); + cmc_assert_not_equals(ptr, NULL, map->buffer); bm_free(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + k_total_free = 0; + v_total_free = 0; }); CMC_CREATE_TEST(customize, { diff --git a/tests/main/unt/deque.c b/tests/main/unt/deque.c index a804121..e960c0c 100644 --- a/tests/main/unt/deque.c +++ b/tests/main/unt/deque.c @@ -40,19 +40,13 @@ CMC_CREATE_UNIT(Deque, true, { d_free(d); d = d_new(0, d_fval); - cmc_assert_equals(ptr, NULL, d); d = d_new(1000, NULL); - cmc_assert_equals(ptr, NULL, d); d = d_new(UINT64_MAX, d_fval); - cmc_assert_equals(ptr, NULL, d); - - if (d) - d_free(d); }); CMC_CREATE_TEST(PFX##_new_custom(), { @@ -73,19 +67,13 @@ CMC_CREATE_UNIT(Deque, true, { d_free(d); d = d_new_custom(0, d_fval, d_alloc_node, callbacks); - cmc_assert_equals(ptr, NULL, d); d = d_new_custom(1000, NULL, d_alloc_node, callbacks); - cmc_assert_equals(ptr, NULL, d); d = d_new_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); - cmc_assert_equals(ptr, NULL, d); - - if (d) - d_free(d); }); CMC_CREATE_TEST(PFX##_init(), { @@ -244,7 +232,7 @@ CMC_CREATE_UNIT(Deque, true, { v_total_free = 0; }); - CMC_CREATE_TEST(PFX##_destroy(), { + CMC_CREATE_TEST(PFX##_release(), { v_total_free = 0; struct deque d = d_init(100, d_fval_counter); diff --git a/tests/main/unt/hashmap.c b/tests/main/unt/hashmap.c index 0cbfdbd..b26be10 100644 --- a/tests/main/unt/hashmap.c +++ b/tests/main/unt/hashmap.c @@ -18,45 +18,249 @@ struct hashmap_fval *hm_fval = &(struct hashmap_fval){ .cmp = cmc_size_cmp, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct hashmap_fkey *hm_fkey_counter = &(struct hashmap_fkey){ .cmp = k_c_cmp, + .cpy = k_c_cpy, + .str = k_c_str, + .free = k_c_free, + .hash = k_c_hash, + .pri = k_c_pri }; + +struct hashmap_fval *hm_fval_counter = &(struct hashmap_fval){ .cmp = v_c_cmp, + .cpy = v_c_cpy, + .str = v_c_str, + .free = v_c_free, + .hash = v_c_hash, + .pri = v_c_pri }; + +struct cmc_alloc_node *hm_alloc_node = &(struct cmc_alloc_node){ + .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +}; + CMC_CREATE_UNIT(HashMap, true, { - CMC_CREATE_TEST(new, { + CMC_CREATE_TEST(PFX##_new(), { struct hashmap *map = hm_new(943722, 0.6, hm_fkey, hm_fval); cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, hm_count(map)); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(double, 0.6, map->load); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(ptr, hm_fkey, map->f_key); + cmc_assert_equals(ptr, hm_fval, map->f_val); + cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, NULL, map->callbacks); + cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map)); hm_free(map); - }); - CMC_CREATE_TEST(new[capacity = 0], { - struct hashmap *map = hm_new(0, 0.6, hm_fkey, hm_fval); + map = hm_new(0, 0.6, hm_fkey, hm_fval); + cmc_assert_equals(ptr, NULL, map); + map = hm_new(UINT64_MAX, 0.99, hm_fkey, hm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = hm_new(1000, 0.6, hm_fkey, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hm_new(1000, 0.6, NULL, hm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = hm_new(1000, 0.6, NULL, NULL); cmc_assert_equals(ptr, NULL, map); }); - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct hashmap *map = hm_new(UINT64_MAX, 0.99, hm_fkey, hm_fval); + CMC_CREATE_TEST(PFX##_new_custom(), { + struct hashmap *map = hm_new_custom(943722, 0.6, hm_fkey, hm_fval, + hm_alloc_node, callbacks); + cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_not_equals(ptr, NULL, map->buffer); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(double, 0.6, map->load); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(ptr, hm_fkey, map->f_key); + cmc_assert_equals(ptr, hm_fval, map->f_val); + cmc_assert_equals(ptr, hm_alloc_node, map->alloc); + cmc_assert_equals(ptr, callbacks, map->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map)); + + hm_free(map); + + map = hm_new_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hm_new_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hm_new_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hm_new_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hm_new_custom(1000, 0.6, NULL, NULL, NULL, NULL); cmc_assert_equals(ptr, NULL, map); }); - CMC_CREATE_TEST(clear[count capacity], { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); + CMC_CREATE_TEST(PFX##_init(), { + struct hashmap map = hm_init(943722, 0.6, hm_fkey, hm_fval); + + cmc_assert_not_equals(ptr, NULL, map.buffer); + cmc_assert_equals(size_t, 0, map.count); + cmc_assert_equals(double, 0.6, map.load); + cmc_assert_equals(int32_t, cmc_flags.OK, map.flag); + cmc_assert_equals(ptr, hm_fkey, map.f_key); + cmc_assert_equals(ptr, hm_fval, map.f_val); + cmc_assert_equals(ptr, &cmc_alloc_node_default, map.alloc); + cmc_assert_equals(ptr, NULL, map.callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); + + hm_release(map); + + map = hm_init(0, 0.6, hm_fkey, hm_fval); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init(UINT64_MAX, 0.99, hm_fkey, hm_fval); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init(1000, 0.6, hm_fkey, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init(1000, 0.6, NULL, hm_fval); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init(1000, 0.6, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + }); + + CMC_CREATE_TEST(PFX##_init_custom(), { + struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, + hm_alloc_node, callbacks); + + cmc_assert_not_equals(ptr, NULL, map.buffer); + cmc_assert_equals(size_t, 0, map.count); + cmc_assert_equals(double, 0.6, map.load); + cmc_assert_equals(int32_t, cmc_flags.OK, map.flag); + cmc_assert_equals(ptr, hm_fkey, map.f_key); + cmc_assert_equals(ptr, hm_fval, map.f_val); + cmc_assert_equals(ptr, hm_alloc_node, map.alloc); + cmc_assert_equals(ptr, callbacks, map.callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); + + hm_release(map); + + map = hm_init_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + + map = hm_init_custom(1000, 0.6, NULL, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + }); + + CMC_CREATE_TEST(PFX##_clear(), { + k_total_free = 0; + v_total_free = 0; + struct hashmap *map = + hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); - for (size_t i = 0; i < 50; i++) + for (size_t i = 1; i <= 1000; i++) hm_insert(map, i, i); - cmc_assert_equals(size_t, 50, hm_count(map)); + cmc_assert_equals(size_t, 1000, map->count); + size_t *r = hm_get_ref(map, 100); + + cmc_assert_equals(size_t, 100, *r); + + map->flag = cmc_flags.ERROR; hm_clear(map); - cmc_assert_equals(size_t, 0, hm_count(map)); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + + // The buffer is still valid and all zeroes + cmc_assert_equals(size_t, 0, *r); hm_free(map); + k_total_free = 0; + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_free(), { + k_total_free = 0; + v_total_free = 0; + struct hashmap *map = + hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + hm_insert(map, i, i); + + cmc_assert_equals(size_t, 1000, map->count); + + hm_free(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + + map = hm_new(1000, 0.6, hm_fkey_counter, hm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_not_equals(ptr, NULL, map->buffer); + + hm_free(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + k_total_free = 0; + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_release(), { + k_total_free = 0; + v_total_free = 0; + struct hashmap map = + hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map.buffer); + + for (size_t i = 1; i <= 1000; i++) + hm_insert(&map, i, i); + + cmc_assert_equals(size_t, 1000, map.count); + + hm_release(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + + map = hm_init(1000, 0.6, hm_fkey_counter, hm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map.buffer); + + hm_release(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + k_total_free = 0; + v_total_free = 0; }); CMC_CREATE_TEST(insert, { diff --git a/tests/main/unt/hashset.c b/tests/main/unt/hashset.c index 91deffc..fbad417 100644 --- a/tests/main/unt/hashset.c +++ b/tests/main/unt/hashset.c @@ -11,45 +11,120 @@ struct hashset_fval *hs_fval = &(struct hashset_fval){ .cmp = cmc_size_cmp, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct hashset_fval *hs_fval_counter = &(struct hashset_fval){ .cmp = v_c_cmp, + .cpy = v_c_cpy, + .str = v_c_str, + .free = v_c_free, + .hash = v_c_hash, + .pri = v_c_pri }; + +struct cmc_alloc_node *hs_alloc_node = &(struct cmc_alloc_node){ + .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +}; + CMC_CREATE_UNIT(HashSet, true, { - CMC_CREATE_TEST(new, { + CMC_CREATE_TEST(PFX##_new(), { struct hashset *set = hs_new(943722, 0.6, hs_fval); cmc_assert_not_equals(ptr, NULL, set); cmc_assert_not_equals(ptr, NULL, set->buffer); - cmc_assert_equals(size_t, 0, hs_count(set)); + cmc_assert_equals(size_t, 0, set->count); + cmc_assert_equals(double, 0.6, set->load); + cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(ptr, hs_fval, set->f_val); + cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc); + cmc_assert_equals(ptr, NULL, set->callbacks); + cmc_assert_greater_equals(size_t, (943722 / 0.6), hs_capacity(set)); hs_free(set); - }); - CMC_CREATE_TEST(new[capacity = 0], { - struct hashset *set = hs_new(0, 0.6, hs_fval); + set = hs_new(0, 0.6, hs_fval); + cmc_assert_equals(ptr, NULL, set); + set = hs_new(UINT64_MAX, 0.99, hs_fval); + cmc_assert_equals(ptr, NULL, set); + + set = hs_new(1000, 0.6, NULL); + cmc_assert_equals(ptr, NULL, set); + + set = hs_new(1000, 0.6, NULL); cmc_assert_equals(ptr, NULL, set); }); - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct hashset *set = hs_new(UINT64_MAX, 0.99, hs_fval); + CMC_CREATE_TEST(PFX##_new_custom(), { + struct hashset *set = + hs_new_custom(943722, 0.6, hs_fval, hs_alloc_node, callbacks); + cmc_assert_not_equals(ptr, NULL, set); + cmc_assert_not_equals(ptr, NULL, set->buffer); + cmc_assert_equals(size_t, 0, set->count); + cmc_assert_equals(double, 0.6, set->load); + cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(ptr, hs_fval, set->f_val); + cmc_assert_equals(ptr, hs_alloc_node, set->alloc); + cmc_assert_equals(ptr, callbacks, set->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), hs_capacity(set)); + + hs_free(set); + + set = hs_new_custom(0, 0.6, hs_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, set); + + set = hs_new_custom(UINT64_MAX, 0.99, hs_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, set); + + set = hs_new_custom(1000, 0.6, NULL, NULL, NULL); cmc_assert_equals(ptr, NULL, set); }); - CMC_CREATE_TEST(clear[count capacity], { - struct hashset *set = hs_new(100, 0.6, hs_fval); + CMC_CREATE_TEST(PFX##_clear(), { + v_total_free = 0; + struct hashset *set = hs_new(100, 0.6, hs_fval_counter); cmc_assert_not_equals(ptr, NULL, set); - for (size_t i = 0; i < 50; i++) + for (size_t i = 1; i <= 1000; i++) hs_insert(set, i); - cmc_assert_equals(size_t, 50, hs_count(set)); + cmc_assert_equals(size_t, 1000, set->count); + set->flag = cmc_flags.ERROR; hs_clear(set); - cmc_assert_equals(size_t, 0, hs_count(set)); + cmc_assert_equals(size_t, 0, set->count); + cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, 1000, v_total_free); hs_free(set); + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_free(), { + v_total_free = 0; + struct hashset *set = hs_new(100, 0.6, hs_fval_counter); + + cmc_assert_not_equals(ptr, NULL, set); + + for (size_t i = 1; i <= 1000; i++) + hs_insert(set, i); + + cmc_assert_equals(size_t, 1000, set->count); + + hs_free(set); + + cmc_assert_equals(int32_t, 1000, v_total_free); + + set = hs_new(1000, 0.6, hs_fval_counter); + + cmc_assert_not_equals(ptr, NULL, set); + cmc_assert_not_equals(ptr, NULL, set->buffer); + + hs_free(set); + + cmc_assert_equals(int32_t, 1000, v_total_free); + v_total_free = 0; }); CMC_CREATE_TEST(insert, { diff --git a/tests/main/unt/multimap.c b/tests/main/unt/multimap.c index a83c34e..05be216 100644 --- a/tests/main/unt/multimap.c +++ b/tests/main/unt/multimap.c @@ -18,45 +18,161 @@ struct multimap_fval *mm_fval = &(struct multimap_fval){ .cmp = cmc_size_cmp, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct multimap_fkey *mm_fkey_counter = + &(struct multimap_fkey){ .cmp = k_c_cmp, + .cpy = k_c_cpy, + .str = k_c_str, + .free = k_c_free, + .hash = k_c_hash, + .pri = k_c_pri }; + +struct multimap_fval *mm_fval_counter = + &(struct multimap_fval){ .cmp = v_c_cmp, + .cpy = v_c_cpy, + .str = v_c_str, + .free = v_c_free, + .hash = v_c_hash, + .pri = v_c_pri }; + +struct cmc_alloc_node *mm_alloc_node = &(struct cmc_alloc_node){ + .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +}; + CMC_CREATE_UNIT(MultiMap, true, { - CMC_CREATE_TEST(new, { - struct multimap *map = mm_new(943722, 0.8, mm_fkey, mm_fval); + CMC_CREATE_TEST(PFX##_new(), { + struct multimap *map = mm_new(943722, 0.6, mm_fkey, mm_fval); cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, mm_count(map)); - cmc_assert_greater_equals(size_t, (943722 / 0.8), mm_capacity(map)); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(double, 0.6, map->load); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(ptr, mm_fkey, map->f_key); + cmc_assert_equals(ptr, mm_fval, map->f_val); + cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, NULL, map->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), mm_capacity(map)); mm_free(map); - }); - CMC_CREATE_TEST(new[capacity = 0], { - struct multimap *map = mm_new(0, 0.8, mm_fkey, mm_fval); - - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct multimap *map = mm_new(UINT64_MAX, 0.99, mm_fkey, mm_fval); - - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(clear[count capacity], { - struct multimap *map = mm_new(100, 0.8, mm_fkey, mm_fval); + map = mm_new(100, 0.6, mm_fkey, mm_fval); cmc_assert_not_equals(ptr, NULL, map); - for (size_t i = 0; i < 50; i++) - cmc_assert(mm_insert(map, i, i)); - - cmc_assert_equals(size_t, 50, mm_count(map)); - - mm_clear(map); - - cmc_assert_equals(size_t, 0, mm_count(map)); + for (size_t i = 0; i < map->capacity; i++) + { + cmc_assert_equals(ptr, NULL, map->buffer[i][0]); + cmc_assert_equals(ptr, NULL, map->buffer[i][1]); + } mm_free(map); + + map = mm_new(0, 0.6, mm_fkey, mm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new(UINT64_MAX, 0.99, mm_fkey, mm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new(1000, 0.6, mm_fkey, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new(1000, 0.6, NULL, mm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new(1000, 0.6, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + }); + + CMC_CREATE_TEST(PFX##_new_custom(), { + struct multimap *map = mm_new_custom(943722, 0.6, mm_fkey, mm_fval, + mm_alloc_node, callbacks); + + cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_not_equals(ptr, NULL, map->buffer); + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(double, 0.6, map->load); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(ptr, mm_fkey, map->f_key); + cmc_assert_equals(ptr, mm_fval, map->f_val); + cmc_assert_equals(ptr, mm_alloc_node, map->alloc); + cmc_assert_equals(ptr, callbacks, map->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), mm_capacity(map)); + + mm_free(map); + + map = mm_new_custom(0, 0.6, mm_fkey, mm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new_custom(UINT64_MAX, 0.99, mm_fkey, mm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new_custom(1000, 0.6, mm_fkey, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new_custom(1000, 0.6, NULL, mm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = mm_new_custom(1000, 0.6, NULL, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + }); + + CMC_CREATE_TEST(PFX##_clear(), { + k_total_free = 0; + v_total_free = 0; + struct multimap *map = + mm_new(100, 0.6, mm_fkey_counter, mm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + mm_insert(map, i, i); + + cmc_assert_equals(size_t, 1000, map->count); + + map->flag = cmc_flags.ERROR; + mm_clear(map); + + cmc_assert_equals(size_t, 0, map->count); + cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + + mm_free(map); + k_total_free = 0; + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_free(), { + k_total_free = 0; + v_total_free = 0; + struct multimap *map = + mm_new(100, 0.6, mm_fkey_counter, mm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + mm_insert(map, i, i); + + cmc_assert_equals(size_t, 1000, map->count); + + mm_free(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + + map = mm_new(1000, 0.6, mm_fkey_counter, mm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_not_equals(ptr, NULL, map->buffer); + + mm_free(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + k_total_free = 0; + v_total_free = 0; }); CMC_CREATE_TEST(insert[count], { diff --git a/tests/main/unt/multiset.c b/tests/main/unt/multiset.c index a4d55dd..5ff6900 100644 --- a/tests/main/unt/multiset.c +++ b/tests/main/unt/multiset.c @@ -11,46 +11,121 @@ struct multiset_fval *ms_fval = &(struct multiset_fval){ .cmp = cmc_size_cmp, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct multiset_fval *ms_fval_counter = + &(struct multiset_fval){ .cmp = v_c_cmp, + .cpy = v_c_cpy, + .str = v_c_str, + .free = v_c_free, + .hash = v_c_hash, + .pri = v_c_pri }; + +struct cmc_alloc_node *ms_alloc_node = &(struct cmc_alloc_node){ + .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +}; + CMC_CREATE_UNIT(MultiSet, true, { - CMC_CREATE_TEST(new, { + CMC_CREATE_TEST(PFX##_new(), { struct multiset *set = ms_new(943722, 0.6, ms_fval); cmc_assert_not_equals(ptr, NULL, set); cmc_assert_not_equals(ptr, NULL, set->buffer); - cmc_assert_equals(size_t, 0, ms_count(set)); - cmc_assert_greater_equals(size_t, ((size_t)(943722 / 0.6)), - ms_capacity(set)); + cmc_assert_equals(size_t, 0, set->count); + cmc_assert_equals(double, 0.6, set->load); + cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(ptr, ms_fval, set->f_val); + cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc); + cmc_assert_equals(ptr, NULL, set->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), ms_capacity(set)); ms_free(set); - }); - CMC_CREATE_TEST(new[capacity = 0], { - struct multiset *set = ms_new(0, 0.6, ms_fval); + set = ms_new(0, 0.6, ms_fval); + cmc_assert_equals(ptr, NULL, set); + set = ms_new(UINT64_MAX, 0.99, ms_fval); + cmc_assert_equals(ptr, NULL, set); + + set = ms_new(1000, 0.6, NULL); + cmc_assert_equals(ptr, NULL, set); + + set = ms_new(1000, 0.6, NULL); cmc_assert_equals(ptr, NULL, set); }); - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct multiset *set = ms_new(UINT64_MAX, 0.99, ms_fval); + CMC_CREATE_TEST(PFX##_new_custom(), { + struct multiset *set = + ms_new_custom(943722, 0.6, ms_fval, ms_alloc_node, callbacks); + cmc_assert_not_equals(ptr, NULL, set); + cmc_assert_not_equals(ptr, NULL, set->buffer); + cmc_assert_equals(size_t, 0, set->count); + cmc_assert_equals(double, 0.6, set->load); + cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(ptr, ms_fval, set->f_val); + cmc_assert_equals(ptr, ms_alloc_node, set->alloc); + cmc_assert_equals(ptr, callbacks, set->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), ms_capacity(set)); + + ms_free(set); + + set = ms_new_custom(0, 0.6, ms_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, set); + + set = ms_new_custom(UINT64_MAX, 0.99, ms_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, set); + + set = ms_new_custom(1000, 0.6, NULL, NULL, NULL); cmc_assert_equals(ptr, NULL, set); }); - CMC_CREATE_TEST(clear[count capacity], { - struct multiset *set = ms_new(100, 0.6, ms_fval); + CMC_CREATE_TEST(PFX##_clear(), { + v_total_free = 0; + struct multiset *set = ms_new(100, 0.6, ms_fval_counter); cmc_assert_not_equals(ptr, NULL, set); - for (size_t i = 0; i < 50; i++) - cmc_assert(ms_insert(set, i)); + for (size_t i = 1; i <= 1000; i++) + ms_insert(set, i); - cmc_assert_equals(size_t, 50, ms_count(set)); + cmc_assert_equals(size_t, 1000, set->count); + set->flag = cmc_flags.ERROR; ms_clear(set); - cmc_assert_equals(size_t, 0, ms_count(set)); + cmc_assert_equals(size_t, 0, set->count); + cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, 1000, v_total_free); ms_free(set); + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_free(), { + v_total_free = 0; + struct multiset *set = ms_new(100, 0.6, ms_fval_counter); + + cmc_assert_not_equals(ptr, NULL, set); + + for (size_t i = 1; i <= 1000; i++) + ms_insert(set, i); + + cmc_assert_equals(size_t, 1000, set->count); + + ms_free(set); + + cmc_assert_equals(int32_t, 1000, v_total_free); + + set = ms_new(1000, 0.6, ms_fval_counter); + + cmc_assert_not_equals(ptr, NULL, set); + cmc_assert_not_equals(ptr, NULL, set->buffer); + + ms_free(set); + + cmc_assert_equals(int32_t, 1000, v_total_free); + v_total_free = 0; }); CMC_CREATE_TEST(insert[count cardinality multiplicity], { diff --git a/tests/main/unt/utl.c b/tests/main/unt/utl.c index ab12991..84cc860 100644 --- a/tests/main/unt/utl.c +++ b/tests/main/unt/utl.c @@ -80,7 +80,7 @@ size_t k_c_hash(size_t x) int k_c_pri(size_t a, size_t b) { k_total_pri++; - return cmc_size_cmp(a, b); + return (a > b) - (a < b); } int v_c_cmp(size_t a, size_t b) @@ -118,7 +118,7 @@ size_t v_c_hash(size_t x) int v_c_pri(size_t a, size_t b) { v_total_pri++; - return cmc_size_cmp(a, b); + return (a > b) - (a < b); } // callbacks