Added flags to bidimap
This commit is contained in:
1 parent
5ed65668e0
commit
9e206635be
2 files changed
+193
-23
No files matched your search
+44
-23
@@ -350,6 +350,7 @@ struct cmc_callbacks_bidimap
|
||||
size_t PFX##_count(struct SNAME *_map_); \
|
||||
size_t PFX##_capacity(struct SNAME *_map_); \
|
||||
double PFX##_load(struct SNAME *_map_); \
|
||||
int PFX##_flag(struct SNAME *_map_); \
|
||||
/* Collection Utility */ \
|
||||
bool PFX##_resize(struct SNAME *_map_, size_t capacity); \
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_map_); \
|
||||
@@ -551,7 +552,7 @@ struct cmc_callbacks_bidimap
|
||||
{ \
|
||||
if (PFX##_full(_map_)) \
|
||||
{ \
|
||||
if (!PFX##_resize(_map_, PFX##_capacity(_map_) + 1)) \
|
||||
if (!PFX##_resize(_map_, _map_->capacity + 1)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
@@ -559,7 +560,6 @@ struct cmc_callbacks_bidimap
|
||||
PFX##_impl_get_entry_by_val(_map_, value) != NULL) \
|
||||
{ \
|
||||
_map_->flag = cmc_flags.DUPLICATE; \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
@@ -871,6 +871,8 @@ struct cmc_callbacks_bidimap
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_map_->flag = cmc_flags.OK; \
|
||||
\
|
||||
return (*entry)->key; \
|
||||
} \
|
||||
\
|
||||
@@ -885,6 +887,8 @@ struct cmc_callbacks_bidimap
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_map_->flag = cmc_flags.OK; \
|
||||
\
|
||||
return (*entry)->value; \
|
||||
} \
|
||||
\
|
||||
@@ -905,8 +909,7 @@ struct cmc_callbacks_bidimap
|
||||
\
|
||||
bool PFX##_full(struct SNAME *_map_) \
|
||||
{ \
|
||||
return (double)PFX##_capacity(_map_) * PFX##_load(_map_) <= \
|
||||
(double)PFX##_count(_map_); \
|
||||
return (double)_map_->capacity * _map_->load <= (double)_map_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(struct SNAME *_map_) \
|
||||
@@ -924,19 +927,26 @@ struct cmc_callbacks_bidimap
|
||||
return _map_->load; \
|
||||
} \
|
||||
\
|
||||
int PFX##_flag(struct SNAME *_map_) \
|
||||
{ \
|
||||
return _map_->flag; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_resize(struct SNAME *_map_, size_t capacity) \
|
||||
{ \
|
||||
if (PFX##_capacity(_map_) == capacity) \
|
||||
\
|
||||
_map_->flag = cmc_flags.OK; \
|
||||
\
|
||||
if (_map_->capacity == capacity) \
|
||||
return true; \
|
||||
\
|
||||
if (PFX##_capacity(_map_) > capacity / PFX##_load(_map_)) \
|
||||
if (_map_->capacity > capacity / _map_->load) \
|
||||
return true; \
|
||||
\
|
||||
/* Prevent integer overflow */ \
|
||||
if (capacity >= UINTMAX_MAX * PFX##_load(_map_)) \
|
||||
if (capacity >= UINTMAX_MAX * _map_->load) \
|
||||
{ \
|
||||
_map_->flag = cmc_flags.ERROR; \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
@@ -944,21 +954,19 @@ struct cmc_callbacks_bidimap
|
||||
size_t new_cap = PFX##_impl_calculate_size(capacity); \
|
||||
\
|
||||
/* Not possible to shrink with current available prime numbers */ \
|
||||
if (new_cap < PFX##_count(_map_) / PFX##_load(_map_)) \
|
||||
if (new_cap < _map_->count / _map_->load) \
|
||||
{ \
|
||||
_map_->flag = cmc_flags.ERROR; \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *_new_map_ = \
|
||||
PFX##_new_custom(capacity, PFX##_load(_map_), _map_->f_key, \
|
||||
PFX##_new_custom(capacity, _map_->load, _map_->f_key, \
|
||||
_map_->f_val, _map_->alloc, _map_->callbacks); \
|
||||
\
|
||||
if (!_new_map_) \
|
||||
{ \
|
||||
_map_->flag = cmc_flags.ALLOC; \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
@@ -988,7 +996,7 @@ struct cmc_callbacks_bidimap
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (PFX##_count(_map_) != PFX##_count(_new_map_)) \
|
||||
if (_map_->count != _new_map_->count) \
|
||||
{ \
|
||||
_map_->alloc->free(_new_map_->key_buffer); \
|
||||
_map_->alloc->free(_new_map_->val_buffer); \
|
||||
@@ -1010,15 +1018,17 @@ struct cmc_callbacks_bidimap
|
||||
_map_->alloc->free(tmp_val_buf); \
|
||||
_map_->alloc->free(_new_map_); \
|
||||
\
|
||||
_map_->flag = cmc_flags.OK; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
struct SNAME *PFX##_copy_of(struct SNAME *_map_) \
|
||||
{ \
|
||||
/* TODO this function can be optimized */ \
|
||||
struct SNAME *result = PFX##_new_custom( \
|
||||
PFX##_capacity(_map_), PFX##_load(_map_), _map_->f_key, \
|
||||
_map_->f_val, _map_->alloc, _map_->callbacks); \
|
||||
struct SNAME *result = \
|
||||
PFX##_new_custom(_map_->capacity, _map_->load, _map_->f_key, \
|
||||
_map_->f_val, _map_->alloc, _map_->callbacks); \
|
||||
\
|
||||
for (size_t i = 0; i < _map_->capacity; i++) \
|
||||
{ \
|
||||
@@ -1044,18 +1054,23 @@ struct cmc_callbacks_bidimap
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_map_->flag = cmc_flags.OK; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \
|
||||
{ \
|
||||
if (PFX##_count(_map1_) != PFX##_count(_map2_)) \
|
||||
_map1_->flag = cmc_flags.OK; \
|
||||
_map2_->flag = cmc_flags.OK; \
|
||||
\
|
||||
if (_map1_->count != _map2_->count) \
|
||||
return false; \
|
||||
\
|
||||
struct SNAME *_mapA_; \
|
||||
struct SNAME *_mapB_; \
|
||||
\
|
||||
if (PFX##_capacity(_map1_) < PFX##_capacity(_map2_)) \
|
||||
if (_map1_->capacity < _map2_->capacity) \
|
||||
{ \
|
||||
_mapA_ = _map1_; \
|
||||
_mapB_ = _map2_; \
|
||||
@@ -1196,7 +1211,7 @@ struct cmc_callbacks_bidimap
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->last; \
|
||||
iter->index = PFX##_count(iter->target) - 1; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = false; \
|
||||
iter->end = true; \
|
||||
} \
|
||||
@@ -1207,7 +1222,7 @@ struct cmc_callbacks_bidimap
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
if (iter->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
@@ -1266,13 +1281,13 @@ struct cmc_callbacks_bidimap
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
if (iter->index + 1 == iter->target->count) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \
|
||||
if (steps == 0 || iter->index + steps >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < steps; i++) \
|
||||
@@ -1306,7 +1321,7 @@ struct cmc_callbacks_bidimap
|
||||
/* the given index */ \
|
||||
bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
if (index >= iter->target->count) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index > index) \
|
||||
@@ -1320,7 +1335,10 @@ struct cmc_callbacks_bidimap
|
||||
K PFX##_iter_key(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->target->flag = cmc_flags.EMPTY; \
|
||||
return (K){ 0 }; \
|
||||
} \
|
||||
\
|
||||
return iter->target->key_buffer[iter->cursor]->key; \
|
||||
} \
|
||||
@@ -1328,7 +1346,10 @@ struct cmc_callbacks_bidimap
|
||||
V PFX##_iter_value(struct SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->target->flag = cmc_flags.EMPTY; \
|
||||
return (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
return iter->target->key_buffer[iter->cursor]->value; \
|
||||
} \
|
||||
|
||||
@@ -28,6 +28,7 @@ CMC_CREATE_UNIT(bidimap_test, true, {
|
||||
struct bidimap *map = bm_new(100, 0.6, bm_ftab_key, bm_ftab_val);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, map);
|
||||
|
||||
cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
|
||||
|
||||
bm_free(map);
|
||||
@@ -356,4 +357,152 @@ CMC_CREATE_UNIT(bidimap_test, true, {
|
||||
bm_free(map1);
|
||||
bm_free(map2);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(flags, {
|
||||
struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
|
||||
|
||||
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_bidimap){ 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));
|
||||
|
||||
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));
|
||||
|
||||
// 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, 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));
|
||||
|
||||
// clear
|
||||
bm_clear(map);
|
||||
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
|
||||
|
||||
// update_key_by_val
|
||||
cmc_assert(!bm_update_key_by_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_key_by_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_key_by_val(map, 2, 1));
|
||||
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
|
||||
cmc_assert(!bm_update_key_by_val(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));
|
||||
|
||||
// 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, 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));
|
||||
|
||||
// clear
|
||||
bm_clear(map);
|
||||
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
|
||||
|
||||
// update_val_by_key
|
||||
cmc_assert(!bm_update_val_by_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_val_by_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_val_by_key(map, 2, 1));
|
||||
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
|
||||
cmc_assert(!bm_update_val_by_key(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));
|
||||
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));
|
||||
cmc_assert_equals(size_t, 0, bm_get_val(map, 1));
|
||||
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
|
||||
|
||||
// copy_of
|
||||
struct bidimap *map2 = bm_copy_of(map);
|
||||
|
||||
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map2));
|
||||
|
||||
// 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));
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user