#include <config.h> #include <check.h> #include <stdlib.h> #include <stdarg.h> #include "emacs-compat.h" #define EMACS_LISP_H /* lisp.h inclusion guard */ #define ITREE_DEBUG 1 #define ITREE_TESTING #include "itree.c" /* Basic tests of the interval_tree data-structure. */ /* +===================================================================================+ * | Insert * +===================================================================================+ */ /* The graphs below display the trees after each insertion (as they should be). See the source code for the different cases applied. */ #define N_50 (n[0]) #define N_30 (n[1]) #define N_20 (n[2]) #define N_10 (n[3]) #define N_15 (n[4]) #define N_05 (n[5]) #define DEF_TEST_SETUP() \ struct interval_tree tree; \ struct interval_node n[6]; \ interval_tree_init (&tree); \ const int values[] = {50, 30, 20, 10, 15, 5}; \ for (int i = 0; i < 6; ++i) \ { \ n[i].begin = values[i]; \ n[i].end = values[i]; \ } START_TEST (test_insert_1) { /* * [50] */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); ck_assert (N_50.color == ITREE_BLACK); ck_assert (&N_50 == tree.root); } END_TEST START_TEST (test_insert_2) { /* * [50] * / * (30) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_30); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_30.color == ITREE_RED); ck_assert (&N_50 == tree.root); ck_assert (N_30.parent == &N_50); ck_assert (N_50.left == &N_30); ck_assert (N_50.right == &tree.nil); ck_assert (N_30.left == &tree.nil); ck_assert (N_30.right == &tree.nil); } END_TEST START_TEST (test_insert_3) { /* case 3.a * [30] * / \ * (20) (50) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_30); interval_tree_insert (&tree, &N_20); ck_assert (N_50.color == ITREE_RED); ck_assert (N_30.color == ITREE_BLACK); ck_assert (N_20.color == ITREE_RED); ck_assert (&N_30 == tree.root); ck_assert (N_50.parent == &N_30); ck_assert (N_30.right == &N_50); ck_assert (N_30.left == &N_20); ck_assert (N_20.left == &tree.nil); ck_assert (N_20.right == &tree.nil); ck_assert (N_20.parent == &N_30); } END_TEST START_TEST (test_insert_4) { /* 1.a * [30] * / \ * [20] [50] * / * (10) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_30); interval_tree_insert (&tree, &N_20); interval_tree_insert (&tree, &N_10); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_30.color == ITREE_BLACK); ck_assert (N_20.color == ITREE_BLACK); ck_assert (N_10.color == ITREE_RED); ck_assert (&N_30 == tree.root); ck_assert (N_50.parent == &N_30); ck_assert (N_30.right == &N_50); ck_assert (N_30.left == &N_20); ck_assert (N_20.left == &N_10); ck_assert (N_20.right == &tree.nil); ck_assert (N_20.parent == &N_30); ck_assert (N_10.parent == &N_20); ck_assert (N_20.left == &N_10); ck_assert (N_10.right == &tree.nil); } END_TEST START_TEST (test_insert_5) { /* 2.a * [30] * / \ * [15] [50] * / \ * (10) (20) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_30); interval_tree_insert (&tree, &N_20); interval_tree_insert (&tree, &N_10); interval_tree_insert (&tree, &N_15); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_30.color == ITREE_BLACK); ck_assert (N_20.color == ITREE_RED); ck_assert (N_10.color == ITREE_RED); ck_assert (N_15.color == ITREE_BLACK); ck_assert (&N_30 == tree.root); ck_assert (N_50.parent == &N_30); ck_assert (N_30.right == &N_50); ck_assert (N_30.left == &N_15); ck_assert (N_20.left == &tree.nil); ck_assert (N_20.right == &tree.nil); ck_assert (N_20.parent == &N_15); ck_assert (N_10.parent == &N_15); ck_assert (N_20.left == &tree.nil); ck_assert (N_10.right == &tree.nil); ck_assert (N_15.right == &N_20); ck_assert (N_15.left == &N_10); ck_assert (N_15.parent == &N_30); } END_TEST START_TEST (test_insert_6) { /* 1.a * [30] * / \ * (15) [50] * / \ * [10] [20] * / * (5) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_30); interval_tree_insert (&tree, &N_20); interval_tree_insert (&tree, &N_10); interval_tree_insert (&tree, &N_15); interval_tree_insert (&tree, &N_05); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_30.color == ITREE_BLACK); ck_assert (N_20.color == ITREE_BLACK); ck_assert (N_10.color == ITREE_BLACK); ck_assert (N_15.color == ITREE_RED); ck_assert (N_05.color == ITREE_RED); ck_assert (&N_30 == tree.root); ck_assert (N_50.parent == &N_30); ck_assert (N_30.right == &N_50); ck_assert (N_30.left == &N_15); ck_assert (N_20.left == &tree.nil); ck_assert (N_20.right == &tree.nil); ck_assert (N_20.parent == &N_15); ck_assert (N_10.parent == &N_15); ck_assert (N_20.left == &tree.nil); ck_assert (N_10.right == &tree.nil); ck_assert (N_15.right == &N_20); ck_assert (N_15.left == &N_10); ck_assert (N_15.parent == &N_30); ck_assert (N_05.parent == &N_10); ck_assert (N_10.left == &N_05); ck_assert (N_05.right == &tree.nil); } END_TEST #undef N_50 #undef N_30 #undef N_20 #undef N_10 #undef N_15 #undef N_05 #undef DEF_TEST_SETUP /* These are the mirror cases to the above ones. */ #define N_50 (n[0]) #define N_70 (n[1]) #define N_80 (n[2]) #define N_90 (n[3]) #define N_85 (n[4]) #define N_95 (n[5]) #define DEF_TEST_SETUP() \ struct interval_tree tree; \ struct interval_node n[6]; \ interval_tree_init (&tree); \ const int values[] = {50, 70, 80, 90, 85, 95}; \ for (int i = 0; i < 6; ++i) \ { \ n[i].begin = values[i]; \ n[i].end = values[i]; \ } START_TEST (test_insert_7) { /* * [50] */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); ck_assert (N_50.color == ITREE_BLACK); ck_assert (&N_50 == tree.root); } END_TEST START_TEST (test_insert_8) { /* * [50] * \ * (70) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_70); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_70.color == ITREE_RED); ck_assert (&N_50 == tree.root); ck_assert (N_70.parent == &N_50); ck_assert (N_50.right == &N_70); ck_assert (N_50.left == &tree.nil); ck_assert (N_70.right == &tree.nil); ck_assert (N_70.left == &tree.nil); } END_TEST START_TEST (test_insert_9) { /* 3.a * [70] * / \ * (50) (80) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_70); interval_tree_insert (&tree, &N_80); ck_assert (N_50.color == ITREE_RED); ck_assert (N_70.color == ITREE_BLACK); ck_assert (N_80.color == ITREE_RED); ck_assert (&N_70 == tree.root); ck_assert (N_50.parent == &N_70); ck_assert (N_70.right == &N_80); ck_assert (N_70.left == &N_50); ck_assert (N_80.right == &tree.nil); ck_assert (N_80.left == &tree.nil); ck_assert (N_80.parent == &N_70); } END_TEST START_TEST (test_insert_10) { /* 1.b * [70] * / \ * [50] [80] * \ * (90) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_70); interval_tree_insert (&tree, &N_80); interval_tree_insert (&tree, &N_90); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_70.color == ITREE_BLACK); ck_assert (N_80.color == ITREE_BLACK); ck_assert (N_90.color == ITREE_RED); ck_assert (&N_70 == tree.root); ck_assert (N_50.parent == &N_70); ck_assert (N_70.right == &N_80); ck_assert (N_70.left == &N_50); ck_assert (N_80.right == &N_90); ck_assert (N_80.left == &tree.nil); ck_assert (N_80.parent == &N_70); ck_assert (N_90.parent == &N_80); ck_assert (N_80.right == &N_90); ck_assert (N_90.left == &tree.nil); } END_TEST START_TEST (test_insert_11) { /* 2.b * [70] * / \ * [50] [85] * / \ * (80) (90) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_70); interval_tree_insert (&tree, &N_80); interval_tree_insert (&tree, &N_90); interval_tree_insert (&tree, &N_85); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_70.color == ITREE_BLACK); ck_assert (N_80.color == ITREE_RED); ck_assert (N_90.color == ITREE_RED); ck_assert (N_85.color == ITREE_BLACK); ck_assert (&N_70 == tree.root); ck_assert (N_50.parent == &N_70); ck_assert (N_70.right == &N_85); ck_assert (N_70.left == &N_50); ck_assert (N_80.right == &tree.nil); ck_assert (N_80.left == &tree.nil); ck_assert (N_80.parent == &N_85); ck_assert (N_90.parent == &N_85); ck_assert (N_80.right == &tree.nil); ck_assert (N_90.left == &tree.nil); ck_assert (N_85.right == &N_90); ck_assert (N_85.left == &N_80); ck_assert (N_85.parent == &N_70); } END_TEST START_TEST (test_insert_12) { /* 1.b * [70] * / \ * [50] (85) * / \ * [80] [90] * \ * (95) */ DEF_TEST_SETUP (); interval_tree_insert (&tree, &N_50); interval_tree_insert (&tree, &N_70); interval_tree_insert (&tree, &N_80); interval_tree_insert (&tree, &N_90); interval_tree_insert (&tree, &N_85); interval_tree_insert (&tree, &N_95); ck_assert (N_50.color == ITREE_BLACK); ck_assert (N_70.color == ITREE_BLACK); ck_assert (N_80.color == ITREE_BLACK); ck_assert (N_90.color == ITREE_BLACK); ck_assert (N_85.color == ITREE_RED); ck_assert (N_95.color == ITREE_RED); ck_assert (&N_70 == tree.root); ck_assert (N_50.parent == &N_70); ck_assert (N_70.right == &N_85); ck_assert (N_70.left == &N_50); ck_assert (N_80.right == &tree.nil); ck_assert (N_80.left == &tree.nil); ck_assert (N_80.parent == &N_85); ck_assert (N_90.parent == &N_85); ck_assert (N_80.right == &tree.nil); ck_assert (N_90.left == &tree.nil); ck_assert (N_85.right == &N_90); ck_assert (N_85.left == &N_80); ck_assert (N_85.parent == &N_70); ck_assert (N_95.parent == &N_90); ck_assert (N_90.right == &N_95); ck_assert (N_95.left == &tree.nil); } END_TEST #undef N_50 #undef N_70 #undef N_80 #undef N_90 #undef N_85 #undef N_95 #undef DEF_TEST_SETUP struct interval_tree* test_get_tree4 (struct interval_node **n) { static struct interval_tree tree; static struct interval_node nodes[4]; memset (&tree, 0, sizeof (struct interval_tree)); memset (&nodes, 0, 4 * sizeof (struct interval_node)); interval_tree_init (&tree); for (int i = 0; i < 4; ++i) { nodes[i].begin = 10 * (i + 1); nodes[i].end = nodes[i].begin; interval_tree_insert (&tree, &nodes[i]); } *n = nodes; return &tree; } static void shuffle (int *index, int n) { for (int i = n - 1; i >= 0; --i) { int j = random () % (i + 1); int h = index[j]; index[j] = index[i]; index[i] = h; } } #define N_10 (nodes[0]) #define N_20 (nodes[1]) #define N_30 (nodes[2]) #define N_40 (nodes[3]) START_TEST (test_insert_13) { struct interval_node *nodes = NULL; struct interval_tree *tree = test_get_tree4 (&nodes); ck_assert (tree->root == &N_20); ck_assert (N_20.left == &N_10); ck_assert (N_20.right == &N_30); ck_assert (N_30.right == &N_40); ck_assert (N_10.color == ITREE_BLACK); ck_assert (N_20.color == ITREE_BLACK); ck_assert (N_30.color == ITREE_BLACK); ck_assert (N_40.color == ITREE_RED); } END_TEST START_TEST (test_insert_14) { struct interval_tree tree; struct interval_node nodes[3]; nodes[0].begin = nodes[1].begin = nodes[2].begin = 10; nodes[0].end = nodes[1].end = nodes[2].end = 10; for (int i = 0; i < 3; ++i) interval_tree_insert (&tree, &nodes[i]); for (int i = 0; i < 3; ++i) ck_assert (interval_tree_contains (&tree, &nodes[i])); } END_TEST /* +===================================================================================+ * | Remove * +===================================================================================+ */ #define A (nodes[0]) #define B (nodes[1]) #define C (nodes[2]) #define D (nodes[3]) #define E (nodes[4]) /* Creating proper test trees for the formal tests via insertions is way to tedious, so we just fake it and only test the fix-routine. */ #define DEF_TEST_SETUP() \ struct interval_tree tree; \ struct interval_node nodes[5]; \ interval_tree_init (&tree); \ tree.root = &B; \ A.parent = &B; B.parent = &tree.nil; C.parent = &D; \ D.parent = &B; E.parent = &D; \ A.left = A.right = C.left = C.right = &tree.nil; \ E.left = E.right = &tree.nil; \ B.left = &A; B.right = &D; D.left = &C; D.right = &E \ /* 1.a -> 2.a * [B] * / \ * [A] (D) * / \ * [C] [E] */ START_TEST (test_remove_1) { DEF_TEST_SETUP (); B.color = A.color = C.color = E.color = ITREE_BLACK; D.color = ITREE_RED; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_RED); ck_assert (D.color == ITREE_BLACK); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.left == &A); ck_assert (B.right == &C); ck_assert (C.parent == &B); ck_assert (E.parent == &D); ck_assert (D.right == &E); ck_assert (D.left == &B); ck_assert (tree.root == &D); } END_TEST /* 2.a */ START_TEST (test_remove_2) { DEF_TEST_SETUP (); B.color = D.color = A.color = C.color = E.color = ITREE_BLACK; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_BLACK); ck_assert (D.color == ITREE_RED); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.left == &A); ck_assert (B.right == &D); ck_assert (C.parent == &D); ck_assert (E.parent == &D); ck_assert (tree.root == &B); } END_TEST /* 3.a -> 4.a*/ START_TEST (test_remove_3) { DEF_TEST_SETUP (); D.color = A.color = E.color = ITREE_BLACK; B.color = C.color = ITREE_RED; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_BLACK); ck_assert (D.color == ITREE_BLACK); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.left == &A); ck_assert (B.right == &tree.nil); ck_assert (&C == tree.root); ck_assert (C.left == &B); ck_assert (C.right == &D); ck_assert (E.parent == &D); ck_assert (D.left == &tree.nil); } END_TEST /* 4.a */ START_TEST (test_remove_4) { DEF_TEST_SETUP (); B.color = C.color = E.color = ITREE_RED; A.color = D.color = ITREE_BLACK; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_RED); ck_assert (D.color == ITREE_BLACK); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.left == &A); ck_assert (B.right == &C); ck_assert (C.parent == &B); ck_assert (E.parent == &D); ck_assert (tree.root == &D); } END_TEST #undef A #undef B #undef C #undef D #undef E #undef DEF_TEST_SETUP /* These are the mirrored cases. */ #define A (nodes[0]) #define B (nodes[1]) #define C (nodes[2]) #define D (nodes[3]) #define E (nodes[4]) #define DEF_TEST_SETUP() \ struct interval_tree tree; \ struct interval_node nodes[5]; \ interval_tree_init (&tree); \ tree.root = &B; \ A.parent = &B; B.parent = &tree.nil; C.parent = &D; \ D.parent = &B; E.parent = &D; \ A.right = A.left = C.right = C.left = &tree.nil; \ E.right = E.left = &tree.nil; \ B.right = &A; B.left = &D; D.right = &C; D.left = &E \ /* 1.b -> 2.b * [B] * / \ * [A] (D) * / \ * [C] [E] */ START_TEST (test_remove_5) { DEF_TEST_SETUP (); B.color = A.color = C.color = E.color = ITREE_BLACK; D.color = ITREE_RED; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_RED); ck_assert (D.color == ITREE_BLACK); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.right == &A); ck_assert (B.left == &C); ck_assert (C.parent == &B); ck_assert (E.parent == &D); ck_assert (D.left == &E); ck_assert (D.right == &B); ck_assert (tree.root == &D); } END_TEST /* 2.b */ START_TEST (test_remove_6) { DEF_TEST_SETUP (); B.color = D.color = A.color = C.color = E.color = ITREE_BLACK; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_BLACK); ck_assert (D.color == ITREE_RED); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.right == &A); ck_assert (B.left == &D); ck_assert (C.parent == &D); ck_assert (E.parent == &D); ck_assert (tree.root == &B); } END_TEST /* 3.b -> 4.b*/ START_TEST (test_remove_7) { DEF_TEST_SETUP (); D.color = A.color = E.color = ITREE_BLACK; B.color = C.color = ITREE_RED; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_BLACK); ck_assert (D.color == ITREE_BLACK); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.right == &A); ck_assert (B.left == &tree.nil); ck_assert (&C == tree.root); ck_assert (C.right == &B); ck_assert (C.left == &D); ck_assert (E.parent == &D); ck_assert (D.right == &tree.nil); } END_TEST /* 4.b */ START_TEST (test_remove_8) { DEF_TEST_SETUP (); B.color = C.color = E.color = ITREE_RED; A.color = D.color = ITREE_BLACK; interval_tree_remove_fix (&tree, &A); ck_assert (A.color == ITREE_BLACK); ck_assert (B.color == ITREE_BLACK); ck_assert (C.color == ITREE_RED); ck_assert (D.color == ITREE_BLACK); ck_assert (E.color == ITREE_BLACK); ck_assert (A.parent == &B); ck_assert (B.right == &A); ck_assert (B.left == &C); ck_assert (C.parent == &B); ck_assert (E.parent == &D); ck_assert (tree.root == &D); } END_TEST #undef A #undef B #undef C #undef D #undef E #undef DEF_TEST_SETUP START_TEST (test_remove_9) { struct interval_node *nodes = NULL; struct interval_tree *tree = test_get_tree4 (&nodes); ck_assert (tree->root == &N_20); ck_assert (N_20.left == &N_10); ck_assert (N_20.right == &N_30); ck_assert (N_30.right == &N_40); ck_assert (N_20.color == ITREE_BLACK); ck_assert (N_10.color == ITREE_BLACK); ck_assert (N_30.color == ITREE_BLACK); ck_assert (N_40.color == ITREE_RED); interval_tree_remove (tree, &N_10); ck_assert (tree->root == &N_30); ck_assert (N_30.parent == &tree->nil); ck_assert (N_30.left == &N_20); ck_assert (N_30.right == &N_40); ck_assert (N_20.color == ITREE_BLACK); ck_assert (N_30.color == ITREE_BLACK); ck_assert (N_40.color == ITREE_BLACK); } END_TEST #define N 3 START_TEST (test_remove_10) { struct interval_tree tree; struct interval_node nodes[N]; int index[N]; srand (42); interval_tree_init (&tree); for (int i = 0; i < N; ++i) { nodes[i].begin = (i + 1) * 10; nodes[i].end = nodes[i].begin + 1; index[i] = i; } shuffle (index, N); for (int i = 0; i < N; ++i) interval_tree_insert (&tree, &nodes[index[i]]); shuffle (index, N); for (int i = 0; i < N; ++i) { ck_assert (interval_tree_contains (&tree, &nodes[index[i]])); interval_tree_remove (&tree, &nodes[index[i]]); } ck_assert (tree.root == &tree.nil); ck_assert (tree.size == 0); } END_TEST /* +===================================================================================+ * | Generator * +===================================================================================+ */ START_TEST (test_generator_1) { struct interval_tree tree; struct interval_node node, *n; struct interval_generator *g; interval_tree_init (&tree); node.begin = 10; node.end = 20; interval_tree_insert (&tree, &node); g = interval_generator_create (&tree); interval_generator_reset (g, 0, 30, ITREE_ASCENDING); n = interval_generator_next (g); ck_assert (n == &node); ck_assert (n->begin == 10 && n->end == 20); ck_assert (interval_generator_next (g) == NULL); ck_assert (interval_generator_next (g) == NULL); ck_assert (interval_generator_next (g) == NULL); interval_generator_destroy (g); g = interval_generator_create (&tree); interval_generator_reset (g, 30, 50, ITREE_ASCENDING); ck_assert (interval_generator_next (g) == NULL); ck_assert (interval_generator_next (g) == NULL); ck_assert (interval_generator_next (g) == NULL); interval_generator_destroy (g); } END_TEST void test_check_generator (struct interval_tree *tree, ptrdiff_t begin, ptrdiff_t end, int n, ...) { va_list ap; struct interval_generator *g = interval_generator_create (tree); interval_generator_reset (g, begin, end, ITREE_ASCENDING); va_start (ap, n); for (int i = 0; i < n; ++i) { ptrdiff_t begin = va_arg (ap, ptrdiff_t); struct interval_node *node = interval_generator_next (g); ck_assert (node); ck_assert_int_eq (node->begin, begin); } va_end (ap); ck_assert (! interval_generator_next (g)); ck_assert (! interval_generator_next (g)); interval_generator_destroy (g); } #define DEF_TEST_SETUP() \ START_TEST (test_generator_2) { struct interval_tree tree; struct interval_node nodes[3]; interval_tree_init (&tree); for (int i = 0; i < 3; ++i) { nodes[i].begin = 10 * (i + 1); nodes[i].end = 10 * (i + 2); interval_tree_insert (&tree, &nodes[i]); } test_check_generator (&tree, 0, 50, 3, 10, 20, 30); test_check_generator (&tree, 0, 10, 0); test_check_generator (&tree, 40, 50, 0); test_check_generator (&tree, 15, 35, 3, 10, 20, 30); test_check_generator (&tree, -100, -50, 0); test_check_generator (&tree, -100, -50, 0); test_check_generator (&tree, 100, 50, 0); test_check_generator (&tree, 100, 150, 0); test_check_generator (&tree, 0, 0, 0); test_check_generator (&tree, 40, 40, 0); test_check_generator (&tree, 30, 30, 0); test_check_generator (&tree, 35, 35, 1, 30); } END_TEST struct interval_node* test_create_tree (struct interval_tree *tree, int n, bool doshuffle, ...) { va_list ap; struct interval_node *nodes = calloc (n, sizeof (struct interval_node)); int *index = calloc (n, sizeof (int)); interval_tree_init (tree); va_start (ap, doshuffle); for (int i = 0; i < n; ++i) { ptrdiff_t begin = va_arg (ap, ptrdiff_t); ptrdiff_t end = va_arg (ap, ptrdiff_t); nodes[i].begin = begin; nodes[i].end = end; index[i] = i; } va_end (ap); srand (42); if (doshuffle) shuffle (index, n); for (int i = 0; i < n; ++i) interval_tree_insert (tree, &nodes[index[i]]); free (index); return nodes; } START_TEST (test_generator_3) { struct interval_tree tree; struct interval_node *nodes = NULL; nodes = test_create_tree (&tree, 3, true, 10, 10, 10, 10, 10, 10); test_check_generator (&tree, 0, 10, 0); test_check_generator (&tree, 10, 10, 3, 10, 10, 10); test_check_generator (&tree, 10, 20, 3, 10, 10, 10); free (nodes); } END_TEST #define FOREACH(n, g) \ for ((n) = interval_generator_next (g); (n) != NULL; \ (n) = interval_generator_next (g)) START_TEST (test_generator_5) { struct interval_tree tree; struct interval_node *nodes; struct interval_generator *g; nodes = test_create_tree (&tree, 4, false, 10, 30, 20, 40, 30, 50, 40, 60); g = interval_generator_create (&tree); interval_generator_reset (g, 0, 100, ITREE_PRE_ORDER); for (int i = 0; i < 4; ++i) { struct interval_node *n = interval_generator_next (g); ck_assert (n); switch (i) { case 0: ck_assert_int_eq (20, n->begin); break; case 1: ck_assert_int_eq (10, n->begin); break; case 2: ck_assert_int_eq (30, n->begin); break; case 3: ck_assert_int_eq (40, n->begin); break; } } interval_generator_destroy (g); free (nodes); } END_TEST START_TEST (test_generator_6) { struct interval_tree tree; struct interval_node *nodes; struct interval_generator *g; nodes = test_create_tree (&tree, 4, true, 10, 30, 20, 40, 30, 50, 40, 60); g = interval_generator_create (&tree); interval_generator_reset (g, 0, 100, ITREE_ASCENDING); for (int i = 0; i < 4; ++i) { struct interval_node *n = interval_generator_next (g); ck_assert (n); switch (i) { case 0: ck_assert_int_eq (10, n->begin); break; case 1: ck_assert_int_eq (20, n->begin); break; case 2: ck_assert_int_eq (30, n->begin); break; case 3: ck_assert_int_eq (40, n->begin); break; } } interval_generator_destroy (g); free (nodes); } END_TEST START_TEST (test_generator_7) { struct interval_tree tree; struct interval_node *nodes; struct interval_generator *g; nodes = test_create_tree (&tree, 4, true, 10, 30, 20, 40, 30, 50, 40, 60); g = interval_generator_create (&tree); interval_generator_reset (g, 0, 100, ITREE_DESCENDING); for (int i = 0; i < 4; ++i) { struct interval_node *n = interval_generator_next (g); ck_assert (n); switch (i) { case 0: ck_assert_int_eq (40, n->begin); break; case 1: ck_assert_int_eq (30, n->begin); break; case 2: ck_assert_int_eq (20, n->begin); break; case 3: ck_assert_int_eq (10, n->begin); break; } } interval_generator_destroy (g); free (nodes); } END_TEST START_TEST (test_generator_8) { struct interval_tree tree; struct interval_node *nodes, *n; struct interval_generator *g; nodes = test_create_tree (&tree, 2, false, 20, 30, 40, 50); g = interval_generator_create (&tree); interval_generator_reset (g, 1, 60, ITREE_DESCENDING); n = interval_generator_next (g); ck_assert_int_eq (n->begin, 40); interval_generator_narrow (g, 50, 60); n = interval_generator_next (g); ck_assert (n == NULL); free (nodes); } END_TEST START_TEST (test_generator_9) { struct interval_tree tree; struct interval_node *nodes, *n; struct interval_generator *g; nodes = test_create_tree (&tree, 2, false, 25, 25, 20, 30); g = interval_generator_create (&tree); interval_generator_reset (g, 1, 30, ITREE_DESCENDING); n = interval_generator_next (g); ck_assert_int_eq (n->begin, 25); interval_generator_narrow (g, 25, 35); n = interval_generator_next (g); ck_assert_int_eq (n->begin, 20); free (nodes); } END_TEST /* +===================================================================================+ * | Insert Gap * +===================================================================================+ */ static struct interval_tree gap_tree; static struct interval_node gap_node; #define N_BEG (interval_tree_validate (&gap_tree, &gap_node)->begin) #define N_END (interval_tree_validate (&gap_tree, &gap_node)->end) static void test_setup_gap_node (ptrdiff_t begin, ptrdiff_t end, bool front_advance, bool rear_advance) { interval_tree_init (&gap_tree); gap_node.begin = begin; gap_node.end = end; gap_node.front_advance = front_advance; gap_node.rear_advance = rear_advance; interval_tree_insert (&gap_tree, &gap_node); } static void test_setup_gap_node_noadvance (ptrdiff_t begin, ptrdiff_t end) { test_setup_gap_node (begin, end, false, false); } START_TEST (test_gap_insert_1) { test_setup_gap_node (100, 200, false, false); interval_tree_insert_gap (&gap_tree, 100 + 10, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200 + 20); } END_TEST START_TEST (test_gap_insert_2) { test_setup_gap_node (100, 200, false, false); interval_tree_insert_gap (&gap_tree, 300, 10); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200); } END_TEST START_TEST (test_gap_insert_3) { test_setup_gap_node (100, 200, false, false); interval_tree_insert_gap (&gap_tree, 0, 15); ck_assert_int_eq (N_BEG, 100 + 15); ck_assert_int_eq (N_END, 200 + 15); } END_TEST START_TEST (test_gap_insert_4) { test_setup_gap_node (100, 200, true, false); interval_tree_insert_gap (&gap_tree, 100, 20); ck_assert_int_eq (N_BEG, 100 + 20); ck_assert_int_eq (N_END, 200 + 20); } END_TEST START_TEST (test_gap_insert_5) { test_setup_gap_node (100, 200, false, false); interval_tree_insert_gap (&gap_tree, 100, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200 + 20); } END_TEST START_TEST (test_gap_insert_6) { test_setup_gap_node (100, 200, false, true); interval_tree_insert_gap (&gap_tree, 200, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200 + 20); } END_TEST START_TEST (test_gap_insert_7) { test_setup_gap_node (100, 200, false, false); interval_tree_insert_gap (&gap_tree, 200, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200); } END_TEST START_TEST (test_gap_insert_8) { test_setup_gap_node (100, 100, true, true); interval_tree_insert_gap (&gap_tree, 100, 20); ck_assert_int_eq (N_BEG, 100 + 20); ck_assert_int_eq (N_END, 100 + 20); } END_TEST START_TEST (test_gap_insert_9) { test_setup_gap_node (100, 100, false, true); interval_tree_insert_gap (&gap_tree, 100, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 100 + 20); } END_TEST START_TEST (test_gap_insert_10) { test_setup_gap_node (100, 100, true, false); interval_tree_insert_gap (&gap_tree, 100, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 100); } END_TEST START_TEST (test_gap_insert_11) { test_setup_gap_node (100, 100, false, false); interval_tree_insert_gap (&gap_tree, 100, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 100); } END_TEST /* +===================================================================================+ * | Delete Gap * +===================================================================================+ */ START_TEST (test_gap_delete_1) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 100 + 10, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200 - 20); } END_TEST START_TEST (test_gap_delete_2) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 200 + 10, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200); } END_TEST START_TEST (test_gap_delete_3) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 200, 20); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 200); } END_TEST START_TEST (test_gap_delete_4) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 100 - 20, 20); ck_assert_int_eq (N_BEG, 100 - 20); ck_assert_int_eq (N_END, 200 - 20); } END_TEST START_TEST (test_gap_delete_5) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 70, 20); ck_assert_int_eq (N_BEG, 100 - 20); ck_assert_int_eq (N_END, 200 - 20); } END_TEST START_TEST (test_gap_delete_6) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 80, 100); ck_assert_int_eq (N_BEG, 80); ck_assert_int_eq (N_END, 100); } END_TEST START_TEST (test_gap_delete_7) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 120, 100); ck_assert_int_eq (N_BEG, 100); ck_assert_int_eq (N_END, 120); } END_TEST START_TEST (test_gap_delete_8) { test_setup_gap_node_noadvance (100, 200); interval_tree_delete_gap (&gap_tree, 100 - 20, 200 + 20); ck_assert_int_eq (N_BEG, 100 - 20); ck_assert_int_eq (N_END, 100 - 20); } END_TEST Suite * basic_suite () { Suite *s = suite_create ("basic_suite"); TCase *tc = tcase_create ("basic_test"); tcase_add_test (tc, test_insert_1); tcase_add_test (tc, test_insert_2); tcase_add_test (tc, test_insert_3); tcase_add_test (tc, test_insert_4); tcase_add_test (tc, test_insert_5); tcase_add_test (tc, test_insert_6); tcase_add_test (tc, test_insert_7); tcase_add_test (tc, test_insert_8); tcase_add_test (tc, test_insert_9); tcase_add_test (tc, test_insert_10); tcase_add_test (tc, test_insert_11); tcase_add_test (tc, test_insert_12); tcase_add_test (tc, test_insert_13); tcase_add_test (tc, test_remove_1); tcase_add_test (tc, test_remove_2); tcase_add_test (tc, test_remove_3); tcase_add_test (tc, test_remove_4); tcase_add_test (tc, test_remove_5); tcase_add_test (tc, test_remove_6); tcase_add_test (tc, test_remove_7); tcase_add_test (tc, test_remove_8); tcase_add_test (tc, test_remove_9); tcase_add_test (tc, test_remove_10); tcase_add_test (tc, test_generator_1); tcase_add_test (tc, test_generator_2); tcase_add_test (tc, test_generator_3); tcase_add_test (tc, test_generator_5); tcase_add_test (tc, test_generator_6); tcase_add_test (tc, test_generator_7); tcase_add_test (tc, test_generator_8); tcase_add_test (tc, test_generator_9); tcase_add_test (tc, test_gap_insert_1); tcase_add_test (tc, test_gap_insert_2); tcase_add_test (tc, test_gap_insert_3); tcase_add_test (tc, test_gap_insert_4); tcase_add_test (tc, test_gap_insert_5); tcase_add_test (tc, test_gap_insert_6); tcase_add_test (tc, test_gap_insert_7); tcase_add_test (tc, test_gap_insert_8); tcase_add_test (tc, test_gap_insert_9); tcase_add_test (tc, test_gap_insert_10); tcase_add_test (tc, test_gap_insert_11); tcase_add_test (tc, test_gap_delete_1); tcase_add_test (tc, test_gap_delete_2); tcase_add_test (tc, test_gap_delete_3); tcase_add_test (tc, test_gap_delete_4); tcase_add_test (tc, test_gap_delete_5); tcase_add_test (tc, test_gap_delete_6); tcase_add_test (tc, test_gap_delete_7); tcase_add_test (tc, test_gap_delete_8); /* tcase_set_timeout (tc, 120); */ suite_add_tcase (s, tc); return s; } int main (void) { int nfailed; Suite *s = basic_suite (); SRunner *sr = srunner_create (s); srunner_run_all (sr, CK_NORMAL); nfailed = srunner_ntests_failed (sr); srunner_free (sr); return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; }