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

+12 -1
View File
@@ -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}
''')
+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: \
+4
View File
@@ -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;
+65 -47
View File
@@ -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;
}
+1
View File
@@ -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)
+2
View File
@@ -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)
+1
View File
@@ -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)
+99 -98
View File
@@ -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, {
+1 -13
View File
@@ -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);
+216 -12
View File
@@ -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, {
+87 -12
View File
@@ -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, {
+143 -27
View File
@@ -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], {
+90 -15
View File
@@ -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], {
+2 -2
View File
@@ -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