diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index ce9b94c..356f5b4 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -375,6 +375,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->alloc->free(_map_); \ } \ + \ void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ struct cmc_callbacks *callbacks) \ { \ @@ -452,6 +453,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " _map_->count++; \ _map_->flag = cmc_flags.OK; \ \ + if (_map_->callbacks && _map_->callbacks->create) \ + _map_->callbacks->create(); \ + \ return true; \ } \ \ @@ -472,6 +476,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = cmc_flags.OK; \ \ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ + \ return true; \ } \ \ @@ -602,11 +609,14 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " if (unbalanced != NULL) \ PFX##_impl_rebalance(_map_, unbalanced); \ \ + if (_map_->count == 0) \ + _map_->root = NULL; \ + \ _map_->count--; \ _map_->flag = cmc_flags.OK; \ \ - if (_map_->count == 0) \ - _map_->root = NULL; \ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ \ return true; \ } \ @@ -631,6 +641,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = cmc_flags.OK; \ \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ return true; \ } \ \ @@ -654,6 +667,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = cmc_flags.OK; \ \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ return true; \ } \ \ @@ -675,6 +691,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = cmc_flags.OK; \ \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ return node->value; \ } \ \ @@ -696,12 +715,20 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = cmc_flags.OK; \ \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ return &(node->value); \ } \ \ bool PFX##_contains(struct SNAME *_map_, K key) \ { \ - return PFX##_impl_get_node(_map_, key) != NULL; \ + bool result = PFX##_impl_get_node(_map_, key) != NULL; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return result; \ } \ \ bool PFX##_empty(struct SNAME *_map_) \ @@ -721,8 +748,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ struct SNAME *PFX##_copy_of(struct SNAME *_map_) \ { \ - struct SNAME *result = PFX##_new_custom( \ - _map_->f_key, _map_->f_val, _map_->alloc, _map_->callbacks); \ + /* Callback will be added later */ \ + struct SNAME *result = \ + PFX##_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, NULL); \ \ if (!result) \ { \ @@ -749,6 +777,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " PFX##_insert(result, key, value); \ } \ \ + result->callbacks = _map_->callbacks; \ _map_->flag = cmc_flags.OK; \ \ return result; \ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 8e4c42f..dcb09c7 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -435,6 +435,9 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " _set_->count++; \ _set_->flag = cmc_flags.OK; \ \ + if (_set_->callbacks && _set_->callbacks->create) \ + _set_->callbacks->create(); \ + \ return true; \ } \ \ @@ -560,11 +563,14 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " if (unbalanced != NULL) \ PFX##_impl_rebalance(_set_, unbalanced); \ \ + if (_set_->count == 0) \ + _set_->root = NULL; \ + \ _set_->count--; \ _set_->flag = cmc_flags.OK; \ \ - if (_set_->count == 0) \ - _set_->root = NULL; \ + if (_set_->callbacks && _set_->callbacks->delete) \ + _set_->callbacks->delete (); \ \ return true; \ } \ @@ -587,6 +593,9 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->flag = cmc_flags.OK; \ \ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ + \ return true; \ } \ \ @@ -608,12 +617,20 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->flag = cmc_flags.OK; \ \ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ + \ return true; \ } \ \ bool PFX##_contains(struct SNAME *_set_, V element) \ { \ - return PFX##_impl_get_node(_set_, element) != NULL; \ + bool result = PFX##_impl_get_node(_set_, element) != NULL; \ + \ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ + \ + return result; \ } \ \ bool PFX##_empty(struct SNAME *_set_) \ diff --git a/tests/main/unt/treemap.c b/tests/main/unt/treemap.c index 79e9fe8..8685fd5 100644 --- a/tests/main/unt/treemap.c +++ b/tests/main/unt/treemap.c @@ -139,4 +139,79 @@ CMC_CREATE_UNIT(treemap_test, true, { tm_free(map); tm_free(map2); }); + + CMC_CREATE_TEST(callbacks, { + struct treemap *map = + tm_new_custom(tm_ftab_key, tm_ftab_val, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, map); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + cmc_assert(tm_insert(map, 1, 10)); + cmc_assert_equals(int32_t, 1, total_create); + + cmc_assert(tm_update(map, 1, 2, NULL)); + cmc_assert_equals(int32_t, 1, total_update); + + cmc_assert(tm_remove(map, 1, NULL)); + cmc_assert_equals(int32_t, 1, total_delete); + + cmc_assert(tm_insert(map, 1, 2)); + cmc_assert_equals(int32_t, 2, total_create); + + cmc_assert(tm_max(map, NULL, NULL)); + cmc_assert_equals(int32_t, 1, total_read); + + cmc_assert(tm_min(map, NULL, NULL)); + cmc_assert_equals(int32_t, 2, total_read); + + cmc_assert_equals(size_t, 2, tm_get(map, 1)); + cmc_assert_equals(int32_t, 3, total_read); + + cmc_assert_not_equals(ptr, NULL, tm_get_ref(map, 1)); + cmc_assert_equals(int32_t, 4, total_read); + + cmc_assert(tm_contains(map, 1)); + cmc_assert_equals(int32_t, 5, total_read); + + cmc_assert_equals(int32_t, 2, total_create); + cmc_assert_equals(int32_t, 5, total_read); + cmc_assert_equals(int32_t, 1, total_update); + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, 0, total_resize); + + tm_customize(map, NULL, NULL); + + tm_clear(map); + cmc_assert(tm_insert(map, 1, 10)); + cmc_assert(tm_update(map, 1, 2, NULL)); + cmc_assert(tm_remove(map, 1, NULL)); + cmc_assert(tm_insert(map, 1, 2)); + cmc_assert(tm_max(map, NULL, NULL)); + cmc_assert(tm_min(map, NULL, NULL)); + cmc_assert_equals(size_t, 2, tm_get(map, 1)); + cmc_assert_not_equals(ptr, NULL, tm_get_ref(map, 1)); + cmc_assert(tm_contains(map, 1)); + + cmc_assert_equals(int32_t, 2, total_create); + cmc_assert_equals(int32_t, 5, total_read); + cmc_assert_equals(int32_t, 1, total_update); + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, 0, total_resize); + + cmc_assert_equals(ptr, NULL, map->callbacks); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + tm_free(map); + }); }); diff --git a/tests/main/unt/treeset.c b/tests/main/unt/treeset.c index 035de42..c1285c6 100644 --- a/tests/main/unt/treeset.c +++ b/tests/main/unt/treeset.c @@ -102,4 +102,66 @@ CMC_CREATE_UNIT(treeset_test, true, { ts_free(set); ts_free(set2); }); + + CMC_CREATE_TEST(callbacks, { + struct treeset *set = ts_new_custom(ts_ftab_val, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, set); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + cmc_assert(ts_insert(set, 10)); + cmc_assert_equals(int32_t, 1, total_create); + + cmc_assert(ts_remove(set, 10)); + cmc_assert_equals(int32_t, 1, total_delete); + + cmc_assert(ts_insert(set, 1)); + cmc_assert_equals(int32_t, 2, total_create); + + cmc_assert(ts_max(set, NULL)); + cmc_assert_equals(int32_t, 1, total_read); + + cmc_assert(ts_min(set, NULL)); + cmc_assert_equals(int32_t, 2, total_read); + + cmc_assert(ts_contains(set, 1)); + cmc_assert_equals(int32_t, 3, total_read); + + cmc_assert_equals(int32_t, 2, total_create); + cmc_assert_equals(int32_t, 3, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, 0, total_resize); + + ts_customize(set, NULL, NULL); + + ts_clear(set); + cmc_assert(ts_insert(set, 10)); + cmc_assert(ts_remove(set, 10)); + cmc_assert(ts_insert(set, 1)); + cmc_assert(ts_max(set, NULL)); + cmc_assert(ts_min(set, NULL)); + cmc_assert(ts_contains(set, 1)); + + cmc_assert_equals(int32_t, 2, total_create); + cmc_assert_equals(int32_t, 3, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, 0, total_resize); + + cmc_assert_equals(ptr, NULL, set->callbacks); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + ts_free(set); + }); });