diff --git a/autogen.py b/autogen.py index bb443cc..db4a10a 100644 --- a/autogen.py +++ b/autogen.py @@ -25,22 +25,22 @@ 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'}, - {'t': 'HEAP', 'h': '"cmc/heap.h"', 'pfx': 'h', 'sname': 'heap', 'key': '', 'val': 'size_t'}, - {'t': 'INTERVALHEAP', 'h': '"cmc/intervalheap.h"', 'pfx': 'ih', 'sname': 'intervalheap', 'key': '', 'val': 'size_t'}, - {'t': 'LINKEDLIST', 'h': '"cmc/linkedlist.h"', 'pfx': 'll', 'sname': 'linkedlist', 'key': '', 'val': 'size_t'}, - {'t': 'LIST', 'h': '"cmc/list.h"', 'pfx': 'l', 'sname': 'list', 'key': '', 'val': 'size_t'}, - {'t': 'MULTIMAP', 'h': '"cmc/multimap.h"', 'pfx': 'mm', 'sname': 'multimap', 'key': 'size_t', 'val': 'size_t'}, - {'t': 'MULTISET', 'h': '"cmc/multiset.h"', 'pfx': 'ms', 'sname': 'multiset', 'key': '', 'val': 'size_t'}, - {'t': 'QUEUE', 'h': '"cmc/queue.h"', 'pfx': 'q', 'sname': 'queue', 'key': '', 'val': 'size_t'}, - {'t': 'SORTEDLIST', 'h': '"cmc/sortedlist.h"', 'pfx': 'sl', 'sname': 'sortedlist', 'key': '', 'val': 'size_t'}, - {'t': 'STACK', 'h': '"cmc/stack.h"', 'pfx': 's', 'sname': 'stack', 'key': '', 'val': 'size_t'}, - {'t': 'TREEMAP', 'h': '"cmc/treemap.h"', 'pfx': 'tm', 'sname': 'treemap', 'key': 'size_t', 'val': 'size_t'}, - {'t': 'TREESET', 'h': '"cmc/treeset.h"', 'pfx': 'ts', 'sname': 'treeset', 'key': '', 'val': 'size_t'} + {'t': 'HASHBIDIMAP', 'h': '"cmc/hashbidimap.h"', 'pfx': 'hbm', 'sname': 'hashbidimap', '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'}, + {'t': 'HEAP', 'h': '"cmc/heap.h"', 'pfx': 'h', 'sname': 'heap', 'key': '', 'val': 'size_t'}, + {'t': 'INTERVALHEAP', 'h': '"cmc/intervalheap.h"', 'pfx': 'ih', 'sname': 'intervalheap', 'key': '', 'val': 'size_t'}, + {'t': 'LINKEDLIST', 'h': '"cmc/linkedlist.h"', 'pfx': 'll', 'sname': 'linkedlist', 'key': '', 'val': 'size_t'}, + {'t': 'LIST', 'h': '"cmc/list.h"', 'pfx': 'l', 'sname': 'list', 'key': '', 'val': 'size_t'}, + {'t': 'MULTIMAP', 'h': '"cmc/multimap.h"', 'pfx': 'mm', 'sname': 'multimap', 'key': 'size_t', 'val': 'size_t'}, + {'t': 'MULTISET', 'h': '"cmc/multiset.h"', 'pfx': 'ms', 'sname': 'multiset', 'key': '', 'val': 'size_t'}, + {'t': 'QUEUE', 'h': '"cmc/queue.h"', 'pfx': 'q', 'sname': 'queue', 'key': '', 'val': 'size_t'}, + {'t': 'SORTEDLIST', 'h': '"cmc/sortedlist.h"', 'pfx': 'sl', 'sname': 'sortedlist', 'key': '', 'val': 'size_t'}, + {'t': 'STACK', 'h': '"cmc/stack.h"', 'pfx': 's', 'sname': 'stack', 'key': '', 'val': 'size_t'}, + {'t': 'TREEMAP', 'h': '"cmc/treemap.h"', 'pfx': 'tm', 'sname': 'treemap', 'key': 'size_t', 'val': 'size_t'}, + {'t': 'TREESET', 'h': '"cmc/treeset.h"', 'pfx': 'ts', 'sname': 'treeset', 'key': '', 'val': 'size_t'} ] # Create output directory diff --git a/src/cmc/bidimap.h b/src/cmc/hashbidimap.h similarity index 98% rename from src/cmc/bidimap.h rename to src/cmc/hashbidimap.h index 1bf7e86..a0885e8 100644 --- a/src/cmc/bidimap.h +++ b/src/cmc/hashbidimap.h @@ -1,5 +1,5 @@ /** - * bidimap.h + * hashbidimap.h * * Creation Date: 26/09/2019 * @@ -9,7 +9,7 @@ */ /** - * BidiMap + * HashBidiMap * * A bidirectional map is a map that allows you to create a bijection in both * directions between two sets of elements (K <-> V). It is possible to retrieve @@ -23,8 +23,8 @@ * the key and the value. */ -#ifndef CMC_BIDIMAP_H -#define CMC_BIDIMAP_H +#ifndef CMC_HASHBIDIMAP_H +#define CMC_HASHBIDIMAP_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -37,37 +37,37 @@ #include "../cor/hashtable.h" /* ------------------------------------------------------------------------- - * Bidimap Specific + * HashBidimap Specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_BIDIMAP(PFX, SNAME, K, V) \ - CMC_GENERATE_BIDIMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_BIDIMAP_SOURCE(PFX, SNAME, K, V) +#define CMC_GENERATE_HASHBIDIMAP(PFX, SNAME, K, V) \ + CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \ + CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) -#define CMC_WRAPGEN_BIDIMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_BIDIMAP_HEADER(PFX, SNAME, K, V) +#define CMC_WRAPGEN_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \ + CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) -#define CMC_WRAPGEN_BIDIMAP_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_BIDIMAP_SOURCE(PFX, SNAME, K, V) +#define CMC_WRAPGEN_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) \ + CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_BIDIMAP_HEADER(PFX, SNAME, K, V) \ +#define CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \ \ - /* BidiMap Structure */ \ + /* HashBidiMap Structure */ \ struct SNAME \ { \ /* Array 0 is K -> V and array 1 is V -> K */ \ @@ -98,14 +98,14 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> " struct cmc_callbacks *callbacks; \ \ /* Methods */ \ - /* Function that returns an iterator to the start of the bidimap */ \ + /* Returns an iterator to the start of the hashbidimap */ \ struct SNAME##_iter (*it_start)(struct SNAME *); \ \ - /* Function that returns an iterator to the end of the bidimap */ \ + /* Returns an iterator to the end of the hashbidimap */ \ struct SNAME##_iter (*it_end)(struct SNAME *); \ }; \ \ - /* BidiMap Entry */ \ + /* HashBidiMap Entry */ \ struct SNAME##_entry \ { \ /* Entry Key */ \ @@ -119,7 +119,7 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> " /* dist[1] is relative to V -> K */ \ size_t dist[2]; \ \ - /* References to this node in the bidimap buffer. Used to */ \ + /* References to this node in the hashbidimap buffer. Used to */ \ /* prevent searching for this node twice for update() and */ \ /* remove(). Increases memory overhead but reduces execution time */ \ /* ref[0] is relative to K -> V */ \ @@ -171,10 +171,10 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> " int (*pri)(V, V); \ }; \ \ - /* BidiMap Iterator */ \ + /* HashBidiMap Iterator */ \ struct SNAME##_iter \ { \ - /* Target bidimap */ \ + /* Target hashbidimap */ \ struct SNAME *target; \ \ /* Cursor's position (index) */ \ @@ -262,7 +262,7 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> " /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_BIDIMAP_SOURCE(PFX, SNAME, K, V) \ +#define CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) \ \ /* Implementation Detail Functions */ \ static struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, \ @@ -973,7 +973,7 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> " struct cmc_string str; \ struct SNAME *m_ = _map_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_bidimap, \ + int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashbidimap, \ #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ m_->alloc, m_->callbacks); \ @@ -1439,4 +1439,4 @@ static const char *cmc_string_fmt_bidimap = "struct %s<%s, %s> " return iter; \ } -#endif /* CMC_BIDIMAP_H */ +#endif /* CMC_HASHBIDIMAP_H */ diff --git a/tests/main/main.c b/tests/main/main.c index c64cfe8..ea60aa5 100644 --- a/tests/main/main.c +++ b/tests/main/main.c @@ -1,6 +1,6 @@ #include "utl/timer.h" -#include "unt/bidimap.c" +#include "unt/hashbidimap.c" #include "unt/bitset.c" #include "unt/deque.c" #include "unt/hashmap.c" @@ -47,10 +47,10 @@ int main(void) cmc_timer_start(timer); uintmax_t tests = 0, units = 0; - cmc_run(BidiMap, units, tests); cmc_run(BitSet, units, tests); cmc_run(BitSetIter, units, tests); cmc_run(Deque, units, tests); + cmc_run(HashBidiMap, units, tests); cmc_run(DequeIter, units, tests); cmc_run(HashMap, units, tests); cmc_run(HashMapIter, units, tests); diff --git a/tests/main/src/bidimap.c b/tests/main/src/hashbidimap.c similarity index 54% rename from tests/main/src/bidimap.c rename to tests/main/src/hashbidimap.c index e3e9dc5..7caeb61 100644 --- a/tests/main/src/bidimap.c +++ b/tests/main/src/hashbidimap.c @@ -1,27 +1,27 @@ -#include "cmc/bidimap.h" +#include "cmc/hashbidimap.h" -struct bidimap +struct hashbidimap { - struct bidimap_entry *(*buffer)[2]; + struct hashbidimap_entry *(*buffer)[2]; size_t capacity; size_t count; double load; int flag; - struct bidimap_fkey *f_key; - struct bidimap_fval *f_val; + struct hashbidimap_fkey *f_key; + struct hashbidimap_fval *f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; - struct bidimap_iter (*it_start)(struct bidimap *); - struct bidimap_iter (*it_end)(struct bidimap *); + struct hashbidimap_iter (*it_start)(struct hashbidimap *); + struct hashbidimap_iter (*it_end)(struct hashbidimap *); }; -struct bidimap_entry +struct hashbidimap_entry { size_t key; size_t value; size_t dist[2]; - struct bidimap_entry **ref[2]; + struct hashbidimap_entry **ref[2]; }; -struct bidimap_fkey +struct hashbidimap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); @@ -30,7 +30,7 @@ struct bidimap_fkey size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct bidimap_fval +struct hashbidimap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); @@ -39,9 +39,9 @@ struct bidimap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct bidimap_iter +struct hashbidimap_iter { - struct bidimap *target; + struct hashbidimap *target; size_t cursor; size_t index; size_t first; @@ -49,69 +49,73 @@ struct bidimap_iter _Bool start; _Bool end; }; -struct bidimap *bm_new(size_t capacity, double load, struct bidimap_fkey *f_key, - struct bidimap_fval *f_val); -struct bidimap *bm_new_custom(size_t capacity, double load, - struct bidimap_fkey *f_key, - struct bidimap_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void bm_clear(struct bidimap *_map_); -void bm_free(struct bidimap *_map_); -void bm_customize(struct bidimap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -_Bool bm_insert(struct bidimap *_map_, size_t key, size_t value); -_Bool bm_update_key(struct bidimap *_map_, size_t val, size_t new_key); -_Bool bm_update_val(struct bidimap *_map_, size_t key, size_t new_val); -_Bool bm_remove_by_key(struct bidimap *_map_, size_t key, size_t *out_key, - size_t *out_val); -_Bool bm_remove_by_val(struct bidimap *_map_, size_t val, size_t *out_key, - size_t *out_val); -size_t bm_get_key(struct bidimap *_map_, size_t val); -size_t bm_get_val(struct bidimap *_map_, size_t key); -_Bool bm_contains_key(struct bidimap *_map_, size_t key); -_Bool bm_contains_val(struct bidimap *_map_, size_t val); -_Bool bm_empty(struct bidimap *_map_); -_Bool bm_full(struct bidimap *_map_); -size_t bm_count(struct bidimap *_map_); -size_t bm_capacity(struct bidimap *_map_); -double bm_load(struct bidimap *_map_); -int bm_flag(struct bidimap *_map_); -_Bool bm_resize(struct bidimap *_map_, size_t capacity); -struct bidimap *bm_copy_of(struct bidimap *_map_); -_Bool bm_equals(struct bidimap *_map1_, struct bidimap *_map2_); -struct cmc_string bm_to_string(struct bidimap *_map_); -_Bool bm_print(struct bidimap *_map_, FILE *fptr); -struct bidimap_iter *bm_iter_new(struct bidimap *target); -void bm_iter_free(struct bidimap_iter *iter); -void bm_iter_init(struct bidimap_iter *iter, struct bidimap *target); -_Bool bm_iter_start(struct bidimap_iter *iter); -_Bool bm_iter_end(struct bidimap_iter *iter); -void bm_iter_to_start(struct bidimap_iter *iter); -void bm_iter_to_end(struct bidimap_iter *iter); -_Bool bm_iter_next(struct bidimap_iter *iter); -_Bool bm_iter_prev(struct bidimap_iter *iter); -_Bool bm_iter_advance(struct bidimap_iter *iter, size_t steps); -_Bool bm_iter_rewind(struct bidimap_iter *iter, size_t steps); -_Bool bm_iter_go_to(struct bidimap_iter *iter, size_t index); -size_t bm_iter_key(struct bidimap_iter *iter); -size_t bm_iter_value(struct bidimap_iter *iter); -size_t bm_iter_index(struct bidimap_iter *iter); -static struct bidimap_entry *bm_impl_new_entry(struct bidimap *_map_, - size_t key, size_t value); -static struct bidimap_entry **bm_impl_get_entry_by_key(struct bidimap *_map_, - size_t key); -static struct bidimap_entry **bm_impl_get_entry_by_val(struct bidimap *_map_, - size_t val); -static struct bidimap_entry ** -bm_impl_add_entry_to_key(struct bidimap *_map_, struct bidimap_entry *entry); -static struct bidimap_entry ** -bm_impl_add_entry_to_val(struct bidimap *_map_, struct bidimap_entry *entry); -static size_t bm_impl_calculate_size(size_t required); -static struct bidimap_iter bm_impl_it_start(struct bidimap *_map_); -static struct bidimap_iter bm_impl_it_end(struct bidimap *_map_); -struct bidimap *bm_new(size_t capacity, double load, struct bidimap_fkey *f_key, - struct bidimap_fval *f_val) +struct hashbidimap *hbm_new(size_t capacity, double load, + struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val); +struct hashbidimap *hbm_new_custom(size_t capacity, double load, + struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val, + struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void hbm_clear(struct hashbidimap *_map_); +void hbm_free(struct hashbidimap *_map_); +void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value); +_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key); +_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val); +_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, + size_t *out_val); +_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, + size_t *out_val); +size_t hbm_get_key(struct hashbidimap *_map_, size_t val); +size_t hbm_get_val(struct hashbidimap *_map_, size_t key); +_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key); +_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val); +_Bool hbm_empty(struct hashbidimap *_map_); +_Bool hbm_full(struct hashbidimap *_map_); +size_t hbm_count(struct hashbidimap *_map_); +size_t hbm_capacity(struct hashbidimap *_map_); +double hbm_load(struct hashbidimap *_map_); +int hbm_flag(struct hashbidimap *_map_); +_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); +struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); +_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); +struct cmc_string hbm_to_string(struct hashbidimap *_map_); +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr); +struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); +void hbm_iter_free(struct hashbidimap_iter *iter); +void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); +_Bool hbm_iter_start(struct hashbidimap_iter *iter); +_Bool hbm_iter_end(struct hashbidimap_iter *iter); +void hbm_iter_to_start(struct hashbidimap_iter *iter); +void hbm_iter_to_end(struct hashbidimap_iter *iter); +_Bool hbm_iter_next(struct hashbidimap_iter *iter); +_Bool hbm_iter_prev(struct hashbidimap_iter *iter); +_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps); +_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps); +_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); +size_t hbm_iter_key(struct hashbidimap_iter *iter); +size_t hbm_iter_value(struct hashbidimap_iter *iter); +size_t hbm_iter_index(struct hashbidimap_iter *iter); +static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, + size_t key, size_t value); +static struct hashbidimap_entry ** +hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key); +static struct hashbidimap_entry ** +hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val); +static struct hashbidimap_entry ** +hbm_impl_add_entry_to_key(struct hashbidimap *_map_, + struct hashbidimap_entry *entry); +static struct hashbidimap_entry ** +hbm_impl_add_entry_to_val(struct hashbidimap *_map_, + struct hashbidimap_entry *entry); +static size_t hbm_impl_calculate_size(size_t required); +static struct hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_); +static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_); +struct hashbidimap *hbm_new(size_t capacity, double load, + struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity == 0 || load <= 0 || load >= 1) @@ -120,12 +124,12 @@ struct bidimap *bm_new(size_t capacity, double load, struct bidimap_fkey *f_key, return ((void *)0); if (!f_key || !f_val) return ((void *)0); - size_t real_capacity = bm_impl_calculate_size(capacity / load); - struct bidimap *_map_ = alloc->malloc(sizeof(struct bidimap)); + size_t real_capacity = hbm_impl_calculate_size(capacity / load); + struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); if (!_map_) return ((void *)0); _map_->buffer = - alloc->calloc(real_capacity, sizeof(struct bidimap_entry *[2])); + alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_->buffer); @@ -140,15 +144,15 @@ struct bidimap *bm_new(size_t capacity, double load, struct bidimap_fkey *f_key, _map_->f_val = f_val; _map_->alloc = alloc; _map_->callbacks = ((void *)0); - _map_->it_start = bm_impl_it_start; - _map_->it_end = bm_impl_it_end; + _map_->it_start = hbm_impl_it_start; + _map_->it_end = hbm_impl_it_end; return _map_; } -struct bidimap *bm_new_custom(size_t capacity, double load, - struct bidimap_fkey *f_key, - struct bidimap_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +struct hashbidimap *hbm_new_custom(size_t capacity, double load, + struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val, + struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) { if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); @@ -156,14 +160,14 @@ struct bidimap *bm_new_custom(size_t capacity, double load, return ((void *)0); if (!f_key || !f_val) return ((void *)0); - size_t real_capacity = bm_impl_calculate_size(capacity / load); + size_t real_capacity = hbm_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; - struct bidimap *_map_ = alloc->malloc(sizeof(struct bidimap)); + struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); if (!_map_) return ((void *)0); _map_->buffer = - alloc->calloc(real_capacity, sizeof(struct bidimap_entry *[2])); + alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_->buffer); @@ -179,15 +183,15 @@ struct bidimap *bm_new_custom(size_t capacity, double load, _map_->flag = cmc_flags.OK; _map_->alloc = alloc; _map_->callbacks = callbacks; - _map_->it_start = bm_impl_it_start; - _map_->it_end = bm_impl_it_end; + _map_->it_start = hbm_impl_it_start; + _map_->it_end = hbm_impl_it_end; return _map_; } -void bm_clear(struct bidimap *_map_) +void hbm_clear(struct hashbidimap *_map_) { for (size_t i = 0; i < _map_->capacity; i++) { - struct bidimap_entry *entry = _map_->buffer[i][0]; + struct hashbidimap_entry *entry = _map_->buffer[i][0]; if (entry && entry != ((void *)1)) { if (_map_->f_key->free) @@ -202,14 +206,14 @@ void bm_clear(struct bidimap *_map_) _map_->count = 0; _map_->flag = cmc_flags.OK; } -void bm_free(struct bidimap *_map_) +void hbm_free(struct hashbidimap *_map_) { - bm_clear(_map_); + hbm_clear(_map_); _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } -void bm_customize(struct bidimap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) { if (!alloc) _map_->alloc = &cmc_alloc_node_default; @@ -218,22 +222,24 @@ void bm_customize(struct bidimap *_map_, struct cmc_alloc_node *alloc, _map_->callbacks = callbacks; _map_->flag = cmc_flags.OK; } -_Bool bm_insert(struct bidimap *_map_, size_t key, size_t value) +_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) { - if (bm_full(_map_)) + if (hbm_full(_map_)) { - if (!bm_resize(_map_, _map_->capacity + 1)) + if (!hbm_resize(_map_, _map_->capacity + 1)) return 0; } - if (bm_impl_get_entry_by_key(_map_, key) != ((void *)0) || - bm_impl_get_entry_by_val(_map_, value) != ((void *)0)) + if (hbm_impl_get_entry_by_key(_map_, key) != ((void *)0) || + hbm_impl_get_entry_by_val(_map_, value) != ((void *)0)) { _map_->flag = cmc_flags.DUPLICATE; return 0; } - struct bidimap_entry *entry = bm_impl_new_entry(_map_, key, value); - struct bidimap_entry **key_entry = bm_impl_add_entry_to_key(_map_, entry); - struct bidimap_entry **val_entry = bm_impl_add_entry_to_val(_map_, entry); + struct hashbidimap_entry *entry = hbm_impl_new_entry(_map_, key, value); + struct hashbidimap_entry **key_entry = + hbm_impl_add_entry_to_key(_map_, entry); + struct hashbidimap_entry **val_entry = + hbm_impl_add_entry_to_val(_map_, entry); if (!key_entry || !val_entry) { if (key_entry) @@ -250,15 +256,15 @@ _Bool bm_insert(struct bidimap *_map_, size_t key, size_t value) _map_->callbacks->create(); return 1; } -_Bool bm_update_key(struct bidimap *_map_, size_t val, size_t new_key) +_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) { - if (bm_empty(_map_)) + if (hbm_empty(_map_)) { _map_->flag = cmc_flags.EMPTY; return 0; } - struct bidimap_entry **key_entry, **val_entry; - val_entry = bm_impl_get_entry_by_val(_map_, val); + struct hashbidimap_entry **key_entry, **val_entry; + val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { _map_->flag = cmc_flags.NOT_FOUND; @@ -266,7 +272,7 @@ _Bool bm_update_key(struct bidimap *_map_, size_t val, size_t new_key) } if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) goto success; - if (bm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) + if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) { _map_->flag = cmc_flags.DUPLICATE; return 0; @@ -277,11 +283,11 @@ _Bool bm_update_key(struct bidimap *_map_, size_t val, size_t new_key) _map_->flag = cmc_flags.ERROR; return 0; } - struct bidimap_entry *to_add = *key_entry; + struct hashbidimap_entry *to_add = *key_entry; size_t tmp_key = to_add->key; to_add->key = new_key; *key_entry = ((void *)1); - if (!bm_impl_add_entry_to_key(_map_, to_add)) + if (!hbm_impl_add_entry_to_key(_map_, to_add)) { to_add->key = tmp_key; *key_entry = to_add; @@ -294,15 +300,15 @@ success: _map_->callbacks->update(); return 1; } -_Bool bm_update_val(struct bidimap *_map_, size_t key, size_t new_val) +_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) { - if (bm_empty(_map_)) + if (hbm_empty(_map_)) { _map_->flag = cmc_flags.EMPTY; return 0; } - struct bidimap_entry **key_entry, **val_entry; - key_entry = bm_impl_get_entry_by_key(_map_, key); + struct hashbidimap_entry **key_entry, **val_entry; + key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { _map_->flag = cmc_flags.NOT_FOUND; @@ -310,7 +316,7 @@ _Bool bm_update_val(struct bidimap *_map_, size_t key, size_t new_val) } if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) goto success; - if (bm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) + if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) { _map_->flag = cmc_flags.DUPLICATE; return 0; @@ -321,11 +327,11 @@ _Bool bm_update_val(struct bidimap *_map_, size_t key, size_t new_val) _map_->flag = cmc_flags.ERROR; return 0; } - struct bidimap_entry *to_add = *val_entry; + struct hashbidimap_entry *to_add = *val_entry; size_t tmp_val = to_add->value; to_add->value = new_val; *val_entry = ((void *)1); - if (!bm_impl_add_entry_to_val(_map_, to_add)) + if (!hbm_impl_add_entry_to_val(_map_, to_add)) { to_add->value = tmp_val; *val_entry = to_add; @@ -338,16 +344,16 @@ success: _map_->callbacks->update(); return 1; } -_Bool bm_remove_by_key(struct bidimap *_map_, size_t key, size_t *out_key, - size_t *out_val) +_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, + size_t *out_val) { - if (bm_empty(_map_)) + if (hbm_empty(_map_)) { _map_->flag = cmc_flags.EMPTY; return 0; } - struct bidimap_entry **key_entry, **val_entry; - key_entry = bm_impl_get_entry_by_key(_map_, key); + struct hashbidimap_entry **key_entry, **val_entry; + key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { _map_->flag = cmc_flags.NOT_FOUND; @@ -372,16 +378,16 @@ _Bool bm_remove_by_key(struct bidimap *_map_, size_t key, size_t *out_key, _map_->callbacks->delete (); return 1; } -_Bool bm_remove_by_val(struct bidimap *_map_, size_t val, size_t *out_key, - size_t *out_val) +_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, + size_t *out_val) { - if (bm_empty(_map_)) + if (hbm_empty(_map_)) { _map_->flag = cmc_flags.EMPTY; return 0; } - struct bidimap_entry **key_entry, **val_entry; - val_entry = bm_impl_get_entry_by_val(_map_, val); + struct hashbidimap_entry **key_entry, **val_entry; + val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { _map_->flag = cmc_flags.NOT_FOUND; @@ -406,9 +412,9 @@ _Bool bm_remove_by_val(struct bidimap *_map_, size_t val, size_t *out_key, _map_->callbacks->delete (); return 1; } -size_t bm_get_key(struct bidimap *_map_, size_t val) +size_t hbm_get_key(struct hashbidimap *_map_, size_t val) { - struct bidimap_entry **entry = bm_impl_get_entry_by_val(_map_, val); + struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val); if (!entry) { _map_->flag = cmc_flags.NOT_FOUND; @@ -419,9 +425,9 @@ size_t bm_get_key(struct bidimap *_map_, size_t val) _map_->callbacks->read(); return (*entry)->key; } -size_t bm_get_val(struct bidimap *_map_, size_t key) +size_t hbm_get_val(struct hashbidimap *_map_, size_t key) { - struct bidimap_entry **entry = bm_impl_get_entry_by_key(_map_, key); + struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key); if (!entry) { _map_->flag = cmc_flags.NOT_FOUND; @@ -432,47 +438,47 @@ size_t bm_get_val(struct bidimap *_map_, size_t key) _map_->callbacks->read(); return (*entry)->value; } -_Bool bm_contains_key(struct bidimap *_map_, size_t key) +_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) { _map_->flag = cmc_flags.OK; - _Bool result = bm_impl_get_entry_by_key(_map_, key) != ((void *)0); + _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return result; } -_Bool bm_contains_val(struct bidimap *_map_, size_t val) +_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val) { _map_->flag = cmc_flags.OK; - _Bool result = bm_impl_get_entry_by_val(_map_, val) != ((void *)0); + _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return result; } -_Bool bm_empty(struct bidimap *_map_) +_Bool hbm_empty(struct hashbidimap *_map_) { return _map_->count == 0; } -_Bool bm_full(struct bidimap *_map_) +_Bool hbm_full(struct hashbidimap *_map_) { return (double)_map_->capacity * _map_->load <= (double)_map_->count; } -size_t bm_count(struct bidimap *_map_) +size_t hbm_count(struct hashbidimap *_map_) { return _map_->count; } -size_t bm_capacity(struct bidimap *_map_) +size_t hbm_capacity(struct hashbidimap *_map_) { return _map_->capacity; } -double bm_load(struct bidimap *_map_) +double hbm_load(struct hashbidimap *_map_) { return _map_->load; } -int bm_flag(struct bidimap *_map_) +int hbm_flag(struct hashbidimap *_map_) { return _map_->flag; } -_Bool bm_resize(struct bidimap *_map_, size_t capacity) +_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) { _map_->flag = cmc_flags.OK; if (_map_->capacity == capacity) @@ -484,15 +490,15 @@ _Bool bm_resize(struct bidimap *_map_, size_t capacity) _map_->flag = cmc_flags.ERROR; return 0; } - size_t new_cap = bm_impl_calculate_size(capacity); + size_t new_cap = hbm_impl_calculate_size(capacity); if (new_cap < _map_->count / _map_->load) { _map_->flag = cmc_flags.INVALID; return 0; } - struct bidimap *_new_map_ = - bm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); + struct hashbidimap *_new_map_ = + hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, + _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = cmc_flags.ALLOC; @@ -500,17 +506,17 @@ _Bool bm_resize(struct bidimap *_map_, size_t capacity) } for (size_t i = 0; i < _map_->capacity; i++) { - struct bidimap_entry *scan = _map_->buffer[i][0]; + struct hashbidimap_entry *scan = _map_->buffer[i][0]; if (scan && scan != ((void *)1)) { - struct bidimap_entry **e1 = - bm_impl_add_entry_to_key(_new_map_, scan); - struct bidimap_entry **e2 = - bm_impl_add_entry_to_val(_new_map_, scan); + struct hashbidimap_entry **e1 = + hbm_impl_add_entry_to_key(_new_map_, scan); + struct hashbidimap_entry **e2 = + hbm_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) }; + _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = cmc_flags.ERROR; @@ -521,14 +527,14 @@ _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) }; + _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = cmc_flags.ERROR; return 0; } - struct bidimap_entry *(*tmp_buff)[2] = _map_->buffer; + struct hashbidimap_entry *(*tmp_buff)[2] = _map_->buffer; _map_->buffer = _new_map_->buffer; _map_->capacity = _new_map_->capacity; _map_->alloc->free(tmp_buff); @@ -538,11 +544,11 @@ success: _map_->callbacks->resize(); return 1; } -struct bidimap *bm_copy_of(struct bidimap *_map_) +struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) { - struct bidimap *result = - bm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, - _map_->f_val, _map_->alloc, _map_->callbacks); + struct hashbidimap *result = + hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, + _map_->f_val, _map_->alloc, _map_->callbacks); if (!result) { _map_->flag = cmc_flags.ERROR; @@ -550,7 +556,7 @@ struct bidimap *bm_copy_of(struct bidimap *_map_) } for (size_t i = 0; i < _map_->capacity; i++) { - struct bidimap_entry *scan = _map_->buffer[i][0]; + struct hashbidimap_entry *scan = _map_->buffer[i][0]; if (scan && scan != ((void *)1)) { size_t tmp_key; @@ -563,24 +569,24 @@ struct bidimap *bm_copy_of(struct bidimap *_map_) tmp_val = _map_->f_val->cpy(scan->value); else tmp_val = scan->value; - struct bidimap_entry *entry = - bm_impl_new_entry(result, tmp_key, tmp_val); - bm_impl_add_entry_to_key(result, entry); - bm_impl_add_entry_to_val(result, entry); + struct hashbidimap_entry *entry = + hbm_impl_new_entry(result, tmp_key, tmp_val); + hbm_impl_add_entry_to_key(result, entry); + hbm_impl_add_entry_to_val(result, entry); result->count++; } } _map_->flag = cmc_flags.OK; return result; } -_Bool bm_equals(struct bidimap *_map1_, struct bidimap *_map2_) +_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_) { _map1_->flag = cmc_flags.OK; _map2_->flag = cmc_flags.OK; if (_map1_->count != _map2_->count) return 0; - struct bidimap *_mapA_; - struct bidimap *_mapB_; + struct hashbidimap *_mapA_; + struct hashbidimap *_mapB_; if (_map1_->capacity < _map2_->capacity) { _mapA_ = _map1_; @@ -593,11 +599,11 @@ _Bool bm_equals(struct bidimap *_map1_, struct bidimap *_map2_) } for (size_t i = 0; i < _mapA_->capacity; i++) { - struct bidimap_entry *scan = _mapA_->buffer[i][0]; + struct hashbidimap_entry *scan = _mapA_->buffer[i][0]; if (scan && scan != ((void *)1)) { - struct bidimap_entry **entry_B = - bm_impl_get_entry_by_key(_mapB_, scan->key); + struct hashbidimap_entry **entry_B = + hbm_impl_get_entry_by_key(_mapB_, scan->key); if (!entry_B) return 0; if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) @@ -606,21 +612,21 @@ _Bool bm_equals(struct bidimap *_map1_, struct bidimap *_map2_) } return 1; } -struct cmc_string bm_to_string(struct bidimap *_map_) +struct cmc_string hbm_to_string(struct hashbidimap *_map_) { struct cmc_string str; - struct bidimap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_bidimap, "bidimap", - "size_t", "size_t", m_, m_->buffer, m_->capacity, - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, - m_->alloc, m_->callbacks); + struct hashbidimap *m_ = _map_; + int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashbidimap, + "hashbidimap", "size_t", "size_t", m_, m_->buffer, + m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, + m_->f_val, m_->alloc, m_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } -_Bool bm_print(struct bidimap *_map_, FILE *fptr) +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr) { for (size_t i = 0; i < _map_->capacity; i++) { - struct bidimap_entry *target = _map_->buffer[i][0]; + struct hashbidimap_entry *target = _map_->buffer[i][0]; if (target && target != ((void *)1)) { if (!_map_->f_key->str(fptr, target->key) || @@ -630,30 +636,30 @@ _Bool bm_print(struct bidimap *_map_, FILE *fptr) } return 1; } -struct bidimap_iter *bm_iter_new(struct bidimap *target) +struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target) { - struct bidimap_iter *iter = - target->alloc->malloc(sizeof(struct bidimap_iter)); + struct hashbidimap_iter *iter = + target->alloc->malloc(sizeof(struct hashbidimap_iter)); if (!iter) return ((void *)0); - bm_iter_init(iter, target); + hbm_iter_init(iter, target); return iter; } -void bm_iter_free(struct bidimap_iter *iter) +void hbm_iter_free(struct hashbidimap_iter *iter) { iter->target->alloc->free(iter); } -void bm_iter_init(struct bidimap_iter *iter, struct bidimap *target) +void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) { - memset(iter, 0, sizeof(struct bidimap_iter)); + memset(iter, 0, sizeof(struct hashbidimap_iter)); iter->target = target; iter->start = 1; - iter->end = bm_empty(target); - if (!bm_empty(target)) + iter->end = hbm_empty(target); + if (!hbm_empty(target)) { for (size_t i = 0; i < target->capacity; i++) { - struct bidimap_entry *tmp = target->buffer[i][0]; + struct hashbidimap_entry *tmp = target->buffer[i][0]; if (tmp != ((void *)0) && tmp != ((void *)1)) { iter->first = i; @@ -663,7 +669,7 @@ void bm_iter_init(struct bidimap_iter *iter, struct bidimap *target) iter->cursor = iter->first; for (size_t i = target->capacity; i > 0; i--) { - struct bidimap_entry *tmp = target->buffer[i - 1][0]; + struct hashbidimap_entry *tmp = target->buffer[i - 1][0]; if (tmp != ((void *)0) && tmp != ((void *)1)) { iter->last = i - 1; @@ -672,17 +678,17 @@ void bm_iter_init(struct bidimap_iter *iter, struct bidimap *target) } } } -_Bool bm_iter_start(struct bidimap_iter *iter) +_Bool hbm_iter_start(struct hashbidimap_iter *iter) { - return bm_empty(iter->target) || iter->start; + return hbm_empty(iter->target) || iter->start; } -_Bool bm_iter_end(struct bidimap_iter *iter) +_Bool hbm_iter_end(struct hashbidimap_iter *iter) { - return bm_empty(iter->target) || iter->end; + return hbm_empty(iter->target) || iter->end; } -void bm_iter_to_start(struct bidimap_iter *iter) +void hbm_iter_to_start(struct hashbidimap_iter *iter) { - if (!bm_empty(iter->target)) + if (!hbm_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; @@ -690,9 +696,9 @@ void bm_iter_to_start(struct bidimap_iter *iter) iter->end = 0; } } -void bm_iter_to_end(struct bidimap_iter *iter) +void hbm_iter_to_end(struct hashbidimap_iter *iter) { - if (!bm_empty(iter->target)) + if (!hbm_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; @@ -700,7 +706,7 @@ void bm_iter_to_end(struct bidimap_iter *iter) iter->end = 1; } } -_Bool bm_iter_next(struct bidimap_iter *iter) +_Bool hbm_iter_next(struct hashbidimap_iter *iter) { if (iter->end) return 0; @@ -709,8 +715,8 @@ _Bool bm_iter_next(struct bidimap_iter *iter) iter->end = 1; return 0; } - iter->start = bm_empty(iter->target); - struct bidimap_entry *scan = iter->target->buffer[iter->cursor][0]; + iter->start = hbm_empty(iter->target); + struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; iter->index++; while (1) { @@ -721,7 +727,7 @@ _Bool bm_iter_next(struct bidimap_iter *iter) } return 1; } -_Bool bm_iter_prev(struct bidimap_iter *iter) +_Bool hbm_iter_prev(struct hashbidimap_iter *iter) { if (iter->start) return 0; @@ -730,8 +736,8 @@ _Bool bm_iter_prev(struct bidimap_iter *iter) iter->start = 1; return 0; } - iter->end = bm_empty(iter->target); - struct bidimap_entry *scan = iter->target->buffer[iter->cursor][0]; + iter->end = hbm_empty(iter->target); + struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; iter->index--; while (1) { @@ -742,7 +748,7 @@ _Bool bm_iter_prev(struct bidimap_iter *iter) } return 1; } -_Bool bm_iter_advance(struct bidimap_iter *iter, size_t steps) +_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps) { if (iter->end) return 0; @@ -754,10 +760,10 @@ _Bool bm_iter_advance(struct bidimap_iter *iter, size_t steps) if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) - bm_iter_next(iter); + hbm_iter_next(iter); return 1; } -_Bool bm_iter_rewind(struct bidimap_iter *iter, size_t steps) +_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps) { if (iter->start) return 0; @@ -769,46 +775,46 @@ _Bool bm_iter_rewind(struct bidimap_iter *iter, size_t steps) if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) - bm_iter_prev(iter); + hbm_iter_prev(iter); return 1; } -_Bool bm_iter_go_to(struct bidimap_iter *iter, size_t index) +_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) - return bm_iter_rewind(iter, iter->index - index); + return hbm_iter_rewind(iter, iter->index - index); else if (iter->index < index) - return bm_iter_advance(iter, index - iter->index); + return hbm_iter_advance(iter, index - iter->index); return 1; } -size_t bm_iter_key(struct bidimap_iter *iter) +size_t hbm_iter_key(struct hashbidimap_iter *iter) { - if (bm_empty(iter->target)) + if (hbm_empty(iter->target)) { iter->target->flag = cmc_flags.EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->key; } -size_t bm_iter_value(struct bidimap_iter *iter) +size_t hbm_iter_value(struct hashbidimap_iter *iter) { - if (bm_empty(iter->target)) + if (hbm_empty(iter->target)) { iter->target->flag = cmc_flags.EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->value; } -size_t bm_iter_index(struct bidimap_iter *iter) +size_t hbm_iter_index(struct hashbidimap_iter *iter) { return iter->index; } -static struct bidimap_entry *bm_impl_new_entry(struct bidimap *_map_, - size_t key, size_t value) +static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, + size_t key, size_t value) { - struct bidimap_entry *entry = - _map_->alloc->malloc(sizeof(struct bidimap_entry)); + struct hashbidimap_entry *entry = + _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); if (!entry) return ((void *)0); entry->key = key; @@ -819,12 +825,12 @@ static struct bidimap_entry *bm_impl_new_entry(struct bidimap *_map_, entry->ref[1] = ((void *)0); return entry; } -static struct bidimap_entry **bm_impl_get_entry_by_key(struct bidimap *_map_, - size_t key) +static struct hashbidimap_entry ** +hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key) { size_t hash = _map_->f_key->hash(key); size_t pos = hash % _map_->capacity; - struct bidimap_entry *target = _map_->buffer[pos][0]; + struct hashbidimap_entry *target = _map_->buffer[pos][0]; while (target != ((void *)0)) { if (target != ((void *)1) && _map_->f_key->cmp(target->key, key) == 0) @@ -834,12 +840,12 @@ static struct bidimap_entry **bm_impl_get_entry_by_key(struct bidimap *_map_, } return ((void *)0); } -static struct bidimap_entry **bm_impl_get_entry_by_val(struct bidimap *_map_, - size_t val) +static struct hashbidimap_entry ** +hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val) { size_t hash = _map_->f_val->hash(val); size_t pos = hash % _map_->capacity; - struct bidimap_entry *target = _map_->buffer[pos][1]; + struct hashbidimap_entry *target = _map_->buffer[pos][1]; while (target != ((void *)0)) { if (target != ((void *)1) && _map_->f_val->cmp(target->value, val) == 0) @@ -849,14 +855,16 @@ static struct bidimap_entry **bm_impl_get_entry_by_val(struct bidimap *_map_, } return ((void *)0); } -static struct bidimap_entry ** -bm_impl_add_entry_to_key(struct bidimap *_map_, struct bidimap_entry *entry) +static struct hashbidimap_entry ** +hbm_impl_add_entry_to_key(struct hashbidimap *_map_, + struct hashbidimap_entry *entry) { - struct bidimap_entry **to_return = ((void *)0); + struct hashbidimap_entry **to_return = ((void *)0); size_t hash = _map_->f_key->hash(entry->key); size_t original_pos = hash % _map_->capacity; size_t pos = original_pos; - struct bidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][0]); + struct hashbidimap_entry **scan = + &(_map_->buffer[hash % _map_->capacity][0]); if (*scan == ((void *)0)) { *scan = entry; @@ -886,7 +894,7 @@ bm_impl_add_entry_to_key(struct bidimap *_map_, struct bidimap_entry *entry) entry->dist[0] = pos - original_pos; original_pos = pos - tmp_dist; entry->ref[0] = scan; - struct bidimap_entry *_tmp_ = *scan; + struct hashbidimap_entry *_tmp_ = *scan; *scan = entry; entry = _tmp_; } @@ -894,14 +902,16 @@ bm_impl_add_entry_to_key(struct bidimap *_map_, struct bidimap_entry *entry) } return ((void *)0); } -static struct bidimap_entry ** -bm_impl_add_entry_to_val(struct bidimap *_map_, struct bidimap_entry *entry) +static struct hashbidimap_entry ** +hbm_impl_add_entry_to_val(struct hashbidimap *_map_, + struct hashbidimap_entry *entry) { - struct bidimap_entry **to_return = ((void *)0); + struct hashbidimap_entry **to_return = ((void *)0); size_t hash = _map_->f_val->hash(entry->value); size_t original_pos = hash % _map_->capacity; size_t pos = original_pos; - struct bidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][1]); + struct hashbidimap_entry **scan = + &(_map_->buffer[hash % _map_->capacity][1]); if (*scan == ((void *)0)) { *scan = entry; @@ -931,7 +941,7 @@ bm_impl_add_entry_to_val(struct bidimap *_map_, struct bidimap_entry *entry) entry->dist[1] = pos - original_pos; original_pos = pos - tmp_dist; entry->ref[1] = scan; - struct bidimap_entry *_tmp_ = *scan; + struct hashbidimap_entry *_tmp_ = *scan; *scan = entry; entry = _tmp_; } @@ -939,7 +949,7 @@ bm_impl_add_entry_to_val(struct bidimap *_map_, struct bidimap_entry *entry) } return ((void *)0); } -static size_t bm_impl_calculate_size(size_t required) +static size_t hbm_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); @@ -950,16 +960,16 @@ static size_t bm_impl_calculate_size(size_t required) i++; return cmc_hashtable_primes[i]; } -static struct bidimap_iter bm_impl_it_start(struct bidimap *_map_) +static struct hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_) { - struct bidimap_iter iter; - bm_iter_init(&iter, _map_); + struct hashbidimap_iter iter; + hbm_iter_init(&iter, _map_); return iter; } -static struct bidimap_iter bm_impl_it_end(struct bidimap *_map_) +static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_) { - struct bidimap_iter iter; - bm_iter_init(&iter, _map_); - bm_iter_to_end(&iter); + struct hashbidimap_iter iter; + hbm_iter_init(&iter, _map_); + hbm_iter_to_end(&iter); return iter; } diff --git a/tests/main/unt/bidimap.c b/tests/main/unt/bidimap.c deleted file mode 100644 index f00ed8a..0000000 --- a/tests/main/unt/bidimap.c +++ /dev/null @@ -1,822 +0,0 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" - -#include "../src/bidimap.c" - -struct bidimap_fkey *bm_fkey = &(struct bidimap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct bidimap_fval *bm_fval = &(struct bidimap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct bidimap_fkey *bm_fkey_counter = &(struct bidimap_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 bidimap_fval *bm_fval_counter = &(struct bidimap_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 *bm_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free -}; - -CMC_CREATE_UNIT(BidiMap, true, { - 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); - - map = bm_new(100, 0.6, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, 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]); - } - - 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(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(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(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); - - bm_free(map); - k_total_free = 0; - v_total_free = 0; - }); - - 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); - - map = bm_new(1000, 0.6, bm_fkey_counter, bm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, 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, { - struct bidimap *map = - bm_new_custom(100, 0.6, bm_fkey, bm_fval, NULL, NULL); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); - cmc_assert_equals(ptr, NULL, map->callbacks); - - bm_free(map); - - struct cmc_alloc_node node; - node.malloc = malloc; - node.realloc = realloc; - node.free = free; - node.calloc = calloc; - - map = bm_new_custom(100, 0.6, bm_fkey, bm_fval, &node, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(ptr, &node, map->alloc); - cmc_assert_equals(ptr, callbacks, map->callbacks); - - bm_free(map); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct bidimap *map = bm_new(1, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 10000; i++) - cmc_assert(bm_insert(map, i, i)); - - size_t sum = 0; - - for (size_t i = 0; i < bm_capacity(map); i++) - { - if (map->buffer[i][0] && map->buffer[i][0] != CMC_ENTRY_DELETED) - { - sum += map->buffer[i][0]->key; - } - } - - cmc_assert_equals(size_t, 50005000, sum); - - bm_free(map); - }); - - CMC_CREATE_TEST(insert, { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(bm_insert(map, 1, 1)); - cmc_assert(bm_insert(map, 2, 2)); - cmc_assert(bm_insert(map, 3, 3)); - - cmc_assert_equals(size_t, 3, bm_count(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(insert[duplicate], { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(bm_insert(map, 1, 1)); - cmc_assert(!bm_insert(map, 1, 1)); - cmc_assert(!bm_insert(map, 2, 1)); - cmc_assert(!bm_insert(map, 1, 2)); - cmc_assert(bm_insert(map, 2, 2)); - - cmc_assert_equals(size_t, 2, bm_count(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(insert[references], { - struct bidimap *map = bm_new(500, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 500; i++) - cmc_assert(bm_insert(map, i, i)); - - for (size_t i = 0; i < map->capacity; i++) - { - struct bidimap_entry *kentry = map->buffer[i][0]; - struct bidimap_entry *ventry = map->buffer[i][1]; - - if (kentry && kentry != CMC_ENTRY_DELETED) - cmc_assert_equals(ptr, kentry, *(kentry->ref[0])); - if (ventry && ventry != CMC_ENTRY_DELETED) - cmc_assert_equals(ptr, ventry, *(ventry->ref[1])); - } - - bm_free(map); - }); - - CMC_CREATE_TEST(insert[growth remove clear], { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - cmc_assert(bm_insert(map, i, i)); - - cmc_assert_equals(size_t, 1000, bm_count(map)); - - size_t j = 1; - while (!bm_empty(map)) - { - if (bm_count(map) % 2 == 0) - cmc_assert(bm_remove_by_key(map, j++, NULL, NULL)); - else - cmc_assert(bm_remove_by_val(map, j++, NULL, NULL)); - } - - cmc_assert_equals(size_t, 0, bm_count(map)); - - for (size_t i = 1; i <= 1000; i++) - cmc_assert(bm_insert(map, i, i)); - - cmc_assert_equals(size_t, 1000, bm_count(map)); - - bm_clear(map); - - cmc_assert_equals(size_t, 0, bm_count(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(insert[ftab hash calls], { - struct bidimap *map = - bm_new(100, 0.7, bm_fkey_counter, bm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - k_total_hash = 0; - v_total_hash = 0; - - for (size_t i = 1; i <= 1000; i++) - cmc_assert(bm_insert(map, i, i)); - - cmc_assert_greater_equals(int32_t, 1000, k_total_hash); - cmc_assert_greater_equals(int32_t, 1000, v_total_hash); - - bm_free(map); - - k_total_hash = 0; - v_total_hash = 0; - }); - - CMC_CREATE_TEST(update_key, { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(bm_insert(map, i, i)); - - cmc_assert_equals(size_t, 100, bm_count(map)); - - for (size_t i = 100; i > 0; i--) - cmc_assert(bm_update_key(map, i, i + 10)); - - cmc_assert_equals(size_t, 100, bm_count(map)); - - for (size_t i = 1; i <= 100; i++) - cmc_assert_equals(size_t, i + 10, bm_get_key(map, i)); - - cmc_assert_equals(size_t, 100, bm_count(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(update_key[empty], { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, 0, bm_count(map)); - - cmc_assert(!bm_update_key(map, 1, 1)); - - cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(update_key[not_found duplicate], { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(bm_insert(map, 1, 1)); - - cmc_assert_equals(size_t, 1, bm_count(map)); - - map->flag = cmc_flags.ERROR; - cmc_assert(bm_update_key(map, 1, 1)); - - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - cmc_assert(!bm_update_key(map, 2, 2)); - - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - - cmc_assert(bm_insert(map, 2, 2)); - - cmc_assert(!bm_update_key(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - cmc_assert(!bm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - - cmc_assert(bm_update_key(map, 2, 2)); - - bm_free(map); - }); - - CMC_CREATE_TEST(update_val, { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(bm_insert(map, i, i)); - - cmc_assert_equals(size_t, 100, bm_count(map)); - - for (size_t i = 100; i > 0; i--) - cmc_assert(bm_update_val(map, i, i + 10)); - - cmc_assert_equals(size_t, 100, bm_count(map)); - - for (size_t i = 1; i <= 100; i++) - cmc_assert_equals(size_t, i + 10, bm_get_val(map, i)); - - cmc_assert_equals(size_t, 100, bm_count(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(update_val[empty], { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, 0, bm_count(map)); - - cmc_assert(!bm_update_val(map, 1, 1)); - - cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map)); - - bm_free(map); - }); - - CMC_CREATE_TEST(update_val[not_found duplicate], { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(bm_insert(map, 1, 1)); - - cmc_assert_equals(size_t, 1, bm_count(map)); - - map->flag = cmc_flags.ERROR; - cmc_assert(bm_update_val(map, 1, 1)); - - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - cmc_assert(!bm_update_val(map, 2, 2)); - - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - - cmc_assert(bm_insert(map, 2, 2)); - - cmc_assert(!bm_update_val(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - cmc_assert(!bm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - - cmc_assert(bm_update_val(map, 2, 2)); - - bm_free(map); - }); - - CMC_CREATE_TEST(remove_by_key[cleanup custom], { - struct bidimap *map = - bm_new_custom(10000, 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 < 10000; i++) - { - cmc_assert(bm_insert(map, i, i)); - } - - for (size_t i = 0; i < 10000; i++) - { - cmc_assert(bm_remove_by_key(map, i, NULL, NULL)); - } - - for (size_t i = 0; i < map->capacity; i++) - { - struct bidimap_entry *k = map->buffer[i][0]; - struct bidimap_entry *v = map->buffer[i][1]; - - cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && - (v == NULL || v == CMC_ENTRY_DELETED)); - } - - bm_free(map); - }); - - CMC_CREATE_TEST(remove_by_val[cleanup custom], { - struct bidimap *map = - bm_new_custom(10000, 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 < 10000; i++) - { - cmc_assert(bm_insert(map, i, i)); - } - - for (size_t i = 0; i < 10000; i++) - { - cmc_assert(bm_remove_by_val(map, i, NULL, NULL)); - } - - for (size_t i = 0; i < map->capacity; i++) - { - struct bidimap_entry *k = map->buffer[i][0]; - struct bidimap_entry *v = map->buffer[i][1]; - - cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && - (v == NULL || v == CMC_ENTRY_DELETED)); - } - - bm_free(map); - }); - - CMC_CREATE_TEST(copy_of, { - struct bidimap *map1 = bm_new(100, 0.7, bm_fkey, bm_fval); - - for (size_t i = 0; i < 100; i++) - cmc_assert(bm_insert(map1, i, i)); - - struct bidimap *map2 = bm_copy_of(map1); - - cmc_assert_not_equals(ptr, NULL, map2); - cmc_assert_equals(size_t, bm_count(map1), bm_count(map2)); - - for (size_t i = 0; i < 100; i++) - { - cmc_assert(bm_contains_key(map2, i) && bm_contains_key(map1, i)); - cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i)); - } - - bm_free(map1); - bm_free(map2); - }); - - CMC_CREATE_TEST(equals, { - struct bidimap *map1 = bm_new(100, 0.7, bm_fkey, bm_fval); - struct bidimap *map2 = bm_new(1000, 0.9, bm_fkey, bm_fval); - - for (size_t i = 0; i < 100; i++) - { - cmc_assert(bm_insert(map1, i, i)); - cmc_assert(bm_insert(map2, 99 - i, 99 - i)); - } - - cmc_assert_not_equals(ptr, NULL, map1); - cmc_assert_not_equals(ptr, NULL, map2); - cmc_assert_equals(size_t, bm_count(map1), bm_count(map2)); - - for (size_t i = 0; i < 100; i++) - { - cmc_assert(bm_contains_key(map2, i) && bm_contains_key(map1, i)); - cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i)); - } - - bm_free(map1); - bm_free(map2); - }); - - CMC_CREATE_TEST(equals[from copy], { - struct bidimap *map1 = bm_new(100, 0.7, bm_fkey, bm_fval); - - for (size_t i = 0; i < 100; i++) - cmc_assert(bm_insert(map1, i, i)); - - struct bidimap *map2 = bm_copy_of(map1); - - cmc_assert_not_equals(ptr, NULL, map2); - - cmc_assert(bm_equals(map1, map2)); - - bm_free(map1); - bm_free(map2); - }); - - CMC_CREATE_TEST(flags, { - struct bidimap *map = bm_new(100, 0.7, bm_fkey, bm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - // customize - bm_customize(map, &cmc_alloc_node_default, - &(struct cmc_callbacks){ 0 }); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - // Insert - cmc_assert(bm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - cmc_assert(!bm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - map->flag = cmc_flags.ERROR; - cmc_assert(!bm_insert(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - - // clear - bm_clear(map); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - // bm_update_key - cmc_assert(!bm_update_key(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map)); - - cmc_assert(bm_insert(map, 1, 1)); - cmc_assert(!bm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - - cmc_assert(bm_insert(map, 2, 2)); - cmc_assert(!bm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - map->flag = cmc_flags.ERROR; - cmc_assert(!bm_update_key(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - - // clear - bm_clear(map); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - // bm_update_val - cmc_assert(!bm_update_val(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map)); - - cmc_assert(bm_insert(map, 1, 1)); - cmc_assert(!bm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - - cmc_assert(bm_insert(map, 2, 2)); - cmc_assert(!bm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - map->flag = cmc_flags.ERROR; - cmc_assert(!bm_update_val(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map)); - - // remove_by_key - cmc_assert(bm_remove_by_key(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - cmc_assert(!bm_remove_by_key(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - - cmc_assert(bm_remove_by_key(map, 2, NULL, NULL)); - cmc_assert(!bm_remove_by_key(map, 2, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map)); - - // remove_by_val - cmc_assert(bm_insert(map, 1, 1) && bm_insert(map, 2, 2)); - - cmc_assert(bm_remove_by_val(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - cmc_assert(!bm_remove_by_val(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - - cmc_assert(bm_remove_by_val(map, 2, NULL, NULL)); - cmc_assert(!bm_remove_by_val(map, 2, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map)); - - // get_key and get_val - cmc_assert(bm_insert(map, 2, 1)); - - cmc_assert_equals(size_t, 2, bm_get_key(map, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - map->flag = cmc_flags.ERROR; - cmc_assert_equals(size_t, 1, bm_get_val(map, 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - cmc_assert_equals(size_t, 0, bm_get_key(map, 2)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - map->flag = cmc_flags.ERROR; - cmc_assert_equals(size_t, 0, bm_get_val(map, 1)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - - // contains_key - cmc_assert(bm_contains_key(map, 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - // contains_val - map->flag = cmc_flags.ERROR; - cmc_assert(bm_contains_val(map, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - - // copy_of - map->flag = cmc_flags.ERROR; - struct bidimap *map2 = bm_copy_of(map); - - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map2)); - - size_t tmp = map->capacity; - map->capacity = 0; - - struct bidimap *map3 = bm_copy_of(map); - cmc_assert_equals(ptr, NULL, map3); - cmc_assert_equals(int32_t, cmc_flags.ERROR, bm_flag(map)); - - map->capacity = tmp; - - // equals - bm_get_key(map, 100); - bm_get_key(map2, 100); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map2)); - map->flag = cmc_flags.ERROR; - cmc_assert(bm_equals(map, map2)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map2)); - - bm_free(map); - bm_free(map2); - }); - - CMC_CREATE_TEST(callbacks, { - struct bidimap *map = - bm_new_custom(100, 0.7, bm_fkey, bm_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(ptr, callbacks, map->callbacks); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(bm_insert(map, 10, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(bm_update_key(map, 10, 5)); - cmc_assert_equals(int32_t, 1, total_update); - - cmc_assert(bm_update_val(map, 5, 5)); - cmc_assert_equals(int32_t, 2, total_update); - - cmc_assert(bm_insert(map, 10, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(bm_remove_by_key(map, 5, NULL, NULL)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(bm_remove_by_val(map, 10, NULL, NULL)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(bm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, 3, total_create); - - cmc_assert_equals(size_t, 1, bm_get_key(map, 2)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert_equals(size_t, 2, bm_get_val(map, 1)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(bm_resize(map, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(bm_resize(map, 200)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert(bm_contains_key(map, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert(bm_contains_val(map, 2)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert_equals(int32_t, 3, total_create); - cmc_assert_equals(int32_t, 4, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - bm_customize(map, NULL, NULL); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - bm_clear(map); - cmc_assert(bm_insert(map, 10, 10)); - cmc_assert(bm_update_key(map, 10, 5)); - cmc_assert(bm_update_val(map, 5, 5)); - cmc_assert(bm_insert(map, 10, 10)); - cmc_assert(bm_remove_by_key(map, 5, NULL, NULL)); - cmc_assert(bm_remove_by_val(map, 10, NULL, NULL)); - cmc_assert(bm_insert(map, 1, 2)); - cmc_assert_equals(size_t, 1, bm_get_key(map, 2)); - cmc_assert_equals(size_t, 2, bm_get_val(map, 1)); - cmc_assert(bm_resize(map, 1000)); - cmc_assert(bm_resize(map, 200)); - cmc_assert(bm_contains_key(map, 1)); - cmc_assert(bm_contains_val(map, 2)); - - cmc_assert_equals(int32_t, 3, total_create); - cmc_assert_equals(int32_t, 4, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - bm_free(map); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); diff --git a/tests/main/unt/hashbidimap.c b/tests/main/unt/hashbidimap.c new file mode 100644 index 0000000..1c1f3a4 --- /dev/null +++ b/tests/main/unt/hashbidimap.c @@ -0,0 +1,822 @@ +#include "utl.c" +#include "utl/assert.h" +#include "utl/test.h" + +#include "../src/hashbidimap.c" + +struct hashbidimap_fkey *hbm_fkey = &(struct hashbidimap_fkey){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }; + +struct hashbidimap_fval *hbm_fval = &(struct hashbidimap_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }; + +struct hashbidimap_fkey *hbm_fkey_counter = &(struct hashbidimap_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 hashbidimap_fval *hbm_fval_counter = &(struct hashbidimap_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 *hbm_alloc_node = &(struct cmc_alloc_node){ + .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +}; + +CMC_CREATE_UNIT(HashBidiMap, true, { + CMC_CREATE_TEST(PFX##_new(), { + struct hashbidimap *map = hbm_new(943722, 0.6, hbm_fkey, hbm_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, hbm_fkey, map->f_key); + cmc_assert_equals(ptr, hbm_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), hbm_capacity(map)); + + hbm_free(map); + + map = hbm_new(100, 0.6, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, 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]); + } + + hbm_free(map); + + map = hbm_new(0, 0.6, hbm_fkey, hbm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_new(UINT64_MAX, 0.99, hbm_fkey, hbm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_new(1000, 0.6, hbm_fkey, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_new(1000, 0.6, NULL, hbm_fval); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_new(1000, 0.6, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + }); + + CMC_CREATE_TEST(PFX##_new_custom(), { + struct hashbidimap *map = hbm_new_custom(943722, 0.6, hbm_fkey, hbm_fval, + hbm_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, hbm_fkey, map->f_key); + cmc_assert_equals(ptr, hbm_fval, map->f_val); + cmc_assert_equals(ptr, hbm_alloc_node, map->alloc); + cmc_assert_equals(ptr, callbacks, map->callbacks); + + cmc_assert_greater_equals(size_t, (943722 / 0.6), hbm_capacity(map)); + + hbm_free(map); + + map = hbm_new_custom(0, 0.6, hbm_fkey, hbm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_new_custom(UINT64_MAX, 0.99, hbm_fkey, hbm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_new_custom(1000, 0.6, hbm_fkey, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_new_custom(1000, 0.6, NULL, hbm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map); + + map = hbm_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 hashbidimap *map = + hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + hbm_insert(map, i, i); + + cmc_assert_equals(size_t, 1000, map->count); + + map->flag = cmc_flags.ERROR; + hbm_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); + + hbm_free(map); + k_total_free = 0; + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_free(), { + k_total_free = 0; + v_total_free = 0; + struct hashbidimap *map = + hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + hbm_insert(map, i, i); + + cmc_assert_equals(size_t, 1000, map->count); + + hbm_free(map); + + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + + map = hbm_new(1000, 0.6, hbm_fkey_counter, hbm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_not_equals(ptr, NULL, map->buffer); + + hbm_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, { + struct hashbidimap *map = + hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, NULL, NULL); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, NULL, map->callbacks); + + hbm_free(map); + + struct cmc_alloc_node node; + node.malloc = malloc; + node.realloc = realloc; + node.free = free; + node.calloc = calloc; + + map = hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, &node, callbacks); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert_equals(ptr, &node, map->alloc); + cmc_assert_equals(ptr, callbacks, map->callbacks); + + hbm_free(map); + }); + + CMC_CREATE_TEST(buffer_growth[capacity = 1], { + struct hashbidimap *map = hbm_new(1, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 10000; i++) + cmc_assert(hbm_insert(map, i, i)); + + size_t sum = 0; + + for (size_t i = 0; i < hbm_capacity(map); i++) + { + if (map->buffer[i][0] && map->buffer[i][0] != CMC_ENTRY_DELETED) + { + sum += map->buffer[i][0]->key; + } + } + + cmc_assert_equals(size_t, 50005000, sum); + + hbm_free(map); + }); + + CMC_CREATE_TEST(insert, { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert(hbm_insert(map, 1, 1)); + cmc_assert(hbm_insert(map, 2, 2)); + cmc_assert(hbm_insert(map, 3, 3)); + + cmc_assert_equals(size_t, 3, hbm_count(map)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(insert[duplicate], { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert(hbm_insert(map, 1, 1)); + cmc_assert(!hbm_insert(map, 1, 1)); + cmc_assert(!hbm_insert(map, 2, 1)); + cmc_assert(!hbm_insert(map, 1, 2)); + cmc_assert(hbm_insert(map, 2, 2)); + + cmc_assert_equals(size_t, 2, hbm_count(map)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(insert[references], { + struct hashbidimap *map = hbm_new(500, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 0; i < 500; i++) + cmc_assert(hbm_insert(map, i, i)); + + for (size_t i = 0; i < map->capacity; i++) + { + struct hashbidimap_entry *kentry = map->buffer[i][0]; + struct hashbidimap_entry *ventry = map->buffer[i][1]; + + if (kentry && kentry != CMC_ENTRY_DELETED) + cmc_assert_equals(ptr, kentry, *(kentry->ref[0])); + if (ventry && ventry != CMC_ENTRY_DELETED) + cmc_assert_equals(ptr, ventry, *(ventry->ref[1])); + } + + hbm_free(map); + }); + + CMC_CREATE_TEST(insert[growth remove clear], { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 1000; i++) + cmc_assert(hbm_insert(map, i, i)); + + cmc_assert_equals(size_t, 1000, hbm_count(map)); + + size_t j = 1; + while (!hbm_empty(map)) + { + if (hbm_count(map) % 2 == 0) + cmc_assert(hbm_remove_by_key(map, j++, NULL, NULL)); + else + cmc_assert(hbm_remove_by_val(map, j++, NULL, NULL)); + } + + cmc_assert_equals(size_t, 0, hbm_count(map)); + + for (size_t i = 1; i <= 1000; i++) + cmc_assert(hbm_insert(map, i, i)); + + cmc_assert_equals(size_t, 1000, hbm_count(map)); + + hbm_clear(map); + + cmc_assert_equals(size_t, 0, hbm_count(map)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(insert[ftab hash calls], { + struct hashbidimap *map = + hbm_new(100, 0.7, hbm_fkey_counter, hbm_fval_counter); + + cmc_assert_not_equals(ptr, NULL, map); + + k_total_hash = 0; + v_total_hash = 0; + + for (size_t i = 1; i <= 1000; i++) + cmc_assert(hbm_insert(map, i, i)); + + cmc_assert_greater_equals(int32_t, 1000, k_total_hash); + cmc_assert_greater_equals(int32_t, 1000, v_total_hash); + + hbm_free(map); + + k_total_hash = 0; + v_total_hash = 0; + }); + + CMC_CREATE_TEST(update_key, { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 100; i++) + cmc_assert(hbm_insert(map, i, i)); + + cmc_assert_equals(size_t, 100, hbm_count(map)); + + for (size_t i = 100; i > 0; i--) + cmc_assert(hbm_update_key(map, i, i + 10)); + + cmc_assert_equals(size_t, 100, hbm_count(map)); + + for (size_t i = 1; i <= 100; i++) + cmc_assert_equals(size_t, i + 10, hbm_get_key(map, i)); + + cmc_assert_equals(size_t, 100, hbm_count(map)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(update_key[empty], { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert_equals(size_t, 0, hbm_count(map)); + + cmc_assert(!hbm_update_key(map, 1, 1)); + + cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(update_key[not_found duplicate], { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert(hbm_insert(map, 1, 1)); + + cmc_assert_equals(size_t, 1, hbm_count(map)); + + map->flag = cmc_flags.ERROR; + cmc_assert(hbm_update_key(map, 1, 1)); + + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + cmc_assert(!hbm_update_key(map, 2, 2)); + + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + + cmc_assert(hbm_insert(map, 2, 2)); + + cmc_assert(!hbm_update_key(map, 1, 2)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert(!hbm_update_key(map, 2, 1)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + + cmc_assert(hbm_update_key(map, 2, 2)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(update_val, { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + for (size_t i = 1; i <= 100; i++) + cmc_assert(hbm_insert(map, i, i)); + + cmc_assert_equals(size_t, 100, hbm_count(map)); + + for (size_t i = 100; i > 0; i--) + cmc_assert(hbm_update_val(map, i, i + 10)); + + cmc_assert_equals(size_t, 100, hbm_count(map)); + + for (size_t i = 1; i <= 100; i++) + cmc_assert_equals(size_t, i + 10, hbm_get_val(map, i)); + + cmc_assert_equals(size_t, 100, hbm_count(map)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(update_val[empty], { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert_equals(size_t, 0, hbm_count(map)); + + cmc_assert(!hbm_update_val(map, 1, 1)); + + cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(update_val[not_found duplicate], { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + + cmc_assert(hbm_insert(map, 1, 1)); + + cmc_assert_equals(size_t, 1, hbm_count(map)); + + map->flag = cmc_flags.ERROR; + cmc_assert(hbm_update_val(map, 1, 1)); + + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + cmc_assert(!hbm_update_val(map, 2, 2)); + + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + + cmc_assert(hbm_insert(map, 2, 2)); + + cmc_assert(!hbm_update_val(map, 1, 2)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert(!hbm_update_val(map, 2, 1)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + + cmc_assert(hbm_update_val(map, 2, 2)); + + hbm_free(map); + }); + + CMC_CREATE_TEST(remove_by_key[cleanup custom], { + struct hashbidimap *map = + hbm_new_custom(10000, 0.6, hbm_fkey, hbm_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 < 10000; i++) + { + cmc_assert(hbm_insert(map, i, i)); + } + + for (size_t i = 0; i < 10000; i++) + { + cmc_assert(hbm_remove_by_key(map, i, NULL, NULL)); + } + + for (size_t i = 0; i < map->capacity; i++) + { + struct hashbidimap_entry *k = map->buffer[i][0]; + struct hashbidimap_entry *v = map->buffer[i][1]; + + cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && + (v == NULL || v == CMC_ENTRY_DELETED)); + } + + hbm_free(map); + }); + + CMC_CREATE_TEST(remove_by_val[cleanup custom], { + struct hashbidimap *map = + hbm_new_custom(10000, 0.6, hbm_fkey, hbm_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 < 10000; i++) + { + cmc_assert(hbm_insert(map, i, i)); + } + + for (size_t i = 0; i < 10000; i++) + { + cmc_assert(hbm_remove_by_val(map, i, NULL, NULL)); + } + + for (size_t i = 0; i < map->capacity; i++) + { + struct hashbidimap_entry *k = map->buffer[i][0]; + struct hashbidimap_entry *v = map->buffer[i][1]; + + cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && + (v == NULL || v == CMC_ENTRY_DELETED)); + } + + hbm_free(map); + }); + + CMC_CREATE_TEST(copy_of, { + struct hashbidimap *map1 = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + for (size_t i = 0; i < 100; i++) + cmc_assert(hbm_insert(map1, i, i)); + + struct hashbidimap *map2 = hbm_copy_of(map1); + + cmc_assert_not_equals(ptr, NULL, map2); + cmc_assert_equals(size_t, hbm_count(map1), hbm_count(map2)); + + for (size_t i = 0; i < 100; i++) + { + cmc_assert(hbm_contains_key(map2, i) && hbm_contains_key(map1, i)); + cmc_assert(hbm_contains_val(map2, i) && hbm_contains_val(map1, i)); + } + + hbm_free(map1); + hbm_free(map2); + }); + + CMC_CREATE_TEST(equals, { + struct hashbidimap *map1 = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + struct hashbidimap *map2 = hbm_new(1000, 0.9, hbm_fkey, hbm_fval); + + for (size_t i = 0; i < 100; i++) + { + cmc_assert(hbm_insert(map1, i, i)); + cmc_assert(hbm_insert(map2, 99 - i, 99 - i)); + } + + cmc_assert_not_equals(ptr, NULL, map1); + cmc_assert_not_equals(ptr, NULL, map2); + cmc_assert_equals(size_t, hbm_count(map1), hbm_count(map2)); + + for (size_t i = 0; i < 100; i++) + { + cmc_assert(hbm_contains_key(map2, i) && hbm_contains_key(map1, i)); + cmc_assert(hbm_contains_val(map2, i) && hbm_contains_val(map1, i)); + } + + hbm_free(map1); + hbm_free(map2); + }); + + CMC_CREATE_TEST(equals[from copy], { + struct hashbidimap *map1 = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + for (size_t i = 0; i < 100; i++) + cmc_assert(hbm_insert(map1, i, i)); + + struct hashbidimap *map2 = hbm_copy_of(map1); + + cmc_assert_not_equals(ptr, NULL, map2); + + cmc_assert(hbm_equals(map1, map2)); + + hbm_free(map1); + hbm_free(map2); + }); + + CMC_CREATE_TEST(flags, { + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); + + cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + // customize + hbm_customize(map, &cmc_alloc_node_default, + &(struct cmc_callbacks){ 0 }); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + // Insert + cmc_assert(hbm_insert(map, 1, 1)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + cmc_assert(!hbm_insert(map, 1, 2)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + map->flag = cmc_flags.ERROR; + cmc_assert(!hbm_insert(map, 2, 1)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + + // clear + hbm_clear(map); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + // hbm_update_key + cmc_assert(!hbm_update_key(map, 1, 1)); + cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + + cmc_assert(hbm_insert(map, 1, 1)); + cmc_assert(!hbm_update_key(map, 2, 1)); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + + cmc_assert(hbm_insert(map, 2, 2)); + cmc_assert(!hbm_update_key(map, 2, 1)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + map->flag = cmc_flags.ERROR; + cmc_assert(!hbm_update_key(map, 1, 2)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + + // clear + hbm_clear(map); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + // hbm_update_val + cmc_assert(!hbm_update_val(map, 1, 1)); + cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + + cmc_assert(hbm_insert(map, 1, 1)); + cmc_assert(!hbm_update_val(map, 2, 1)); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + + cmc_assert(hbm_insert(map, 2, 2)); + cmc_assert(!hbm_update_val(map, 2, 1)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + map->flag = cmc_flags.ERROR; + cmc_assert(!hbm_update_val(map, 1, 2)); + cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + + // remove_by_key + cmc_assert(hbm_remove_by_key(map, 1, NULL, NULL)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + cmc_assert(!hbm_remove_by_key(map, 1, NULL, NULL)); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + + cmc_assert(hbm_remove_by_key(map, 2, NULL, NULL)); + cmc_assert(!hbm_remove_by_key(map, 2, NULL, NULL)); + cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + + // remove_by_val + cmc_assert(hbm_insert(map, 1, 1) && hbm_insert(map, 2, 2)); + + cmc_assert(hbm_remove_by_val(map, 1, NULL, NULL)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + cmc_assert(!hbm_remove_by_val(map, 1, NULL, NULL)); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + + cmc_assert(hbm_remove_by_val(map, 2, NULL, NULL)); + cmc_assert(!hbm_remove_by_val(map, 2, NULL, NULL)); + cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + + // get_key and get_val + cmc_assert(hbm_insert(map, 2, 1)); + + cmc_assert_equals(size_t, 2, hbm_get_key(map, 1)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + map->flag = cmc_flags.ERROR; + cmc_assert_equals(size_t, 1, hbm_get_val(map, 2)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + cmc_assert_equals(size_t, 0, hbm_get_key(map, 2)); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + map->flag = cmc_flags.ERROR; + cmc_assert_equals(size_t, 0, hbm_get_val(map, 1)); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + + // contains_key + cmc_assert(hbm_contains_key(map, 2)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + // contains_val + map->flag = cmc_flags.ERROR; + cmc_assert(hbm_contains_val(map, 1)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + + // copy_of + map->flag = cmc_flags.ERROR; + struct hashbidimap *map2 = hbm_copy_of(map); + + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map2)); + + size_t tmp = map->capacity; + map->capacity = 0; + + struct hashbidimap *map3 = hbm_copy_of(map); + cmc_assert_equals(ptr, NULL, map3); + cmc_assert_equals(int32_t, cmc_flags.ERROR, hbm_flag(map)); + + map->capacity = tmp; + + // equals + hbm_get_key(map, 100); + hbm_get_key(map2, 100); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map2)); + map->flag = cmc_flags.ERROR; + cmc_assert(hbm_equals(map, map2)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map2)); + + hbm_free(map); + hbm_free(map2); + }); + + CMC_CREATE_TEST(callbacks, { + struct hashbidimap *map = + hbm_new_custom(100, 0.7, hbm_fkey, hbm_fval, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, map); + cmc_assert_equals(ptr, callbacks, map->callbacks); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + cmc_assert(hbm_insert(map, 10, 10)); + cmc_assert_equals(int32_t, 1, total_create); + + cmc_assert(hbm_update_key(map, 10, 5)); + cmc_assert_equals(int32_t, 1, total_update); + + cmc_assert(hbm_update_val(map, 5, 5)); + cmc_assert_equals(int32_t, 2, total_update); + + cmc_assert(hbm_insert(map, 10, 10)); + cmc_assert_equals(int32_t, 2, total_create); + + cmc_assert(hbm_remove_by_key(map, 5, NULL, NULL)); + cmc_assert_equals(int32_t, 1, total_delete); + + cmc_assert(hbm_remove_by_val(map, 10, NULL, NULL)); + cmc_assert_equals(int32_t, 2, total_delete); + + cmc_assert(hbm_insert(map, 1, 2)); + cmc_assert_equals(int32_t, 3, total_create); + + cmc_assert_equals(size_t, 1, hbm_get_key(map, 2)); + cmc_assert_equals(int32_t, 1, total_read); + + cmc_assert_equals(size_t, 2, hbm_get_val(map, 1)); + cmc_assert_equals(int32_t, 2, total_read); + + cmc_assert(hbm_resize(map, 1000)); + cmc_assert_equals(int32_t, 1, total_resize); + + cmc_assert(hbm_resize(map, 200)); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert(hbm_contains_key(map, 1)); + cmc_assert_equals(int32_t, 3, total_read); + + cmc_assert(hbm_contains_val(map, 2)); + cmc_assert_equals(int32_t, 4, total_read); + + cmc_assert_equals(int32_t, 3, total_create); + cmc_assert_equals(int32_t, 4, total_read); + cmc_assert_equals(int32_t, 2, total_update); + cmc_assert_equals(int32_t, 2, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + hbm_customize(map, NULL, NULL); + + cmc_assert_equals(ptr, NULL, map->callbacks); + + hbm_clear(map); + cmc_assert(hbm_insert(map, 10, 10)); + cmc_assert(hbm_update_key(map, 10, 5)); + cmc_assert(hbm_update_val(map, 5, 5)); + cmc_assert(hbm_insert(map, 10, 10)); + cmc_assert(hbm_remove_by_key(map, 5, NULL, NULL)); + cmc_assert(hbm_remove_by_val(map, 10, NULL, NULL)); + cmc_assert(hbm_insert(map, 1, 2)); + cmc_assert_equals(size_t, 1, hbm_get_key(map, 2)); + cmc_assert_equals(size_t, 2, hbm_get_val(map, 1)); + cmc_assert(hbm_resize(map, 1000)); + cmc_assert(hbm_resize(map, 200)); + cmc_assert(hbm_contains_key(map, 1)); + cmc_assert(hbm_contains_val(map, 2)); + + cmc_assert_equals(int32_t, 3, total_create); + cmc_assert_equals(int32_t, 4, total_read); + cmc_assert_equals(int32_t, 2, total_update); + cmc_assert_equals(int32_t, 2, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert_equals(ptr, NULL, map->callbacks); + + hbm_free(map); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + }); +});