libdatatypes 0.3.2
Abstract datatypes for C.
Loading...
Searching...
No Matches
rbtree.c
Go to the documentation of this file.
1/***************************************************************************
2 begin........: May 2012
3 copyright....: Sebastian Fedrau
4 email........: sebastian.fedrau@gmail.com
5 ***************************************************************************/
6
7/***************************************************************************
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License v3 as published by
10 the Free Software Foundation.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License v3 for more details.
16 ***************************************************************************/
22#define _GNU_SOURCE
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include <limits.h>
28#include <assert.h>
29
30#include "rbtree.h"
31
33#define RBTREE_INITIAL_BLOCK_SIZE 4
34
35RBTree *
36rbtree_new(CompareFunc compare_keys, FreeFunc free_key, FreeFunc free_value, Pool *pool)
37{
38 assert(compare_keys != NULL);
39
40 RBTree *tree = (RBTree *)malloc(sizeof(RBTree));
41
42 if(!tree)
43 {
44 perror("malloc()");
45 abort();
46 }
47
48 rbtree_init(tree, compare_keys, free_key, free_value, pool);
49
50 return tree;
51}
52
53void
54rbtree_init(RBTree *tree, CompareFunc compare_keys, FreeFunc free_key, FreeFunc free_value, Pool *pool)
55{
56 assert(tree != NULL);
57 assert(compare_keys != NULL);
58
59 memset(tree, 0, sizeof(RBTree));
60
61 tree->stack = (RBNode **)malloc(sizeof(RBNode *) * RBTREE_INITIAL_BLOCK_SIZE);
62
63 if(!tree->stack)
64 {
65 perror("malloc()");
66 abort();
67 }
68
69 tree->compare_keys = compare_keys;
70 tree->free_key = free_key;
71 tree->free_value = free_value;
73 tree->pool = pool;
74 tree->pair.free_value = free_value;
75 tree->pair.node = NULL;
76}
77
78static void
79_rbtree_destroy_node(RBTree *tree, RBNode *node)
80{
81 assert(tree != NULL);
82 assert(node != NULL);
83
84 if(node->left)
85 {
86 _rbtree_destroy_node(tree, node->left);
87 }
88
89 if(node->right)
90 {
91 _rbtree_destroy_node(tree, node->right);
92 }
93
94 if(tree->free_key)
95 {
96 tree->free_key(node->key);
97 }
98
99 if(tree->free_value && node->value)
100 {
101 tree->free_value(node->value);
102 }
103
104 if(tree->pool)
105 {
106 tree->pool->free(tree->pool, node);
107 }
108 else
109 {
110 free(node);
111 }
112}
113
114void
116{
117 assert(tree != NULL);
118
119 rbtree_free(tree);
120 free(tree);
121}
122
123void
125{
126 assert(tree != NULL);
127
128 if(tree->root)
129 {
130 _rbtree_destroy_node(tree, tree->root);
131 }
132
133 free(tree->stack);
134}
135
136void
138{
139 assert(tree != NULL);
140
141 if(tree->root)
142 {
143 _rbtree_destroy_node(tree, tree->root);
144 }
145
146 tree->sp = NULL;
147 tree->count = 0;
148 tree->root = NULL;
149}
150
151size_t
153{
154 assert(tree != NULL);
155
156 return tree->count;
157}
158
159/*
160 * stack helpers:
161 */
162static bool
163_rbtree_stack_push(RBTree *tree, RBNode *node)
164{
165 assert(tree != NULL);
166 assert(node != NULL);
167
168 if(!tree->sp)
169 {
170 tree->sp = tree->stack;
171 }
172 else
173 {
174 intptr_t sp = tree->sp - tree->stack;
175
176 if(sp >= 0 && (size_t)sp >= tree->stack_size - 1)
177 {
178 if(tree->stack_size > (SSIZE_MAX / sizeof(RBNode *)) / 2)
179 {
180 fprintf(stderr, "%s(): integer overflow.\n", __func__);
181 abort();
182 }
183
184 tree->stack_size *= 2;
185 tree->stack = (RBNode **)realloc(tree->stack, sizeof(RBNode *) * tree->stack_size);
186
187 if(!tree->stack)
188 {
189 perror("realloc()");
190 abort();
191 }
192
193 tree->sp = tree->stack + sp;
194 }
195
196 ++tree->sp;
197 }
198
199 *tree->sp = node;
200
201 return true;
202}
203
204/*
205 * node helpers:
206 */
207
209#define _rbnode_is_black(n) (n == NULL ? 1 : n->black)
212static RBNode *
213_rbnode_create_new(Pool *pool, void *key, void *value, int black, RBNode *left, RBNode *right)
214{
215 assert(key != NULL);
216
217 RBNode *node;
218
219 if(pool)
220 {
221 node = (RBNode *)pool->alloc(pool);
222 }
223 else if(!(node = (RBNode *)malloc(sizeof(RBNode))))
224 {
225 perror("malloc()");
226 abort();
227 }
228
229 node->key = key;
230 node->value = value;
231 node->black = black;
232 node->left = left;
233 node->right = right;
234
235 return node;
236}
237
238/*
239 * replace & rotate nodes:
240 */
241static void
242_rbnode_replace(RBTree *tree, const RBNode *old_node, RBNode *parent, RBNode *new_node)
243{
244 assert(tree != NULL);
245
246 if(parent)
247 {
248 if(old_node == parent->left)
249 {
250 parent->left = new_node;
251 }
252 else
253 {
254 parent->right = new_node;
255 }
256 }
257 else
258 {
259 tree->root = new_node;
260 }
261}
262
263static void
264_rbnode_rotate_left(RBTree *tree, RBNode *node, RBNode *parent)
265{
266 assert(tree != NULL);
267 assert(node != NULL);
268
269 RBNode *right = node->right;
270
271 assert(right != NULL);
272
273 _rbnode_replace(tree, node, parent, right);
274 node->right = right->left;
275
276 right->left = node;
277}
278
279static void
280_rbnode_rotate_right(RBTree *tree, RBNode *node, RBNode *parent)
281{
282 assert(tree != NULL);
283 assert(node != NULL);
284
285 RBNode *left = node->left;
286 _rbnode_replace(tree, node, parent, left);
287 node->left = left->right;
288
289 left->right = node;
290}
291
292/*
293 * insert nodes:
294 */
295static void _rbtree_insert_case1(RBTree *tree);
296
297static void
298_rbtree_insert_case2_to_6(RBTree *tree)
299{
300 assert(tree != NULL);
301
302 RBNode *node = *tree->sp;
303 RBNode *parent = *(tree->sp - 1);
304
305 /* case 2 */
306 if(_rbnode_is_black(parent))
307 {
308 return;
309 }
310
311 /* case 3 */
312 RBNode *grandparent = *(tree->sp - 2);
313 RBNode *uncle = (parent == grandparent->left) ? grandparent->right : grandparent->left;
314
315 if(!_rbnode_is_black(uncle))
316 {
317 parent->black = 1;
318 uncle->black = 1;
319
320 grandparent->black = 0;
321 tree->sp -= 2;
322 _rbtree_insert_case1(tree);
323 }
324 else
325 {
326 /* case 4 */
327 if(node == parent->right && parent == grandparent->left)
328 {
329 _rbnode_rotate_left(tree, parent, grandparent);
330
331 *(tree->sp - 1) = node;
332 parent = node;
333 node = node->left;
334 *tree->sp = node;
335 }
336 else if(node == parent->left && parent == grandparent->right)
337 {
338 _rbnode_rotate_right(tree, parent, grandparent);
339
340 *(tree->sp - 1) = node;
341 parent = node;
342 node = node->right;
343 *tree->sp = node;
344 }
345
346 /* case 5 */
347 RBNode *great_grandparent = NULL;
348
349 if(tree->sp >= tree->stack + 3)
350 {
351 great_grandparent = *(tree->sp - 3);
352 }
353
354 grandparent->black = 0;
355 parent->black = 1;
356
357 if(node == parent->left && parent == grandparent->left)
358 {
359 _rbnode_rotate_right(tree, grandparent, great_grandparent);
360 }
361 else
362 {
363 _rbnode_rotate_left(tree, grandparent, great_grandparent);
364 }
365
366 *(tree->sp - 2) = *(tree->sp - 1);
367 *(tree->sp - 1) = *(tree->sp);
368 --tree->sp;
369 }
370}
371
372static void
373_rbtree_insert_case1(RBTree *tree)
374{
375 assert(tree != NULL);
376
377 RBNode *node = *tree->sp;
378
379 if(tree->sp == tree->stack)
380 {
381 node->black = 1;
382 }
383 else
384 {
385 _rbtree_insert_case2_to_6(tree);
386 }
387}
388
389static bool
390_rbtree_insert_root(RBTree *tree, void *key, void *value)
391{
392 bool inserted = false;
393
394 assert(tree != NULL);
395 assert(key != NULL);
396
397 if(!tree->root)
398 {
399 inserted = true;
400
401 tree->root = _rbnode_create_new(tree->pool, key, value, 1, NULL, NULL);
402 tree->count = 1;
403 }
404
405 return inserted;
406}
407
408static void
409_rbtree_replace_node(RBTree *tree, RBNode *node, void *key, void *value, bool overwrite_key)
410{
411 assert(tree != NULL);
412 assert(node != NULL);
413 assert(key != NULL);
414
415 if(overwrite_key)
416 {
417 if(tree->free_key)
418 {
419 tree->free_key(node->key);
420 }
421
422 node->key = key;
423 }
424
425 if(tree->free_value && node->value)
426 {
427 tree->free_value(node->value);
428 }
429
430 node->value = value;
431}
432
434_rbtree_insert_child(RBTree *tree, void *key, void *value, bool overwrite_key)
435{
436 int result = -1;
437
438 assert(tree != NULL);
439 assert(tree->root != NULL);
440 assert(tree->compare_keys != NULL);
441 assert(key != NULL);
442
443 tree->sp = NULL;
444
445 RBNode *node = tree->root;
446
447 while(result == -1)
448 {
449 if(_rbtree_stack_push(tree, node))
450 {
451 int32_t cmp = tree->compare_keys(key, node->key);
452
453 if(!cmp)
454 {
456
457 _rbtree_replace_node(tree, node, key, value, overwrite_key);
458
459 }
460 else if(tree->count < SIZE_MAX)
461 {
462 RBNode **child = (cmp < 0) ? &node->left : &node->right;
463
464 if(*child)
465 {
466 node = *child;
467 }
468 else
469 {
471
472 *child = _rbnode_create_new(tree->pool, key, value, 0, NULL, NULL);
473
474 if(_rbtree_stack_push(tree, *child))
475 {
476 _rbtree_insert_case2_to_6(tree);
477 }
478 else
479 {
481 }
482 }
483 }
484 else
485 {
487
488 fprintf(stderr, "%s(): integer overflow.\n", __func__);
489 }
490 }
491 else
492 {
494 }
495 }
496
497 if(result == RBTREE_INSERT_RESULT_NEW)
498 {
499 ++tree->count;
500 }
501
502 return result;
503}
504
506rbtree_set(RBTree *tree, void *key, void *value, bool overwrite_key)
507{
509
510 assert(tree != NULL);
511 assert(tree->compare_keys != NULL);
512 assert(key != NULL);
513
514 if(!_rbtree_insert_root(tree, key, value))
515 {
516 result = _rbtree_insert_child(tree, key, value, overwrite_key);
517 }
518
519 return result;
520}
521
522/*
523 * search nodes:
524 */
525static RBNode *
526_rbtree_find_node(RBTree *tree, const void *key, bool build_stack)
527{
528 assert(tree != NULL);
529 assert(tree->compare_keys != NULL);
530 assert(key != NULL);
531
532 RBNode *node = tree->root;
533
534 while(node)
535 {
536 if(build_stack)
537 {
538 _rbtree_stack_push(tree, node);
539 }
540
541 int32_t result = tree->compare_keys(key, node->key);
542
543 if(!result)
544 {
545 return node;
546 }
547 else
548 {
549 if(result < 0)
550 {
551 node = node->left;
552 }
553 else
554 {
555 node = node->right;
556 }
557 }
558 }
559
560 return NULL;
561}
562
564rbtree_lookup(RBTree *tree, const void *key)
565{
566 assert(tree != NULL);
567 assert(key != NULL);
568
569 RBNode *node = _rbtree_find_node((RBTree *)tree, key, false);
570
571 if(node)
572 {
573 tree->pair.node = node;
574
575 return &tree->pair;
576 }
577
578 return NULL;
579}
580
581void *
583{
584 assert(pair != NULL && pair->node != NULL);
585
586 if(pair)
587 {
588 return pair->node->key;
589 }
590
591 return NULL;
592}
593
594void *
596{
597 assert(pair != NULL && pair->node != NULL);
598
599 if(pair)
600 {
601 return pair->node->value;
602 }
603
604 return NULL;
605}
606
607void
609{
610 assert(pair != NULL);
611 assert(pair->node != NULL);
612
613 if(pair->free_value && pair->node->value)
614 {
615 pair->free_value(pair->node->value);
616 }
617
618 pair->node->value = value;
619}
620
621bool
622rbtree_key_exists(const RBTree *tree, const void *key)
623{
624 assert(tree != NULL);
625 assert(key != NULL);
626
627 return _rbtree_find_node((RBTree *)tree, key, false) ? true : false;
628}
629
630/*
631 * remove nodes:
632 */
633static RBNode *
634_rbtree_find_max_node(RBTree *tree, RBNode *node)
635{
636 assert(tree != NULL);
637 assert(node != NULL);
638
639 _rbtree_stack_push(tree, node);
640
641 while(node->right)
642 {
643 node = node->right;
644 _rbtree_stack_push(tree, node);
645 }
646
647 return node;
648}
649
650static void _rbtree_remove_case1(RBTree *tree);
651
652static void
653_rbtree_remove_case3_to_6(RBTree *tree)
654{
655 assert(tree != NULL);
656
657 const RBNode *node = *tree->sp;
658 RBNode *parent = *(tree->sp - 1);
659 RBNode *sibling;
660
661 if(parent->right == node)
662 {
663 sibling = parent->left;
664 }
665 else
666 {
667 sibling = parent->right;
668 }
669
670 assert(sibling != NULL);
671
672 if(_rbnode_is_black(sibling) && _rbnode_is_black(sibling->left) && _rbnode_is_black(sibling->right))
673 {
674 if(_rbnode_is_black(parent))
675 {
676 /* case 3 */
677 sibling->black = 0;
678 --tree->sp;
679 _rbtree_remove_case1(tree);
680
681 return;
682 }
683 else
684 {
685 /* case 4 */
686 sibling->black = 0;
687 parent->black = 1;
688
689 return;
690 }
691 }
692
693 /* case 5 */
694 if(node == parent->left && _rbnode_is_black(sibling) && !_rbnode_is_black(sibling->left) && _rbnode_is_black(sibling->right))
695 {
696 sibling->black = 0;
697 sibling->left->black = 1;
698 _rbnode_rotate_right(tree, sibling, parent);
699 sibling = parent->right;
700 }
701 else if(node == parent->right && _rbnode_is_black(sibling) && _rbnode_is_black(sibling->left) && !_rbnode_is_black(sibling->right))
702 {
703 sibling->black = 0;
704 sibling->right->black = 1;
705 _rbnode_rotate_left(tree, sibling, parent);
706 sibling = parent->left;
707 }
708
709 /* case 6 */
710 sibling->black = parent->black;
711 parent->black = 1;
712
713 RBNode *grandparent = NULL;
714
715 if(tree->sp >= tree->stack + 2)
716 {
717 grandparent = *(tree->sp - 2);
718 }
719
720 if(node == parent->left)
721 {
722 assert(!_rbnode_is_black(sibling->right));
723 sibling->right->black = 1;
724 _rbnode_rotate_left(tree, parent, grandparent);
725 }
726 else
727 {
728 assert(!_rbnode_is_black(sibling->left));
729 sibling->left->black = 1;
730 _rbnode_rotate_right(tree, parent, grandparent);
731 }
732}
733
734static void
735_rbtree_remove_case2(RBTree *tree)
736{
737 assert(tree != NULL);
738
739 RBNode *node = *tree->sp;
740 RBNode *parent = *(tree->sp - 1);
741 RBNode *sibling;
742
743 if(parent->right == node)
744 {
745 sibling = parent->left;
746 }
747 else
748 {
749 sibling = parent->right;
750 }
751
752 if(!_rbnode_is_black(sibling))
753 {
754 parent->black = 0;
755 sibling->black = 1;
756
757 RBNode *grandparent = NULL;
758
759 if(tree->sp >= tree->stack + 2)
760 {
761 grandparent = *(tree->sp - 2);
762 }
763
764 if(parent->left == node)
765 {
766 _rbnode_rotate_left(tree, parent, grandparent);
767 }
768 else
769 {
770 _rbnode_rotate_right(tree, parent, grandparent);
771 }
772
773 _rbtree_stack_push(tree, node);
774 *(tree->sp - 1) = parent;
775 *(tree->sp - 2) = sibling;
776 }
777
778 _rbtree_remove_case3_to_6(tree);
779}
780
781static void
782_rbtree_remove_case1(RBTree *tree)
783{
784 assert(tree != NULL);
785
786 if(tree->sp > tree->stack)
787 {
788 _rbtree_remove_case2(tree);
789 }
790}
791
792bool
793rbtree_remove(RBTree *tree, const void *key)
794{
795 assert(tree != NULL);
796 assert(key != NULL);
797
798 tree->sp = NULL;
799
800 RBNode *node =_rbtree_find_node(tree, key, true);
801
802 if(!node)
803 {
804 return false;
805 }
806
807 --tree->count;
808
809 if(tree->free_key)
810 {
811 tree->free_key(node->key);
812 }
813
814 if(tree->free_value && node->value)
815 {
816 tree->free_value(node->value);
817 }
818
819 if(node->left && node->right)
820 {
821 RBNode *max = _rbtree_find_max_node(tree, node->left);
822
823 node->key = max->key;
824 node->value = max->value;
825
826 node = max;
827 }
828
829 RBNode *child = node->right ? node->right : node->left;
830 RBNode *parent = NULL;
831
832 if(tree->sp > tree->stack)
833 {
834 parent = *(tree->sp - 1);
835 }
836
837 if(_rbnode_is_black(node))
838 {
839 if(!_rbnode_is_black(child))
840 {
841 node->black = 0;
842 }
843
844 _rbtree_remove_case1(tree);
845 }
846
847 _rbnode_replace(tree, node, parent, child);
848
849 if(!parent && child)
850 {
851 child->black = 1;
852 }
853
854 if(tree->pool)
855 {
856 tree->pool->free(tree->pool, node);
857 }
858 else
859 {
860 free(node);
861 }
862
863 return true;
864}
865
866/*
867 * iterator:
868 */
869void
871{
872 assert(tree != NULL);
873 assert(iter != NULL);
874
875 iter->tree = tree;
876 iter->stack_size = tree->count + 1;
877 iter->sp = NULL;
878 iter->finished = false;
879
880 if(tree->root)
881 {
882 iter->stack = (RBTreeIterStackItem *)malloc(sizeof(RBTreeIterStackItem) * iter->stack_size);
883
884 if(!iter->stack)
885 {
886 perror("malloc()");
887 abort();
888 }
889 }
890 else
891 {
892 iter->finished = true;
893 }
894}
895
896void
898{
899 assert(iter != NULL);
900
901 free(iter->stack);
902}
903
904void
906{
907 assert(tree != NULL);
908 assert(iter != NULL);
909
910 iter->tree = tree;
911 iter->sp = NULL;
912
913 if(tree->root)
914 {
915 if(tree->count + 1 > iter->stack_size)
916 {
917 iter->stack_size = tree->count + 1;
918 iter->stack = (RBTreeIterStackItem *)realloc(iter->stack, sizeof(RBTreeIterStackItem) * iter->stack_size);
919
920 if(!iter->stack)
921 {
922 perror("realloc()");
923 abort();
924 }
925 }
926
927 iter->finished = false;
928 }
929 else
930 {
931 iter->finished = true;
932 }
933}
934
935bool
937{
938 assert(iter != NULL);
939
940 if(iter->finished)
941 {
942 return false;
943 }
944
945 if(iter->sp)
946 {
947 for(;;)
948 {
949 assert(iter->sp->state >= 0 && iter->sp->state <= 2);
950
951 if(iter->sp->state == 0)
952 {
953 ++iter->sp->state;
954 ++iter->sp;
955 iter->sp->node = (iter->sp - 1)->node->left;
956 iter->sp->state = 0;
957 }
958 else if(iter->sp->state == 1)
959 {
960 ++iter->sp->state;
961 ++iter->sp;
962 iter->sp->node = (iter->sp - 1)->node->right;
963 iter->sp->state = 0;
964 }
965 else if(iter->sp->state == 2)
966 {
967 ++iter->sp->state;
968 --iter->sp;
969 }
970
971 if(iter->sp < iter->stack)
972 {
973 iter->finished = true;
974
975 return false;
976 }
977
978 if(iter->sp->node)
979 {
980 if(iter->sp->state == 0)
981 {
982 return true;
983 }
984 }
985 else
986 {
987 --iter->sp;
988 }
989 }
990 }
991 else
992 {
993 iter->sp = iter->stack;
994 iter->sp->node = iter->tree->root;
995 iter->sp->state = 0;
996 }
997
998 return true;
999}
1000
1001void *
1003{
1004 assert(iter != NULL);
1005
1006 if(iter->sp && iter->sp->node)
1007 {
1008 return iter->sp->node->key;
1009 }
1010
1011 return NULL;
1012}
1013
1014void *
1016{
1017 assert(iter != NULL);
1018
1019 if(iter->sp && iter->sp->node)
1020 {
1021 return iter->sp->node->value;
1022 }
1023
1024 return NULL;
1025}
1026
int32_t(* CompareFunc)(const void *a, const void *b)
Definition compare.h:30
void(* FreeFunc)(void *p)
Definition datatypes.h:33
void * rbtree_iter_get_value(const RBTreeIter *iter)
Definition rbtree.c:1015
bool rbtree_remove(RBTree *tree, const void *key)
Definition rbtree.c:793
bool rbtree_key_exists(const RBTree *tree, const void *key)
Definition rbtree.c:622
void * rbtree_pair_get_key(const RBTreePair *pair)
Definition rbtree.c:582
void rbtree_pair_set_value(RBTreePair *pair, void *value)
Definition rbtree.c:608
void rbtree_init(RBTree *tree, CompareFunc compare_keys, FreeFunc free_key, FreeFunc free_value, Pool *pool)
Definition rbtree.c:54
RBTreeInsertResult rbtree_set(RBTree *tree, void *key, void *value, bool overwrite_key)
Definition rbtree.c:506
RBTreePair * rbtree_lookup(RBTree *tree, const void *key)
Definition rbtree.c:564
void rbtree_iter_init(const RBTree *tree, RBTreeIter *iter)
Definition rbtree.c:870
void rbtree_clear(RBTree *tree)
Definition rbtree.c:137
void rbtree_destroy(RBTree *tree)
Definition rbtree.c:115
size_t rbtree_count(const RBTree *tree)
Definition rbtree.c:152
void rbtree_iter_reuse(const RBTree *tree, RBTreeIter *iter)
Definition rbtree.c:905
RBTree * rbtree_new(CompareFunc compare_keys, FreeFunc free_key, FreeFunc free_value, Pool *pool)
Definition rbtree.c:36
#define RBTREE_INITIAL_BLOCK_SIZE
Definition rbtree.c:33
void * rbtree_iter_get_key(const RBTreeIter *iter)
Definition rbtree.c:1002
bool rbtree_iter_next(RBTreeIter *iter)
Definition rbtree.c:936
void * rbtree_pair_get_value(const RBTreePair *pair)
Definition rbtree.c:595
void rbtree_iter_free(RBTreeIter *iter)
Definition rbtree.c:897
void rbtree_free(RBTree *tree)
Definition rbtree.c:124
Generic red-black tree.
RBTreeIterStackItem * stack
Definition rbtree.h:127
Pool * pool
Definition rbtree.h:70
RBNode * root
Definition rbtree.h:62
struct RBTree::_RBTreePair pair
Last found key-value pair.
bool finished
Definition rbtree.h:133
bool black
Definition rbtree.h:46
FreeFunc free_value
Definition rbtree.h:60
void * value
Definition rbtree.h:40
RBNode ** stack
Definition rbtree.h:64
RBTreeIterStackItem * sp
Definition rbtree.h:129
struct _rbnode * left
Definition rbtree.h:42
RBNode * node
Definition rbtree.h:85
size_t stack_size
Definition rbtree.h:68
FreeFunc free_key
Definition rbtree.h:58
struct _rbnode * right
Definition rbtree.h:44
void * key
Definition rbtree.h:38
const RBTree * tree
Definition rbtree.h:125
RBTreeInsertResult
result of rbtree_set() method.
Definition rbtree.h:97
@ RBTREE_INSERT_RESULT_NEW
Definition rbtree.h:99
@ RBTREE_INSERT_RESULT_REPLACED
Definition rbtree.h:101
@ RBTREE_INSERT_RESULT_FAILED
Definition rbtree.h:103
struct _RBTreePair RBTreePair
Definition rbtree.h:90
FreeFunc free_value
Definition rbtree.h:83
size_t stack_size
Definition rbtree.h:131
RBNode ** sp
Definition rbtree.h:66
CompareFunc compare_keys
Definition rbtree.h:56
size_t count
Definition rbtree.h:72
Structure holding node data.
Definition rbtree.h:36
Red-black tree.
Definition rbtree.h:54
Structure to iterate over the elements of a RBTree.
Definition rbtree.h:123
Structure holding a node and the iteration state.
Definition rbtree.h:111
Allocate groups of equal-sized chunks of memory.
Definition pool.h:33
void(* free)(struct _Pool *pool, void *ptr)
Definition pool.h:37
void *(* alloc)(struct _Pool *pool)
Definition pool.h:35