1 /* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
27 #include "eina_suite.h"
30 static inline Eina_Bool
31 _eina_rbtree_is_red(Eina_Rbtree *tree)
33 return tree != NULL && tree->color == EINA_RBTREE_RED;
37 _eina_rbtree_black_height(Eina_Rbtree *tree, Eina_Rbtree_Cmp_Node_Cb cmp)
41 Eina_Rbtree_Direction dir;
48 left = tree->son[EINA_RBTREE_LEFT];
49 right = tree->son[EINA_RBTREE_RIGHT];
51 /* Consecutive red links. */
52 fail_if(_eina_rbtree_is_red(tree) &&
53 (_eina_rbtree_is_red(left) || _eina_rbtree_is_red(right)));
55 left_height = _eina_rbtree_black_height(left, cmp);
56 right_height = _eina_rbtree_black_height(right, cmp);
58 /* Check binary search tree. */
61 dir = cmp(tree, left, NULL);
62 fail_if(dir != EINA_RBTREE_LEFT);
67 dir = cmp(tree, right, NULL);
68 fail_if(dir != EINA_RBTREE_RIGHT);
71 /* Check black height */
72 if (left_height != right_height)
73 fprintf(stderr, "%i != %i\n", left_height, right_height);
75 fail_if(left_height != right_height);
77 return _eina_rbtree_is_red(tree) ? left_height : left_height + 1;
80 typedef struct _Eina_Rbtree_Int Eina_Rbtree_Int;
81 struct _Eina_Rbtree_Int
87 static Eina_Rbtree_Direction
88 eina_rbtree_int_cmp(const Eina_Rbtree_Int *left,
89 const Eina_Rbtree_Int *right,
90 __UNUSED__ void *data)
95 if (left->value < right->value)
96 return EINA_RBTREE_LEFT;
98 return EINA_RBTREE_RIGHT;
102 eina_rbtree_int_key(const Eina_Rbtree_Int *node,
104 __UNUSED__ int length,
105 __UNUSED__ void *data)
108 return node->value - *key;
111 static Eina_Rbtree_Int *
112 _eina_rbtree_int_new(int value)
116 it = malloc(sizeof (Eina_Rbtree_Int));
124 START_TEST(eina_rbtree_insertion)
126 Eina_Rbtree_Int *root = NULL;
127 Eina_Rbtree_Int *item;
132 for (i = 0; i < 500; ++i)
134 item = _eina_rbtree_int_new(rand());
135 root = (Eina_Rbtree_Int *)eina_rbtree_inline_insert(
138 EINA_RBTREE_CMP_NODE_CB(
139 eina_rbtree_int_cmp),
143 _eina_rbtree_black_height(&root->node,
144 EINA_RBTREE_CMP_NODE_CB(
145 eina_rbtree_int_cmp));
149 START_TEST(eina_rbtree_lookup)
151 Eina_Rbtree_Int *root = NULL;
152 Eina_Rbtree_Int *item;
153 int list[] = { 50, 100, 10, 43, 23 };
156 for (i = 0; i < sizeof (list) / sizeof (int); ++i)
158 item = _eina_rbtree_int_new(list[i]);
159 root = (Eina_Rbtree_Int *)eina_rbtree_inline_insert(
162 EINA_RBTREE_CMP_NODE_CB(
163 eina_rbtree_int_cmp),
167 item = (Eina_Rbtree_Int *)eina_rbtree_inline_lookup(&root->node,
170 EINA_RBTREE_CMP_KEY_CB(
171 eina_rbtree_int_key),
177 (Eina_Rbtree_Int *)eina_rbtree_inline_lookup(&root->node,
180 EINA_RBTREE_CMP_KEY_CB(
181 eina_rbtree_int_key),
187 START_TEST(eina_rbtree_remove)
189 Eina_Rbtree_Int *root = NULL;
190 Eina_Rbtree_Int *item;
192 Eina_Array_Iterator it;
197 ea = eina_array_new(11);
202 for (i = 0; i < 500; ++i)
204 item = _eina_rbtree_int_new(rand());
205 eina_array_push(ea, item);
206 root = (Eina_Rbtree_Int *)eina_rbtree_inline_insert(
209 EINA_RBTREE_CMP_NODE_CB(
210 eina_rbtree_int_cmp),
214 _eina_rbtree_black_height(&root->node,
215 EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
217 EINA_ARRAY_ITER_NEXT(ea, i, item, it)
219 root = (Eina_Rbtree_Int *)eina_rbtree_inline_remove(
222 EINA_RBTREE_CMP_NODE_CB(
223 eina_rbtree_int_cmp),
225 _eina_rbtree_black_height(&root->node,
226 EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
229 fail_if(root != NULL);
235 START_TEST(eina_rbtree_simple_remove)
237 Eina_Rbtree *root = NULL;
242 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
244 EINA_RBTREE_CMP_NODE_CB(
245 eina_rbtree_int_cmp), NULL);
247 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
249 EINA_RBTREE_CMP_NODE_CB(
250 eina_rbtree_int_cmp), NULL);
252 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
254 EINA_RBTREE_CMP_NODE_CB(
255 eina_rbtree_int_cmp), NULL);
257 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
259 EINA_RBTREE_CMP_NODE_CB(
260 eina_rbtree_int_cmp), NULL);
261 _eina_rbtree_black_height(root,
262 EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
264 fail_if(root == NULL);
267 lookup = eina_rbtree_inline_lookup(root,
270 EINA_RBTREE_CMP_KEY_CB(
271 eina_rbtree_int_key),
273 _eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
274 fail_if(lookup == NULL);
277 eina_rbtree_inline_remove(root, lookup, EINA_RBTREE_CMP_NODE_CB(
278 eina_rbtree_int_cmp), NULL);
280 _eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
284 START_TEST(eina_rbtree_simple_remove2)
286 Eina_Rbtree *root = NULL;
291 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
293 EINA_RBTREE_CMP_NODE_CB(
294 eina_rbtree_int_cmp), NULL);
296 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
298 EINA_RBTREE_CMP_NODE_CB(
299 eina_rbtree_int_cmp), NULL);
301 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
303 EINA_RBTREE_CMP_NODE_CB(
304 eina_rbtree_int_cmp), NULL);
306 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
308 EINA_RBTREE_CMP_NODE_CB(
309 eina_rbtree_int_cmp), NULL);
311 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
313 EINA_RBTREE_CMP_NODE_CB(
314 eina_rbtree_int_cmp), NULL);
316 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
318 EINA_RBTREE_CMP_NODE_CB(
319 eina_rbtree_int_cmp), NULL);
321 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
323 EINA_RBTREE_CMP_NODE_CB(
324 eina_rbtree_int_cmp), NULL);
325 _eina_rbtree_black_height(root,
326 EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
328 fail_if(root == NULL);
331 lookup = eina_rbtree_inline_lookup(root,
334 EINA_RBTREE_CMP_KEY_CB(
335 eina_rbtree_int_key),
337 _eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
338 fail_if(lookup == NULL);
341 eina_rbtree_inline_remove(root, lookup, EINA_RBTREE_CMP_NODE_CB(
342 eina_rbtree_int_cmp), NULL);
344 _eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
348 START_TEST(eina_rbtree_simple_remove3)
350 Eina_Rbtree *root = NULL;
355 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
357 EINA_RBTREE_CMP_NODE_CB(
358 eina_rbtree_int_cmp), NULL);
360 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
362 EINA_RBTREE_CMP_NODE_CB(
363 eina_rbtree_int_cmp), NULL);
365 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
367 EINA_RBTREE_CMP_NODE_CB(
368 eina_rbtree_int_cmp), NULL);
370 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
372 EINA_RBTREE_CMP_NODE_CB(
373 eina_rbtree_int_cmp), NULL);
375 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
377 EINA_RBTREE_CMP_NODE_CB(
378 eina_rbtree_int_cmp), NULL);
380 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
382 EINA_RBTREE_CMP_NODE_CB(
383 eina_rbtree_int_cmp), NULL);
385 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
387 EINA_RBTREE_CMP_NODE_CB(
388 eina_rbtree_int_cmp), NULL);
390 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
392 EINA_RBTREE_CMP_NODE_CB(
393 eina_rbtree_int_cmp), NULL);
395 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
397 EINA_RBTREE_CMP_NODE_CB(
398 eina_rbtree_int_cmp), NULL);
400 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
402 EINA_RBTREE_CMP_NODE_CB(
403 eina_rbtree_int_cmp), NULL);
405 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
407 EINA_RBTREE_CMP_NODE_CB(
408 eina_rbtree_int_cmp), NULL);
410 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
412 EINA_RBTREE_CMP_NODE_CB(
413 eina_rbtree_int_cmp), NULL);
415 eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
417 EINA_RBTREE_CMP_NODE_CB(
418 eina_rbtree_int_cmp), NULL);
419 _eina_rbtree_black_height(root,
420 EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
422 fail_if(root == NULL);
425 lookup = eina_rbtree_inline_lookup(root,
428 EINA_RBTREE_CMP_KEY_CB(
429 eina_rbtree_int_key),
431 _eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
432 fail_if(lookup == NULL);
435 eina_rbtree_inline_remove(root, lookup, EINA_RBTREE_CMP_NODE_CB(
436 eina_rbtree_int_cmp), NULL);
438 _eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
443 eina_test_rbtree(TCase *tc)
445 tcase_add_test(tc, eina_rbtree_insertion);
446 tcase_add_test(tc, eina_rbtree_lookup);
447 tcase_add_test(tc, eina_rbtree_remove);
448 tcase_add_test(tc, eina_rbtree_simple_remove);
449 tcase_add_test(tc, eina_rbtree_simple_remove2);
450 tcase_add_test(tc, eina_rbtree_simple_remove3);