Added flags to bidimap

This commit is contained in:
Leonardo committed 2020-02-26 13:01:35 -03:00
1 parent 5ed65668e0
commit 9e206635be
2 files changed
+193 -23

No files matched your search

+44 -23
View File
@@ -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; \
} \
+149
View File
@@ -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);
});
});