Renaming bidimap to hashbidimap
This commit is contained in:
1 parent
c58f3df50a
commit
b35281b8dc
6 files changed
+1130
-1120
No files matched your search
+16
-16
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
+2
-2
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user