15 static A_INLINE
int int_factor(a_avl_node
*node
)
17 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 3)
18 return a_cast_s(int, node
->parent_
& 3) - 1;
19 #else /* !A_SIZE_POINTER */
21 #endif /* A_SIZE_POINTER */
24 static A_INLINE int_node
*int_entry(void const *node
)
26 return a_cast_r(int_node
*, a_cast_r(a_uptr
, node
) - a_offsetof(int_node
, node
)); /* NOLINT */
29 static int int_cmp(void const *lhs
, void const *rhs
)
31 int a
= int_entry(lhs
)->data
;
32 int b
= int_entry(rhs
)->data
;
33 return (a
> b
) - (a
< b
);
36 static int intcmp(void const *lhs
, void const *rhs
)
38 int a
= *a_int_(const *, lhs
);
39 int b
= *a_int_(const *, rhs
);
40 return (a
> b
) - (a
< b
);
43 #define int_height(node) ((node) ? int_entry(node)->height : 0)
44 static void set_height(a_avl_node
*node
) /* NOLINT */
49 TEST_BUG(node
->left
!= node
);
50 TEST_BUG(node
->right
!= node
);
51 set_height(node
->left
);
52 set_height(node
->right
);
53 hl
= int_height(node
->left
);
54 hr
= int_height(node
->right
);
55 int_entry(node
)->height
= A_MAX(hl
, hr
) + 1;
59 static void check_tree(a_avl_node
*node
) /* NOLINT */
63 int const e
= int_factor(node
);
64 TEST_BUG(-1 <= e
&& e
<= 1);
65 TEST_BUG(int_height(node
->right
) - int_height(node
->left
) == e
);
68 TEST_BUG(int_entry(node
->left
)->data
< int_entry(node
)->data
);
69 check_tree(node
->left
);
73 TEST_BUG(int_entry(node
->right
)->data
> int_entry(node
)->data
);
74 check_tree(node
->right
);
79 static int test(unsigned long n
)
83 a_avl_node
*cur
, *next
;
84 a_str str
= A_STR_INIT
;
85 a_avl root
= A_AVL_ROOT
;
86 int *sorted
= a_new(int, A_NULL
, n
);
87 int_node
*vec
= a_new(int_node
, A_NULL
, n
);
88 for (i
= 0; i
< n
; ++i
)
90 a_str_setf(&str
, "%u", i
);
91 vec
[i
].data
= sorted
[i
] = a_cast_s(int, a_hash_bkdr(a_str_ptr(&str
), 0));
92 a_avl_insert(&root
, &vec
[i
].node
, int_cmp
);
93 set_height(root
.node
);
94 check_tree(root
.node
);
97 debug("insert 0x%04X/0x%04lX\n", i
, n
);
102 for (i
= 0; i
< n
; ++i
)
104 TEST_BUG(a_avl_search(&root
, &vec
[i
].node
, int_cmp
));
107 qsort(sorted
, n
, sizeof(int), intcmp
);
110 for (i
= 0; i
< n
; ++i
)
114 A_AVL_FOREACH(cur
, &root
)
116 int_node
*it
= int_entry(cur
);
117 TEST_BUG(it
->data
== sorted
[x
]);
121 for (i
= 0; i
< n
; ++i
)
123 TEST_BUG(vec
[i
].reached
);
128 for (i
= 0; i
< n
; ++i
)
132 A_AVL_FOREACH_REVERSE(cur
, &root
)
134 int_node
*it
= int_entry(cur
);
135 TEST_BUG(it
->data
== sorted
[--x
]);
138 for (i
= 0; i
< n
; ++i
)
140 TEST_BUG(vec
[i
].reached
);
144 for (i
= 0; i
< n
; ++i
)
148 A_AVL_PRE_FOREACH(cur
, &root
)
150 int_node
*it
= int_entry(cur
);
153 for (i
= 0; i
< n
; ++i
)
155 TEST_BUG(vec
[i
].reached
);
158 for (i
= 0; i
< n
; ++i
)
162 A_AVL_PRE_FOREACH_REVERSE(cur
, &root
)
164 int_node
*it
= int_entry(cur
);
167 for (i
= 0; i
< n
; ++i
)
169 TEST_BUG(vec
[i
].reached
);
172 for (i
= 0; i
< n
; ++i
)
176 A_AVL_POST_FOREACH(cur
, &root
)
178 int_node
*it
= int_entry(cur
);
181 for (i
= 0; i
< n
; ++i
)
183 TEST_BUG(vec
[i
].reached
);
186 for (i
= 0; i
< n
; ++i
)
190 A_AVL_POST_FOREACH_REVERSE(cur
, &root
)
192 int_node
*it
= int_entry(cur
);
195 for (i
= 0; i
< n
; ++i
)
197 TEST_BUG(vec
[i
].reached
);
200 for (i
= 0; i
< n
; ++i
)
202 a_avl_remove(&root
, &vec
[i
].node
);
203 set_height(root
.node
);
204 check_tree(root
.node
);
207 debug("remove 0x%04X/0x%04lX\n", i
, n
);
211 TEST_BUG(!a_avl_search(&root
, &vec
->node
, int_cmp
));
213 for (i
= 0; i
< n
; ++i
)
215 a_avl_insert(&root
, &vec
[i
].node
, int_cmp
);
218 A_AVL_FORTEAR(cur
, next
, &root
)
220 int_entry(cur
)->reached
= 1;
222 for (i
= 0; i
< n
; ++i
)
224 TEST_BUG(vec
[i
].reached
);
232 int main(int argc
, char *argv
[]) /* NOLINT(misc-definitions-in-headers) */
234 unsigned long n
= 0x1000;
235 if (argc
> 1) { n
= strtoul(argv
[1], A_NULL
, 0); }