libdict
Data Structure C Library
Loading...
Searching...
No Matches
rb_tree.c
Go to the documentation of this file.
1/*
2 * libdict -- red-black tree implementation.
3 *
4 * Copyright (c) 2001-2014, Farooq Mela
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * cf. [Cormen, Leiserson, and Rivest 1990], [Guibas and Sedgewick, 1978]
30 */
31
32#include "rb_tree.h"
33
34#include <string.h>
35#include "dict_private.h"
36#include "tree_common.h"
37
38typedef struct rb_node rb_node;
39struct rb_node {
40 void* key;
41 void* datum;
42 intptr_t color;
45};
46
47#define RB_RED 0
48#define RB_BLACK 1
49
50#define PARENT(node) ((rb_node*)((node)->color & ~RB_BLACK))
51#define COLOR(node) ((node)->color & RB_BLACK)
52
53#define SET_RED(node) (node)->color &= (~(intptr_t)RB_BLACK)
54#define SET_BLACK(node) (node)->color |= ((intptr_t)RB_BLACK)
55#define SET_PARENT(node,p) (node)->color = COLOR(node) | (intptr_t)(p)
56
60
64
65static const dict_vtable rb_tree_vtable = {
66 true,
81};
82
83static const itor_vtable rb_tree_itor_vtable = {
102};
103
104static void rot_left(rb_tree* tree, rb_node* node);
105static void rot_right(rb_tree* tree, rb_node* node);
106static unsigned insert_fixup(rb_tree* tree, rb_node* node);
107static unsigned delete_fixup(rb_tree* tree, rb_node* node, rb_node* parent, bool left);
108static rb_node* node_new(void* key);
109static rb_node* node_next(rb_node* node);
110static rb_node* node_prev(rb_node* node);
111
112rb_tree*
114{
115 ASSERT(cmp_func != NULL);
116
117 rb_tree* tree = MALLOC(sizeof(*tree));
118 if (tree) {
119 tree->root = NULL;
120 tree->count = 0;
121 tree->cmp_func = cmp_func;
122 tree->rotation_count = 0;
123 }
124 return tree;
125}
126
127dict*
129{
130 dict* dct = MALLOC(sizeof(*dct));
131 if (dct) {
132 if (!(dct->_object = rb_tree_new(cmp_func))) {
133 FREE(dct);
134 return NULL;
135 }
136 dct->_vtable = &rb_tree_vtable;
137 }
138 return dct;
139}
140
141size_t
143 const size_t count = rb_tree_clear(tree, delete_func);
144 FREE(tree);
145 return count;
146}
147
148size_t
150{
151 const size_t count = tree->count;
152
153 rb_node* node = tree->root;
154 while (node) {
155 if (node->llink || node->rlink) {
156 node = node->llink ? node->llink : node->rlink;
157 continue;
158 }
159 if (delete_func) delete_func(node->key, node->datum);
160 rb_node* const parent = PARENT(node);
161 FREE(node);
162 *(parent ? (parent->llink == node ? &parent->llink : &parent->rlink) : &tree->root) = NULL;
163 node = parent;
164 }
165 ASSERT(tree->root == NULL);
166 tree->count = 0;
167 return count;
168}
169
170void** rb_tree_search(rb_tree* tree, const void* key) { return tree_search(tree, key); }
171void** rb_tree_search_le(rb_tree* tree, const void* key) { return tree_search_le(tree, key); }
172void** rb_tree_search_lt(rb_tree* tree, const void* key) { return tree_search_lt(tree, key); }
173void** rb_tree_search_ge(rb_tree* tree, const void* key) { return tree_search_ge(tree, key); }
174void** rb_tree_search_gt(rb_tree* tree, const void* key) { return tree_search_gt(tree, key); }
175
178{
179 int cmp = 0; /* Quell GCC warning about uninitialized usage. */
180 rb_node* node = tree->root;
181 rb_node* parent = NULL;
182 while (node) {
183 cmp = tree->cmp_func(key, node->key);
184 if (cmp < 0) {
185 parent = node; node = node->llink;
186 } else if (cmp > 0) {
187 parent = node; node = node->rlink;
188 } else
189 return (dict_insert_result) { &node->datum, false };
190 }
191
192 if (!(node = node_new(key)))
193 return (dict_insert_result) { NULL, false };
194
195 SET_PARENT(node, parent);
196 if (parent == NULL) {
197 ASSERT(tree->root == NULL);
198 tree->root = node;
199 ASSERT(tree->count == 0);
200 SET_BLACK(node);
201 } else {
202 if (cmp < 0)
203 parent->llink = node;
204 else
205 parent->rlink = node;
206
207 tree->rotation_count += insert_fixup(tree, node);
208 }
209 tree->count++;
210 return (dict_insert_result) { &node->datum, true };
211}
212
213static unsigned
214insert_fixup(rb_tree* tree, rb_node* node)
215{
216 unsigned rotations = 0;
217 while (node != tree->root && COLOR(PARENT(node)) == RB_RED) {
218 if (PARENT(node) == PARENT(PARENT(node))->llink) {
219 rb_node* temp = PARENT(PARENT(node))->rlink;
220 if (temp && COLOR(temp) == RB_RED) {
221 SET_BLACK(temp);
222 node = PARENT(node);
223 SET_BLACK(node);
224 node = PARENT(node);
225 SET_RED(node);
226 } else {
227 if (node == PARENT(node)->rlink) {
228 node = PARENT(node);
229 rot_left(tree, node);
230 ++rotations;
231 }
232 temp = PARENT(node);
233 SET_BLACK(temp);
234 temp = PARENT(temp);
235 SET_RED(temp);
236 rot_right(tree, temp);
237 ++rotations;
238 }
239 } else {
240 rb_node* temp = PARENT(PARENT(node))->llink;
241 if (temp && COLOR(temp) == RB_RED) {
242 SET_BLACK(temp);
243 node = PARENT(node);
244 SET_BLACK(node);
245 node = PARENT(node);
246 SET_RED(node);
247 } else {
248 if (node == PARENT(node)->llink) {
249 node = PARENT(node);
250 rot_right(tree, node);
251 ++rotations;
252 }
253 temp = PARENT(node);
254 SET_BLACK(temp);
255 temp = PARENT(temp);
256 SET_RED(temp);
257 rot_left(tree, temp);
258 ++rotations;
259 }
260 }
261 }
262
264 return rotations;
265}
266
267static void
268remove_node(rb_tree* tree, rb_node* node)
269{
270 rb_node* out;
271 if (!node->llink || !node->rlink) {
272 out = node;
273 } else {
274 out = tree_node_min(node->rlink);
275 void *tmp;
276 SWAP(node->key, out->key, tmp);
277 SWAP(node->datum, out->datum, tmp);
278 }
279
280 rb_node* const x = out->llink ? out->llink : out->rlink;
281 rb_node* const xp = PARENT(out);
282 if (x)
283 SET_PARENT(x, xp);
284 bool left = xp && xp->llink == out;
285 *(xp ? (xp->llink == out ? &xp->llink : &xp->rlink) : &tree->root) = x;
286
287 if (COLOR(out) == RB_BLACK && tree->root)
288 tree->rotation_count += delete_fixup(tree, x, xp, left);
289 FREE(out);
290 tree->count--;
291}
292
294rb_tree_remove(rb_tree* tree, const void* key)
295{
296 rb_node* node = tree_search_node(tree, key);
297 if (!node)
298 return (dict_remove_result) { NULL, NULL, false };
299 dict_remove_result result = { node->key, node->datum, true };
300 remove_node(tree, node);
301 return result;
302}
303
304static unsigned
305delete_fixup(rb_tree* tree, rb_node* node, rb_node* parent, bool left)
306{
307 unsigned rotations = 0;
308 while (node != tree->root && (node == NULL || COLOR(node) == RB_BLACK)) {
309 if (left) {
310 rb_node* w = parent->rlink;
311 if (COLOR(w) == RB_RED) {
312 SET_BLACK(w);
313 SET_RED(parent);
314 rot_left(tree, parent); ++rotations;
315 w = parent->rlink;
316 }
317 if ((w->llink == NULL || COLOR(w->llink) == RB_BLACK) &&
318 (w->rlink == NULL || COLOR(w->rlink) == RB_BLACK)) {
319 SET_RED(w);
320 node = parent;
321 parent = PARENT(parent);
322 left = parent && parent->llink == node;
323 } else {
324 if (w->rlink == NULL || COLOR(w->rlink) == RB_BLACK) {
325 SET_BLACK(w->llink);
326 SET_RED(w);
327 rot_right(tree, w); ++rotations;
328 w = parent->rlink;
329 }
330 if (COLOR(parent) == RB_RED)
331 SET_RED(w);
332 else
333 SET_BLACK(w);
334 if (w->rlink)
335 SET_BLACK(w->rlink);
336 SET_BLACK(parent);
337 rot_left(tree, parent); ++rotations;
338 break;
339 }
340 } else { // left == false
341 rb_node* w = parent->llink;
342 if (COLOR(w) == RB_RED) {
343 SET_BLACK(w);
344 SET_RED(parent);
345 rot_right(tree, parent); ++rotations;
346 w = parent->llink;
347 }
348 if ((w->llink == NULL || COLOR(w->llink) == RB_BLACK) &&
349 (w->rlink == NULL || COLOR(w->rlink) == RB_BLACK)) {
350 SET_RED(w);
351 node = parent;
352 parent = PARENT(parent);
353 left = parent && parent->llink == node;
354 } else {
355 if (w->llink == NULL || COLOR(w->llink) == RB_BLACK) {
356 SET_BLACK(w->rlink);
357 SET_RED(w);
358 rot_left(tree, w); ++rotations;
359 w = parent->llink;
360 }
361 if (COLOR(parent) == RB_RED)
362 SET_RED(w);
363 else
364 SET_BLACK(w);
365 if (w->llink)
366 SET_BLACK(w->llink);
367 SET_BLACK(parent);
368 rot_right(tree, parent); ++rotations;
369 break;
370 }
371 }
372 }
373
374 if (node)
375 SET_BLACK(node);
376 return rotations;
377}
378
379size_t rb_tree_count(const rb_tree* tree) { return tree_count(tree); }
383
384size_t
386{
387 if (tree->root == NULL)
388 return 0;
389
390 size_t count = 0;
391 rb_node* node = tree_node_min(tree->root);
392 for (; node != NULL; node = node_next(node)) {
393 ++count;
394 if (!visit(node->key, node->datum, user_data)) break;
395 }
396 return count;
397}
398
399bool
400rb_tree_select(rb_tree *tree, size_t n, const void **key, void **datum)
401{
402 if (n >= tree->count) {
403 if (key)
404 *key = NULL;
405 if (datum)
406 *datum = NULL;
407 return false;
408 }
409 rb_node *node;
410 if (n >= tree->count / 2) {
411 node = tree_node_max(tree->root);
412 n = tree->count - 1 - n;
413 while (n--)
414 node = node_prev(node);
415 } else {
416 node = tree_node_min(tree->root);
417 while (n--)
418 node = node_next(node);
419 }
420 if (key)
421 *key = node->key;
422 if (datum)
423 *datum = node->datum;
424 return true;
425}
426
427static void
428rot_left(rb_tree* tree, rb_node* node)
429{
430 rb_node* const rlink = node->rlink;
431 if ((node->rlink = rlink->llink) != NULL)
432 SET_PARENT(rlink->llink, node);
433 rb_node* const parent = PARENT(node);
434 SET_PARENT(rlink, parent);
435 *(parent ? (parent->llink == node ? &parent->llink : &parent->rlink) : &tree->root) = rlink;
436 rlink->llink = node;
437 SET_PARENT(node, rlink);
438}
439
440static void
441rot_right(rb_tree* tree, rb_node* node)
442{
443 rb_node* const llink = node->llink;
444 if ((node->llink = llink->rlink) != NULL)
445 SET_PARENT(llink->rlink, node);
446 rb_node* const parent = PARENT(node);
447 SET_PARENT(llink, parent);
448 *(parent ? (parent->llink == node ? &parent->llink : &parent->rlink) : &tree->root) = llink;
449 llink->rlink = node;
450 SET_PARENT(node, llink);
451}
452
453static rb_node*
454node_new(void* key)
455{
456 rb_node* node = MALLOC(sizeof(*node));
457 if (node) {
458 ASSERT((((intptr_t)node) & 1) == 0); /* Ensure malloc returns aligned result. */
459 node->key = key;
460 node->datum = NULL;
461 node->color = RB_RED; /* Also initializes parent to NULL */
462 node->llink = NULL;
463 node->rlink = NULL;
464 }
465 return node;
466}
467
468static rb_node*
469node_next(rb_node* node)
470{
471 if (node->rlink) {
472 for (node = node->rlink; node->llink; node = node->llink)
473 /* void */;
474 } else {
475 rb_node* temp = PARENT(node);
476 while (temp && temp->rlink == node) {
477 node = temp;
478 temp = PARENT(temp);
479 }
480 node = temp;
481 }
482
483 return node;
484}
485
486static rb_node*
487node_prev(rb_node* node)
488{
489 if (node->llink) {
490 for (node = node->llink; node->rlink; node = node->rlink)
491 /* void */;
492 } else {
493 rb_node* temp = PARENT(node);
494 while (temp && temp->llink == node) {
495 node = temp;
496 temp = PARENT(temp);
497 }
498 node = temp;
499 }
500
501 return node;
502}
503
504static bool
505node_verify(const rb_tree* tree, const rb_node* parent, const rb_node* node,
506 unsigned black_node_count, unsigned leaf_black_node_count)
507{
508 if (parent == NULL) {
509 VERIFY(tree->root == node);
510 VERIFY(node == NULL || COLOR(node) == RB_BLACK);
511 } else {
512 VERIFY(parent->llink == node || parent->rlink == node);
513 }
514 if (node) {
515 VERIFY(PARENT(node) == parent);
516 if (parent) {
517 if (parent->llink == node) {
518 VERIFY(tree->cmp_func(parent->key, node->key) > 0);
519 } else {
520 ASSERT(parent->rlink == node);
521 VERIFY(tree->cmp_func(parent->key, node->key) < 0);
522 }
523 }
524 if (COLOR(node) == RB_RED) {
525 /* Verify that every child of a red node is black. */
526 if (node->llink)
527 VERIFY(COLOR(node->llink) == RB_BLACK);
528 if (node->rlink)
529 VERIFY(COLOR(node->rlink) == RB_BLACK);
530 } else {
531 black_node_count++;
532 }
533 if (!node->llink && !node->rlink) {
534 /* Verify that each path to a leaf contains the same number of black nodes. */
535 VERIFY(black_node_count == leaf_black_node_count);
536 }
537 bool l = node_verify(tree, node, node->llink, black_node_count, leaf_black_node_count);
538 bool r = node_verify(tree, node, node->rlink, black_node_count, leaf_black_node_count);
539 return l && r;
540 }
541 return true;
542}
543
544bool
546{
547 if (tree->root)
549 unsigned leaf_black_node_count = 0;
550 if (tree->root) {
551 VERIFY(tree->count > 0);
552 for (rb_node* node = tree->root; node; node = node->llink)
553 if (COLOR(node) == RB_BLACK)
554 leaf_black_node_count++;
555 } else {
556 VERIFY(tree->count == 0);
557 }
558 return node_verify(tree, NULL, tree->root, 0, leaf_black_node_count);
559}
560
561rb_itor*
563{
564 rb_itor* itor = MALLOC(sizeof(*itor));
565 if (itor) {
566 itor->tree = tree;
567 itor->node = NULL;
568 }
569 return itor;
570}
571
574{
575 dict_itor* itor = MALLOC(sizeof(*itor));
576 if (itor) {
577 if (!(itor->_itor = rb_itor_new(tree))) {
578 FREE(itor);
579 return NULL;
580 }
581 itor->_vtable = &rb_tree_itor_vtable;
582 }
583 return itor;
584}
585
587bool rb_itor_valid(const rb_itor* itor) { return tree_iterator_valid(itor); }
589
590bool
592{
593 if (itor->node)
594 itor->node = node_next(itor->node);
595 return itor->node != NULL;
596}
597
598bool
600{
601 if (itor->node)
602 itor->node = node_prev(itor->node);
603 return itor->node != NULL;
604}
605
606bool
607rb_itor_nextn(rb_itor* itor, size_t count)
608{
609 while (count--) {
610 if (!rb_itor_next(itor))
611 return false;
612 }
613 return itor->node != NULL;
614}
615
616bool
617rb_itor_prevn(rb_itor* itor, size_t count)
618{
619 while (count--) {
620 if (!rb_itor_prev(itor))
621 return false;
622 }
623 return itor->node != NULL;
624}
625
626bool rb_itor_first(rb_itor* itor) { return tree_iterator_first(itor); }
627bool rb_itor_last(rb_itor* itor) { return tree_iterator_last(itor); }
628bool rb_itor_search(rb_itor* itor, const void* key) { return tree_iterator_search(itor, key); }
629bool rb_itor_search_le(rb_itor* itor, const void* key) { return tree_iterator_search_le(itor, key); }
630bool rb_itor_search_lt(rb_itor* itor, const void* key) { return tree_iterator_search_lt(itor, key); }
631bool rb_itor_search_ge(rb_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
632bool rb_itor_search_gt(rb_itor* itor, const void* key) { return tree_iterator_search_gt(itor, key); }
633const void* rb_itor_key(const rb_itor* itor) { return tree_iterator_key(itor); }
634void** rb_itor_datum(rb_itor* itor) { return tree_iterator_datum(itor); }
635int rb_itor_compare(const rb_itor* i1, const rb_itor* i2) { return tree_iterator_compare(i1, i2); }
636
637bool
639{
640 if (!it->node)
641 return false;
642 remove_node(it->tree, it->node);
643 it->node = NULL;
644 return true;
645}
dict_remove_result(* dict_remove_func)(void *obj, const void *key)
Definition dict.h:90
int(* dict_compare_func)(const void *, const void *)
Definition dict.h:54
bool(* dict_select_func)(void *obj, size_t n, const void **key, void **datum)
Definition dict.h:93
void(* dict_invalidate_func)(void *itor)
Definition dict.h:117
size_t(* dict_traverse_func)(void *obj, dict_visit_func visit, void *user_data)
Definition dict.h:92
dict_insert_result(* dict_insert_func)(void *obj, void *key)
Definition dict.h:87
void(* dict_delete_func)(void *, void *)
Definition dict.h:57
int(* dict_icompare_func)(void *itor1, void *itor2)
Definition dict.h:128
bool(* dict_nextn_func)(void *itor, size_t count)
Definition dict.h:120
bool(* dict_valid_func)(const void *itor)
Definition dict.h:116
size_t(* dict_count_func)(const void *obj)
Definition dict.h:94
bool(* dict_first_func)(void *itor)
Definition dict.h:122
bool(* dict_next_func)(void *itor)
Definition dict.h:118
void *(* dict_key_func)(void *itor)
Definition dict.h:124
size_t(* dict_dfree_func)(void *obj, dict_delete_func delete_func)
Definition dict.h:85
void **(* dict_datum_func)(void *itor)
Definition dict.h:125
bool(* dict_prevn_func)(void *itor, size_t count)
Definition dict.h:121
void **(* dict_search_func)(void *obj, const void *key)
Definition dict.h:88
bool(* dict_isearch_func)(void *itor, const void *key)
Definition dict.h:126
bool(* dict_iremove_func)(void *itor)
Definition dict.h:127
bool(* dict_prev_func)(void *itor)
Definition dict.h:119
dict_itor *(* dict_inew_func)(void *obj)
Definition dict.h:84
bool(* dict_last_func)(void *itor)
Definition dict.h:123
bool(* dict_verify_func)(const void *obj)
Definition dict.h:95
bool(* dict_visit_func)(const void *, void *, void *)
Definition dict.h:59
size_t(* dict_clear_func)(void *obj, dict_delete_func delete_func)
Definition dict.h:91
void(* dict_ifree_func)(void *itor)
Definition dict.h:115
#define FREE(p)
#define ASSERT(expr)
#define VERIFY(expr)
#define MALLOC(n)
#define SWAP(a, b, v)
void ** rb_tree_search_lt(rb_tree *tree, const void *key)
Definition rb_tree.c:172
size_t rb_tree_min_path_length(const rb_tree *tree)
Definition rb_tree.c:380
bool rb_itor_search_lt(rb_itor *itor, const void *key)
Definition rb_tree.c:630
#define PARENT(node)
Definition rb_tree.c:50
bool rb_itor_search_ge(rb_itor *itor, const void *key)
Definition rb_tree.c:631
const void * rb_itor_key(const rb_itor *itor)
Definition rb_tree.c:633
rb_tree * rb_tree_new(dict_compare_func cmp_func)
Definition rb_tree.c:113
bool rb_itor_next(rb_itor *itor)
Definition rb_tree.c:591
bool rb_itor_valid(const rb_itor *itor)
Definition rb_tree.c:587
void ** rb_tree_search_ge(rb_tree *tree, const void *key)
Definition rb_tree.c:173
dict_itor * rb_dict_itor_new(rb_tree *tree)
Definition rb_tree.c:573
size_t rb_tree_traverse(rb_tree *tree, dict_visit_func visit, void *user_data)
Definition rb_tree.c:385
size_t rb_tree_total_path_length(const rb_tree *tree)
Definition rb_tree.c:382
void ** rb_tree_search(rb_tree *tree, const void *key)
Definition rb_tree.c:170
#define SET_BLACK(node)
Definition rb_tree.c:54
bool rb_itor_search_le(rb_itor *itor, const void *key)
Definition rb_tree.c:629
void rb_itor_invalidate(rb_itor *itor)
Definition rb_tree.c:588
size_t rb_tree_clear(rb_tree *tree, dict_delete_func delete_func)
Definition rb_tree.c:149
size_t rb_tree_max_path_length(const rb_tree *tree)
Definition rb_tree.c:381
rb_itor * rb_itor_new(rb_tree *tree)
Definition rb_tree.c:562
bool rb_itor_remove(rb_itor *it)
Definition rb_tree.c:638
bool rb_itor_prevn(rb_itor *itor, size_t count)
Definition rb_tree.c:617
bool rb_itor_search(rb_itor *itor, const void *key)
Definition rb_tree.c:628
bool rb_itor_prev(rb_itor *itor)
Definition rb_tree.c:599
#define SET_PARENT(node, p)
Definition rb_tree.c:55
#define SET_RED(node)
Definition rb_tree.c:53
void ** rb_itor_datum(rb_itor *itor)
Definition rb_tree.c:634
bool rb_itor_first(rb_itor *itor)
Definition rb_tree.c:626
size_t rb_tree_free(rb_tree *tree, dict_delete_func delete_func)
Definition rb_tree.c:142
bool rb_itor_nextn(rb_itor *itor, size_t count)
Definition rb_tree.c:607
void rb_itor_free(rb_itor *itor)
Definition rb_tree.c:586
#define RB_BLACK
Definition rb_tree.c:48
bool rb_itor_last(rb_itor *itor)
Definition rb_tree.c:627
dict_insert_result rb_tree_insert(rb_tree *tree, void *key)
Definition rb_tree.c:177
bool rb_tree_verify(const rb_tree *tree)
Definition rb_tree.c:545
void ** rb_tree_search_le(rb_tree *tree, const void *key)
Definition rb_tree.c:171
size_t rb_tree_count(const rb_tree *tree)
Definition rb_tree.c:379
dict * rb_dict_new(dict_compare_func cmp_func)
Definition rb_tree.c:128
dict_remove_result rb_tree_remove(rb_tree *tree, const void *key)
Definition rb_tree.c:294
bool rb_tree_select(rb_tree *tree, size_t n, const void **key, void **datum)
Definition rb_tree.c:400
#define COLOR(node)
Definition rb_tree.c:51
#define RB_RED
Definition rb_tree.c:47
bool rb_itor_search_gt(rb_itor *itor, const void *key)
Definition rb_tree.c:632
void ** rb_tree_search_gt(rb_tree *tree, const void *key)
Definition rb_tree.c:174
int rb_itor_compare(const rb_itor *i1, const rb_itor *i2)
Definition rb_tree.c:635
void * _itor
Definition dict.h:175
const itor_vtable * _vtable
Definition dict.h:176
Definition dict.h:151
void * _object
Definition dict.h:152
const dict_vtable * _vtable
Definition dict.h:153
rb_tree * tree
Definition rb_tree.c:62
rb_node * node
Definition rb_tree.c:62
rb_node * rlink
Definition rb_tree.c:44
void * datum
Definition rb_tree.c:41
rb_node * llink
Definition rb_tree.c:43
void * key
Definition rb_tree.c:40
intptr_t color
Definition rb_tree.c:42
dict_compare_func cmp_func
Definition tree_common.c:38
tree_node * root
Definition tree_common.c:38
size_t count
Definition tree_common.c:38
size_t rotation_count
Definition tree_common.c:38
bool tree_iterator_last(void *Iterator)
void ** tree_iterator_datum(void *Iterator)
void * tree_node_max(void *Node)
void tree_iterator_invalidate(void *Iterator)
void ** tree_search_gt(void *Tree, const void *key)
int tree_iterator_compare(const void *Iterator1, const void *Iterator2)
void * tree_search_node(void *Tree, const void *key)
bool tree_iterator_search_le(void *Iterator, const void *key)
bool tree_iterator_valid(const void *Iterator)
size_t tree_count(const void *Tree)
void ** tree_search_lt(void *Tree, const void *key)
const void * tree_iterator_key(const void *Iterator)
size_t tree_min_path_length(const void *Tree)
void * tree_node_min(void *Node)
void ** tree_search(void *Tree, const void *key)
size_t tree_total_path_length(const void *Tree)
bool tree_iterator_first(void *Iterator)
void tree_iterator_free(void *Iterator)
bool tree_iterator_search_lt(void *Iterator, const void *key)
bool tree_iterator_search_ge(void *Iterator, const void *key)
size_t tree_max_path_length(const void *Tree)
bool tree_iterator_search_gt(void *Iterator, const void *key)
void ** tree_search_ge(void *Tree, const void *key)
void ** tree_search_le(void *Tree, const void *key)
bool tree_iterator_search(void *Iterator, const void *key)
#define TREE_ITERATOR_FIELDS(tree_type, node_type)
Definition tree_common.h:54
#define TREE_FIELDS(node_type)
Definition tree_common.h:44