From e8c6df02a8ebf65ea7a6c87e070d759b27e36803 Mon Sep 17 00:00:00 2001 From: Nguyen Ba Ngoc Date: Fri, 14 Jan 2022 16:56:59 +0700 Subject: [PATCH] =?UTF-8?q?Ki=E1=BB=83m=20th=E1=BB=AD=20ng=E1=BA=ABu=20nhi?= =?UTF-8?q?=C3=AAn=20rbm=20&=20rbs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 4 ++- rbm.h | 22 +++++++------- rbs.h | 2 +- tests/CMakeLists.txt | 3 +- tests/rbm/CMakeLists.txt | 5 ++++ tests/rbm/rbm_rand_i_ut.c | 61 +++++++++++++++++++++++++++++++++++++++ tests/rbs/CMakeLists.txt | 3 +- tests/rbs/rbs_rand_ut.c | 54 ++++++++++++++++++++++++++++++++++ 8 files changed, 139 insertions(+), 15 deletions(-) create mode 100644 tests/rbm/CMakeLists.txt create mode 100644 tests/rbm/rbm_rand_i_ut.c create mode 100644 tests/rbs/rbs_rand_ut.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 017bbcd6..01315668 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,4 +78,6 @@ add_test(NAME HashSetRandUT COMMAND hset_rand_ut) add_test(NAME GvecVoidUT COMMAND gvec_v_ut) add_test(NAME SpacesUT COMMAND spaces_ut) add_test(NAME SplitUT COMMAND split_ut) -add_test(NAME RbsStrUt COMMAND rbs_str_ut) \ No newline at end of file +add_test(NAME RbsStrUt COMMAND rbs_str_ut) +add_test(NAME RbmRandiUt COMMAND rbm_rand_i_ut 1000) +add_test(NAME RbsRandUt COMMAND rbs_rand_ut 1000) \ No newline at end of file diff --git a/rbm.h b/rbm.h index 2b9745e3..3b27b0c6 100644 --- a/rbm.h +++ b/rbm.h @@ -167,29 +167,29 @@ static inline void _rbm_move_next(gtype **k, gtype **v) { * Tham khảo: #hmap_traverse(key, value, map) */ #define rbm_traverse(k, v, map) \ - for (gtype *k = &(rbm_node_key(bn_left_most((map)->t.root))), \ - *v = &(rbm_node_value(bn_left_most((map)->t.root))); \ + for (gtype *k = (rbm_size(map))? &(rbm_node_key(bn_left_most((map)->t.root))): NULL_PTR, \ + *v = (rbm_size(map))? &(rbm_node_value(bn_left_most((map)->t.root))): NULL_PTR; \ k != NULL_PTR && v != NULL_PTR; _rbm_move_next(&k, &v)) \ /** * Giải phóng bộ nhớ được cấp phát cho bảng m. Các hàm free_key và * free_value được gọi cho từng khóa và giá trị nếu != NULL. * - * @param t Con trỏ tới bảng cây. + * @param map Con trỏ tới bảng cây. */ -#define rbm_free(t) \ +#define rbm_free(map) \ do { \ - if ((t)->free_key || (t)->free_value) { \ - rbm_traverse(_k, _v, (t)) { \ - if ((t)->free_key) { \ - (t)->free_key(*_k); \ + if ((map)->free_key || (map)->free_value) { \ + rbm_traverse(_k, _v, (map)) { \ + if ((map)->free_key) { \ + (map)->free_key(*_k); \ } \ - if ((t)->free_value) { \ - (t)->free_value(*_v); \ + if ((map)->free_value) { \ + (map)->free_value(*_v); \ } \ } \ } \ - bn_free_tree((bn_tree_t)(t)); \ + bn_free_tree((bn_tree_t)(map)); \ } while (0) #endif // RBM_H_ diff --git a/rbs.h b/rbs.h index 352a85bc..f39c7c7a 100644 --- a/rbs.h +++ b/rbs.h @@ -44,7 +44,7 @@ static inline void _rbs_move_next(gtype **cur) { #define rbs_size(s) ((s)->size) #define rbs_traverse(cur, s) \ - for (gtype *cur = &(rbs_node_value(bn_left_most((s)->t.root))); \ + for (gtype *cur = (rbs_size(s))? &(rbs_node_value(bn_left_most((s)->t.root))): NULL_PTR; \ cur != NULL_PTR; _rbs_move_next(&cur)) #define rbs_free(s) \ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d93e9bb3..df3f3633 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,4 +13,5 @@ add_subdirectory(rbs) add_subdirectory(p1w) add_subdirectory(gvec) add_subdirectory(hset) -add_subdirectory(str) \ No newline at end of file +add_subdirectory(str) +add_subdirectory(rbm) \ No newline at end of file diff --git a/tests/rbm/CMakeLists.txt b/tests/rbm/CMakeLists.txt new file mode 100644 index 00000000..59c8f8f1 --- /dev/null +++ b/tests/rbm/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(rbm_rand_i_ut rbm_rand_i_ut.c) + +foreach (p rbm_rand_i_ut) + target_link_libraries(${p} bkc) +endforeach() \ No newline at end of file diff --git a/tests/rbm/rbm_rand_i_ut.c b/tests/rbm/rbm_rand_i_ut.c new file mode 100644 index 00000000..90e31a2d --- /dev/null +++ b/tests/rbm/rbm_rand_i_ut.c @@ -0,0 +1,61 @@ +/* + (C) Nguyen Ba Ngoc 2022 + Kiểm tra kịch bản ánh xạ chuỗi -> chuỗi +*/ + +#include "cgen.h" +#include "tests/base/utils.h" + +#include +#include +#include + +#define BUFF_SIZE 32 +char buff[BUFF_SIZE] = {0}; + +void gen_buff() { + for (int i = 0; i < BUFF_SIZE - 1; ++i) { + buff[i] = 'a' + rand() % ('z' - 'a' + 1); + buff[BUFF_SIZE - 1]; + } +} + +int main(int argc, char *argv[]) { + int n; + sscanf(argv[1], "%d", &n); + rbm_t map = rbm_create(gtype_cmp_s, gtype_free_s, gtype_free_s); + srand(time(NULL)); + char **keys = malloc(n * sizeof(char *)), + **values = malloc(n * sizeof(char *)); + long cc = 0; + for (int i = 0; i < n; ++i) { + gen_buff(); + char *tmp = strdup(buff); + rbm_ires ires = rbm_insert(map, gtype_s(tmp), gtype_s(NULL)); + if (!ires.inserted) { + CHECK_MSG(rbm_size(map) == bn_size((bn_tree_t)map), "Size equal bn_size"); + CHECK_MSG(rbm_size(map) == cc, "size == cc"); + free(tmp); + continue; + } + keys[cc] = tmp; + gen_buff(); + values[cc] = strdup(buff); + ires.value->s = values[cc]; + ++cc; + CHECK_MSG(rbm_size(map) == bn_size((bn_tree_t)map), "Size equal bn_size"); + CHECK_MSG(rbm_size(map) == cc, "size == cc"); + } + int sz = cc; + for (int i = 0; i < sz; ++i) { + CHECK_MSG(rbm_value(map, gtype_s(keys[i]))->s == values[i], "Point to the same place"); + CHECK_MSG(rbm_remove(map, gtype_s(keys[i])) == 1, "Remove key i"); + --cc; + CHECK_MSG(rbm_size(map) == bn_size((bn_tree_t)map), "Size equal bn_size"); + CHECK_MSG(rbm_size(map) == cc, "size == cc"); + } + rbm_free(map); + free(keys); + free(values); + TEST_OK(); +} \ No newline at end of file diff --git a/tests/rbs/CMakeLists.txt b/tests/rbs/CMakeLists.txt index 5310fc12..b2054969 100644 --- a/tests/rbs/CMakeLists.txt +++ b/tests/rbs/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable(rbs_i_ut rbs_i_ut.c) add_executable(rbs_str_ut rbs_str_ut.c) +add_executable(rbs_rand_ut rbs_rand_ut.c) -foreach (p rbs_i_ut rbs_str_ut) +foreach (p rbs_i_ut rbs_str_ut rbs_rand_ut) target_link_libraries(${p} bkc) endforeach() \ No newline at end of file diff --git a/tests/rbs/rbs_rand_ut.c b/tests/rbs/rbs_rand_ut.c new file mode 100644 index 00000000..5d4540f9 --- /dev/null +++ b/tests/rbs/rbs_rand_ut.c @@ -0,0 +1,54 @@ +/* + (C) Nguyen Ba Ngoc 2022 + Kiểm tra kịch bản ánh xạ chuỗi -> chuỗi +*/ + +#include "cgen.h" +#include "tests/base/utils.h" + +#include +#include +#include + +#define BUFF_SIZE 32 +char buff[BUFF_SIZE] = {0}; + +void gen_buff() { + for (int i = 0; i < BUFF_SIZE - 1; ++i) { + buff[i] = 'a' + rand() % ('z' - 'a' + 1); + buff[BUFF_SIZE - 1]; + } +} + +int main(int argc, char *argv[]) { + int n; + sscanf(argv[1], "%d", &n); + rbs_t s = rbs_create(gtype_cmp_s, gtype_free_s); + srand(time(NULL)); + char **keys = malloc(n * sizeof(char *)); + long cc = 0; + for (int i = 0; i < n; ++i) { + gen_buff(); + char *tmp = strdup(buff); + if (!rbs_insert(s, gtype_s(tmp))) { + CHECK_MSG(rbs_size(s) == bn_size((bn_tree_t)s), "Size equal bn_size"); + CHECK_MSG(rbs_size(s) == cc, "size == cc"); + free(tmp); + continue; + } + keys[cc] = tmp; + ++cc; + CHECK_MSG(rbs_size(s) == bn_size((bn_tree_t)s), "Size equal bn_size"); + CHECK_MSG(rbs_size(s) == cc, "size == cc"); + } + int sz = cc; + for (int i = 0; i < sz; ++i) { + CHECK_MSG(rbs_remove(s, gtype_s(keys[i])) == 1, "Remove key i"); + --cc; + CHECK_MSG(rbs_size(s) == bn_size((bn_tree_t)s), "Size equal bn_size"); + CHECK_MSG(rbs_size(s) == cc, "size == cc"); + } + rbs_free(s); + free(keys); + TEST_OK(); +} \ No newline at end of file