update actions/upload-artifact
[liba.git] / test / avl.h
blob5d591b0f992ad9c8ab34cc0da3124b3544914066
1 #define MAIN_(x) A_CAST_2(x, _avl)
2 #include "test.h"
3 #include "a/avl.h"
4 #include "a/str.h"
6 typedef struct
8 a_avl_node node;
9 int data;
10 int height;
11 int reached;
12 } int_node;
14 static A_INLINE int int_factor(a_avl_node *node)
16 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 3)
17 return a_cast_s(int, node->_parent & 3) - 1;
18 #else /* !A_SIZE_POINTER */
19 return node->factor;
20 #endif /* A_SIZE_POINTER */
23 static A_INLINE int_node *int_entry(void const *node)
25 return a_cast_r(int_node *, a_cast_r(a_uptr, node) - a_offsetof(int_node, node)); // NOLINT
28 static int int_cmp(void const *lhs, void const *rhs)
30 return int_entry(lhs)->data - int_entry(rhs)->data;
33 #define int_max(a, b) ((a) > (b) ? (a) : (b))
34 #define int_height(node) ((node) ? int_entry(node)->height : 0)
35 static void set_height(a_avl_node *node) // NOLINT
37 if (node)
39 TEST_BUG(node->left != node);
40 TEST_BUG(node->right != node);
41 set_height(node->left);
42 set_height(node->right);
43 int const hl = int_height(node->left);
44 int const hr = int_height(node->right);
45 int_entry(node)->height = int_max(hl, hr) + 1;
49 static void check_tree(a_avl_node *node) // NOLINT
51 if (node)
53 int const e = int_factor(node);
54 TEST_BUG(-1 <= e && e <= 1);
55 TEST_BUG(int_height(node->right) - int_height(node->left) == e);
56 if (node->left)
58 TEST_BUG(int_entry(node->left)->data < int_entry(node)->data);
59 check_tree(node->left);
61 if (node->right)
63 TEST_BUG(int_entry(node->right)->data > int_entry(node)->data);
64 check_tree(node->right);
69 static int intcmp(void const *lhs, void const *rhs)
71 return *a_int_(const *, lhs) - *a_int_(const *, rhs);
74 static int test(int argc, char *argv[])
76 (void)(argc);
77 (void)(argv);
79 a_str str = A_STR_NUL;
80 a_avl root = A_AVL_ROOT;
81 unsigned int const n = 0x1000;
82 int_node *vec = a_new(int_node, A_NULL, n);
83 int *sorted = a_new(int, A_NULL, n);
84 for (unsigned int i = 0; i < n; ++i)
86 a_str_putf(&str, "%u", i);
87 vec[i].data = a_cast_s(int, a_hash_bkdr(a_str_ptr(&str), 0));
88 a_str_drop(&str);
89 sorted[i] = vec[i].data;
90 a_avl_insert(&root, &vec[i].node, int_cmp);
91 set_height(root.node);
92 check_tree(root.node);
93 if (i % 0x100 == 0)
95 debug("insert 0x%04X/0x%04X\n", i, n);
98 a_str_dtor(&str);
100 for (unsigned int i = 0; i < n; ++i)
102 TEST_BUG(a_avl_search(&root, &vec[i].node, int_cmp));
105 unsigned int x;
106 qsort(sorted, n, sizeof(int), intcmp);
108 x = 0;
109 for (unsigned int i = 0; i < n; ++i)
111 vec[i].reached = 0;
113 a_avl_foreach(cur, &root)
115 int_node *it = int_entry(cur);
116 TEST_BUG(it->data == sorted[x]);
117 it->reached = 1;
118 ++x;
120 for (unsigned int i = 0; i < n; ++i)
122 TEST_BUG(vec[i].reached);
124 TEST_BUG(x == n);
126 x = n;
127 for (unsigned int i = 0; i < n; ++i)
129 vec[i].reached = 0;
131 a_avl_foreach_reverse(cur, &root)
133 int_node *it = int_entry(cur);
134 TEST_BUG(it->data == sorted[--x]);
135 it->reached = 1;
137 for (unsigned int i = 0; i < n; ++i)
139 TEST_BUG(vec[i].reached);
141 TEST_BUG(x == 0);
143 for (unsigned int i = 0; i < n; ++i)
145 vec[i].reached = 0;
147 a_avl_pre_foreach(cur, &root)
149 int_node *it = int_entry(cur);
150 it->reached = 1;
152 for (unsigned int i = 0; i < n; ++i)
154 TEST_BUG(vec[i].reached);
157 for (unsigned int i = 0; i < n; ++i)
159 vec[i].reached = 0;
161 a_avl_pre_foreach_reverse(cur, &root)
163 int_node *it = int_entry(cur);
164 it->reached = 1;
166 for (unsigned int i = 0; i < n; ++i)
168 TEST_BUG(vec[i].reached);
171 for (unsigned int i = 0; i < n; ++i)
173 vec[i].reached = 0;
175 a_avl_post_foreach(cur, &root)
177 int_node *it = int_entry(cur);
178 it->reached = 1;
180 for (unsigned int i = 0; i < n; ++i)
182 TEST_BUG(vec[i].reached);
185 for (unsigned int i = 0; i < n; ++i)
187 vec[i].reached = 0;
189 a_avl_post_foreach_reverse(cur, &root)
191 int_node *it = int_entry(cur);
192 it->reached = 1;
194 for (unsigned int i = 0; i < n; ++i)
196 TEST_BUG(vec[i].reached);
199 for (unsigned int i = 0; i < n; ++i)
201 a_avl_remove(&root, &vec[i].node);
202 set_height(root.node);
203 check_tree(root.node);
204 if (i % 0x100 == 0)
206 debug("remove 0x%04X/0x%04X\n", i, n);
210 TEST_BUG(!a_avl_search(&root, &vec->node, int_cmp));
212 for (unsigned int i = 0; i < n; ++i)
214 a_avl_insert(&root, &vec[i].node, int_cmp);
215 vec[i].reached = 0;
217 a_avl_fortear(cur, next, &root)
219 int_entry(cur)->reached = 1;
221 for (unsigned int i = 0; i < n; ++i)
223 TEST_BUG(vec[i].reached);
226 a_die(vec);
227 a_die(sorted);
228 return 0;
231 int MAIN(int argc, char *argv[]) // NOLINT(misc-definitions-in-headers)
233 printf("%s\n", A_FUNC);
234 test(argc, argv);
235 return 0;