libdict
Data Structure C Library
Loading...
Searching...
No Matches
hb_tree.c
Go to the documentation of this file.
1/*
2 * libdict -- height-balanced (AVL) 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#include "hb_tree.h"
29
30#include "dict_private.h"
31#include "tree_common.h"
32
33typedef struct hb_node hb_node;
34
35struct hb_node {
36 void* key;
37 void* datum;
38 union {
39 intptr_t bal;
41 };
44};
45
46#define BAL_MASK ((intptr_t)3)
47#define PARENT(node) ((hb_node*) ((node)->bal & ~BAL_MASK))
48#define BAL_POS(node) ((node)->bal & 1)
49#define BAL_NEG(node) ((node)->bal & 2)
50
54
58
59static const dict_vtable hb_tree_vtable = {
60 true,
75};
76
77static const itor_vtable hb_tree_itor_vtable = {
96};
97
98static hb_node* node_prev(hb_node* node);
99static hb_node* node_next(hb_node* node);
100static hb_node* node_new(void* key);
101
102static bool node_verify(const hb_tree* tree, const hb_node* parent, const hb_node* node,
103 unsigned* height, size_t *count);
104
105hb_tree*
107{
108 ASSERT(cmp_func != NULL);
109
110 hb_tree* tree = MALLOC(sizeof(*tree));
111 if (tree) {
112 tree->root = NULL;
113 tree->count = 0;
114 tree->cmp_func = cmp_func;
115 tree->rotation_count = 0;
116 }
117 return tree;
118}
119
120dict*
122{
123 dict* dct = MALLOC(sizeof(*dct));
124 if (dct) {
125 if (!(dct->_object = hb_tree_new(cmp_func))) {
126 FREE(dct);
127 return NULL;
128 }
129 dct->_vtable = &hb_tree_vtable;
130 }
131 return dct;
132}
133
134size_t
136 const size_t count = hb_tree_clear(tree, delete_func);
137 FREE(tree);
138 return count;
139}
140
141size_t
143{
144 const size_t count = tree->count;
145
146 hb_node* node = tree->root;
147 while (node) {
148 if (node->llink || node->rlink) {
149 node = node->llink ? node->llink : node->rlink;
150 continue;
151 }
152 if (delete_func) delete_func(node->key, node->datum);
153 hb_node* const parent = PARENT(node);
154 FREE(node);
155 *(parent ? (parent->llink == node ? &parent->llink : &parent->rlink) : &tree->root) = NULL;
156 node = parent;
157 }
158 ASSERT(tree->root == NULL);
159 tree->count = 0;
160 return count;
161}
162
163/* L: rotate |q| left */
164static bool
165rotate_l(hb_tree* restrict const tree, hb_node* restrict const q)
166{
167 hb_node* restrict const qp = PARENT(q);
168 hb_node* restrict const qr = q->rlink;
169
170 ASSERT(BAL_POS(q));
171
172 hb_node *restrict const qrl = qr->llink;
173 const int qr_bal = qr->bal & BAL_MASK;
174
175 /* q->parent <- qr; q->bal <- (qr_bal == 0); */
176 q->bal = (intptr_t)qr | (qr_bal == 0);
177 if ((q->rlink = qrl) != NULL)
178 qrl->bal = (intptr_t)q | (qrl->bal & BAL_MASK); /* qrl->parent <- q; */
179
180 /* qr->parent <- qp; qr->bal <- -(qr_bal == 0); */
181 qr->bal = (intptr_t)qp | ((qr_bal == 0) << 1);
182 qr->llink = q;
183 *(qp == NULL ? &tree->root : qp->llink == q ? &qp->llink : &qp->rlink) = qr;
184
185 return (qr_bal == 0);
186}
187
188/* R: rotate |q| right. */
189static bool
190rotate_r(hb_tree* restrict const tree, hb_node* restrict const q)
191{
192 hb_node* restrict const qp = PARENT(q);
193 hb_node* restrict const ql = q->llink;
194
195 ASSERT(BAL_NEG(q));
196
197 hb_node* restrict const qlr = ql->rlink;
198 const int ql_bal = ql->bal & BAL_MASK;
199
200 /* q->parent <- ql; q->bal <- -(ql_bal == 0); */
201 q->bal = (intptr_t)ql | ((ql_bal == 0) << 1);
202 if ((q->llink = qlr) != NULL)
203 qlr->bal = (intptr_t)q | (qlr->bal & BAL_MASK); /* qlr->parent <- q; */
204
205 /* ql->parent <- qp; ql->bal <- (ql_bal == 0); */
206 ql->bal = (intptr_t)qp | (ql_bal == 0);
207 ql->rlink = q;
208 *(qp == NULL ? &tree->root : qp->llink == q ? &qp->llink : &qp->rlink) = ql;
209
210 return (ql_bal == 0);
211}
212
213/* RL: Rotate |q->rlink| right, then |q| left. */
214static void
215rotate_rl(hb_tree* restrict const tree, hb_node* restrict const q)
216{
217 hb_node* restrict const qp = PARENT(q);
218 hb_node* restrict const qr = q->rlink;
219 hb_node* restrict const qrl = qr->llink;
220
221 ASSERT(BAL_POS(q));
222 ASSERT(BAL_NEG(qr));
223
224 const int qrl_bal = qrl->bal & BAL_MASK;
225 hb_node* restrict const qrll = qrl->llink;
226 hb_node* restrict const qrlr = qrl->rlink;
227
228 /* qrl->parent <- qp; qrl->bal <- 0; */
229 qrl->bal = (intptr_t)qp;
230 *(qp == NULL ? &tree->root : qp->llink == q ? &qp->llink : &qp->rlink) = qrl;
231 qrl->llink = q;
232 qrl->rlink = qr;
233
234 /* q->parent <- qrl; q->bal <- -(qrl_bal == 1); */
235 q->bal = (intptr_t)qrl | ((qrl_bal == 1) << 1);
236 if ((q->rlink = qrll) != NULL)
237 qrll->bal = (intptr_t)q | (qrll->bal & BAL_MASK);
238
239 /* qr->parent <- qrl; qr->bal <- (qrl_bal == -1); */
240 qr->bal = (intptr_t)qrl | (qrl_bal == 2);
241 if ((qr->llink = qrlr) != NULL)
242 qrlr->bal = (intptr_t)qr | (qrlr->bal & BAL_MASK);
243}
244
245/* LR: rotate |q->llink| left, then rotate |q| right. */
246static void
247rotate_lr(hb_tree* restrict const tree, hb_node* restrict const q)
248{
249 hb_node* restrict const qp = PARENT(q);
250 hb_node* restrict const ql = q->llink;
251 hb_node* restrict const qlr = ql->rlink;
252
253 ASSERT(BAL_NEG(q));
254 ASSERT(BAL_POS(ql));
255
256 const int qlr_bal = qlr->bal & BAL_MASK;
257 hb_node* restrict const qlrl = qlr->llink;
258 hb_node* restrict const qlrr = qlr->rlink;
259
260 /* qlr->parent <- qp; qlr->bal <- 0; */
261 qlr->bal = (intptr_t)qp;
262 *(qp == NULL ? &tree->root : qp->llink == q ? &qp->llink : &qp->rlink) = qlr;
263 qlr->llink = ql;
264 qlr->rlink = q;
265
266 /* q->parent <- qlr; q->bal = (qlr_bal == -1); */
267 q->bal = (intptr_t)qlr | (qlr_bal == 2);
268 if ((q->llink = qlrr) != NULL)
269 qlrr->bal = (intptr_t)q | (qlrr->bal & BAL_MASK);
270
271 /* ql->parent <- qlr; ql->bal <- -(qlr_bal == 1); */
272 ql->bal = (intptr_t)qlr | ((qlr_bal == 1) << 1);
273 if ((ql->rlink = qlrl) != NULL)
274 qlrl->bal = (intptr_t)ql | (qlrl->bal & BAL_MASK);
275}
276
279{
280 int cmp = 0;
281 hb_node* node = tree->root;
282 hb_node* parent = NULL;
283 hb_node* q = NULL;
284
285 while (node) {
286 cmp = tree->cmp_func(key, node->key);
287 if (cmp < 0) {
288 parent = node; node = node->llink;
289 } else if (cmp > 0) {
290 parent = node; node = node->rlink;
291 } else
292 return (dict_insert_result) { &node->datum, false };
293 if (parent->bal & BAL_MASK)
294 q = parent;
295 }
296
297 hb_node* const add = node = node_new(key);
298 if (!node)
299 return (dict_insert_result) { NULL, false };
300
301 if (!(node->pptr = parent)) {
302 ASSERT(tree->count == 0);
303 ASSERT(tree->root == NULL);
304 tree->root = node;
305 } else {
306 if (cmp < 0)
307 parent->llink = node;
308 else
309 parent->rlink = node;
310
311 while (parent != q) {
312 ASSERT((parent->bal & BAL_MASK) == 0);
313 if (parent->llink == node)
314 parent->bal |= 2;
315 else
316 parent->bal |= 1;
317 node = parent;
318 parent = PARENT(parent);
319 }
320 if (q) {
321 ASSERT(q->bal & BAL_MASK);
322 if (q->llink == node) {
323 if (BAL_NEG(q)) { /* if q->balance == -1 */
324 if (BAL_POS(q->llink)) { /* if q->llink->balance == +1 */
325 tree->rotation_count += 2;
326 rotate_lr(tree, q);
327 } else {
328 tree->rotation_count += 1;
329 ASSERT(!rotate_r(tree, q));
330 }
331 } else { /* else, q->balance == +1 */
332 ASSERT(BAL_POS(q));
333 q->bal &= ~BAL_MASK; /* q->balance <- 0 */
334 }
335 } else {
336 ASSERT(q->rlink == node);
337 if (BAL_POS(q)) { /* if q->balance == +1 */
338 if (BAL_NEG(q->rlink)) { /* if q->rlink->balance == -1 */
339 tree->rotation_count += 2;
340 rotate_rl(tree, q);
341 } else {
342 tree->rotation_count += 1;
343 ASSERT(!rotate_l(tree, q));
344 }
345 } else { /* else, q->balance == -1 */
346 ASSERT(BAL_NEG(q));
347 q->bal &= ~BAL_MASK; /* q->balance <- 0 */
348 }
349 }
350 }
351 }
352 tree->count++;
353 return (dict_insert_result) { &add->datum, true };
354}
355
356void** hb_tree_search(hb_tree* tree, const void* key) { return tree_search(tree, key); }
357void** hb_tree_search_le(hb_tree* tree, const void* key) { return tree_search_le(tree, key); }
358void** hb_tree_search_lt(hb_tree* tree, const void* key) { return tree_search_lt(tree, key); }
359void** hb_tree_search_ge(hb_tree* tree, const void* key) { return tree_search_ge(tree, key); }
360void** hb_tree_search_gt(hb_tree* tree, const void* key) { return tree_search_gt(tree, key); }
361
362static void
363remove_node(hb_tree* tree, hb_node* node)
364{
365 if (node->llink && node->rlink) {
366 hb_node* restrict out =
367 BAL_POS(node) ? tree_node_min(node->rlink) : tree_node_max(node->llink);
368 void* tmp;
369 SWAP(node->key, out->key, tmp);
370 SWAP(node->datum, out->datum, tmp);
371 node = out;
372 }
373
374 hb_node* p = PARENT(node);
375 hb_node* child = node->llink ? node->llink : node->rlink;
376 FREE(node);
377 tree->count--;
378 if (child)
379 child->bal = (intptr_t)p | (child->bal & BAL_MASK);
380 if (!p) {
381 tree->root = child;
382 return;
383 }
384
385 bool left = (p->llink == node);
386 if (left) {
387 p->llink = child;
388 } else {
389 ASSERT(p->rlink == node);
390 p->rlink = child;
391 }
392 node = child;
393
394 unsigned rotations = 0;
395 for (;;) {
396 if (left) {
397 ASSERT(p->llink == node);
398 if (BAL_POS(p)) { /* if p->balance == +1 */
399 if (BAL_NEG(p->rlink)) { /* if p->rlink->balance == -1 */
400 rotations += 2;
401 rotate_rl(tree, p);
402 } else {
403 rotations += 1;
404 if (rotate_l(tree, p)) break;
405 }
406 node = PARENT(p);
407 } else if (BAL_NEG(p)) { /* else if p->balance == -1 */
408 p->bal &= ~BAL_MASK; /* p->balance <- 0 */
409 node = p;
410 } else { /* else, p->balance == 0 */
411 ASSERT((p->bal & BAL_MASK) == 0);
412 p->bal |= 1; /* p->balance <- +1 */
413 break;
414 }
415 } else {
416 ASSERT(p->rlink == node);
417 if (BAL_NEG(p)) { /* if p->balance == -1 */
418 if (BAL_POS(p->llink)) { /* if p->llink->balance == +1 */
419 rotations += 2;
420 rotate_lr(tree, p);
421 } else {
422 rotations += 1;
423 if (rotate_r(tree, p))
424 break;
425 }
426 node = PARENT(p);
427 } else if (BAL_POS(p)) { /* else if p->balance == +1 */
428 p->bal &= ~BAL_MASK; /* p->balance <- 0 */
429 node = p;
430 } else { /* else, p->balance == 0 */
431 ASSERT((p->bal & BAL_MASK) == 0);
432 p->bal |= 2; /* p->balance <- -1 */
433 break;
434 }
435 }
436
437 if (!(p = PARENT(node)))
438 break;
439 if (p->llink == node) {
440 left = true;
441 } else {
442 ASSERT(p->rlink == node);
443 left = false;
444 }
445 }
446 tree->rotation_count += rotations;
447}
448
450hb_tree_remove(hb_tree* tree, const void* key)
451{
452 hb_node* node = tree_search_node(tree, key);
453 if (!node)
454 return (dict_remove_result) { NULL, NULL, false };
455 const dict_remove_result result = { node->key, node->datum, true };
456 remove_node(tree, node);
457 return result;
458}
459
460size_t
462{
463 return tree_traverse(tree, visit, user_data);
464}
465
466bool
467hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
468{
469 if (n >= tree->count) {
470 if (key)
471 *key = NULL;
472 if (datum)
473 *datum = NULL;
474 return false;
475 }
476 hb_node* node;
477 if (n >= tree->count / 2) {
478 node = tree_node_max(tree->root);
479 n = tree->count - 1 - n;
480 while (n--)
481 node = node_prev(node);
482 } else {
483 node = tree_node_min(tree->root);
484 while (n--)
485 node = node_next(node);
486 }
487 if (key)
488 *key = node->key;
489 if (datum)
490 *datum = node->datum;
491 return true;
492}
493
494size_t hb_tree_count(const hb_tree* tree) { return tree_count(tree); }
498
499static hb_node*
500node_new(void* key)
501{
502 hb_node* node = MALLOC(sizeof(*node));
503 if (node) {
504 ASSERT((((intptr_t)node) & 3) == 0); /* Ensure malloc returns aligned result. */
505 node->key = key;
506 node->datum = NULL;
507 node->bal = 0; /* also initializes parent to NULL */
508 node->llink = NULL;
509 node->rlink = NULL;
510 }
511 return node;
512}
513
514static hb_node*
515node_prev(hb_node* node)
516{
517 if (node->llink)
518 return tree_node_max(node->llink);
519 hb_node* parent = PARENT(node);
520 while (parent && parent->llink == node) {
521 node = parent;
522 parent = PARENT(parent);
523 }
524 return parent;
525}
526
527static hb_node*
528node_next(hb_node* node)
529{
530 if (node->rlink)
531 return tree_node_min(node->rlink);
532 hb_node* parent = PARENT(node);
533 while (parent && parent->rlink == node) {
534 node = parent;
535 parent = PARENT(parent);
536 }
537 return parent;
538}
539
540static bool
541node_verify(const hb_tree* tree, const hb_node* parent, const hb_node* node,
542 unsigned* height, size_t *count)
543{
544 if (!parent) {
545 VERIFY(tree->root == node);
546 } else {
547 if (parent->llink == node) {
548 if (node)
549 VERIFY(tree->cmp_func(parent->key, node->key) > 0);
550 } else {
551 ASSERT(parent->rlink == node);
552 if (node)
553 VERIFY(tree->cmp_func(parent->key, node->key) < 0);
554 }
555 }
556 if (node) {
557 int bal = node->bal & BAL_MASK;
558 VERIFY(bal >= 0);
559 VERIFY(bal <= 2);
560 if (bal == 2) {
561 VERIFY(node->llink != NULL);
562 bal = -1;
563 } else if (bal == 1) {
564 VERIFY(node->rlink != NULL);
565 }
566 VERIFY(PARENT(node) == parent);
567 unsigned lheight, rheight;
568 if (!node_verify(tree, node, node->llink, &lheight, count) ||
569 !node_verify(tree, node, node->rlink, &rheight, count))
570 return false;
571 VERIFY(bal == (int)rheight - (int)lheight);
572 if (height)
573 *height = MAX(lheight, rheight) + 1;
574 *count += 1;
575 } else {
576 if (height)
577 *height = 0;
578 }
579 return true;
580}
581
582bool
584{
585 size_t count = 0;
586 bool verified = node_verify(tree, NULL, tree->root, NULL, &count);
587 VERIFY(tree->count == count);
588 return verified;
589}
590
591hb_itor*
593{
594 hb_itor* itor = MALLOC(sizeof(*itor));
595 if (itor) {
596 itor->tree = tree;
597 itor->node = NULL;
598 }
599 return itor;
600}
601
604{
605 dict_itor* itor = MALLOC(sizeof(*itor));
606 if (itor) {
607 if (!(itor->_itor = hb_itor_new(tree))) {
608 FREE(itor);
609 return NULL;
610 }
611 itor->_vtable = &hb_tree_itor_vtable;
612 }
613 return itor;
614}
615
617bool hb_itor_valid(const hb_itor* itor) { return tree_iterator_valid(itor); }
619
621 if (itor->node)
622 itor->node = node_next(itor->node);
623 return itor->node != NULL;
624}
625
627 if (itor->node)
628 itor->node = node_prev(itor->node);
629 return itor->node != NULL;
630}
631
632bool hb_itor_nextn(hb_itor* itor, size_t count) {
633 while (itor->node && count--)
634 itor->node = node_next(itor->node);
635 return itor->node != NULL;
636}
637
638bool hb_itor_prevn(hb_itor* itor, size_t count) {
639 while (itor->node && count--)
640 itor->node = node_prev(itor->node);
641 return itor->node != NULL;
642}
643
644bool hb_itor_first(hb_itor* itor) { return tree_iterator_first(itor); }
645bool hb_itor_last(hb_itor* itor) { return tree_iterator_last(itor); }
646bool hb_itor_search(hb_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
647bool hb_itor_search_le(hb_itor* itor, const void* key) { return tree_iterator_search_le(itor, key); }
648bool hb_itor_search_lt(hb_itor* itor, const void* key) { return tree_iterator_search_lt(itor, key); }
649bool hb_itor_search_ge(hb_itor* itor, const void* key) { return tree_iterator_search_ge(itor, key); }
650bool hb_itor_search_gt(hb_itor* itor, const void* key) { return tree_iterator_search_gt(itor, key); }
651int hb_itor_compare(const hb_itor* i1, const hb_itor* i2) { return tree_iterator_compare(i1, i2); }
652const void* hb_itor_key(const hb_itor* itor) { return tree_iterator_key(itor); }
653void** hb_itor_datum(hb_itor* itor) { return tree_iterator_datum(itor); }
654
655bool
657{
658 if (!itor->node)
659 return false;
660 remove_node(itor->tree, itor->node);
661 itor->node = NULL;
662 return true;
663}
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)
#define MAX(a, b)
bool hb_itor_search(hb_itor *itor, const void *key)
Definition hb_tree.c:646
dict_itor * hb_dict_itor_new(hb_tree *tree)
Definition hb_tree.c:603
size_t hb_tree_clear(hb_tree *tree, dict_delete_func delete_func)
Definition hb_tree.c:142
#define BAL_POS(node)
Definition hb_tree.c:48
bool hb_itor_search_gt(hb_itor *itor, const void *key)
Definition hb_tree.c:650
void ** hb_tree_search_lt(hb_tree *tree, const void *key)
Definition hb_tree.c:358
#define PARENT(node)
Definition hb_tree.c:47
void ** hb_tree_search(hb_tree *tree, const void *key)
Definition hb_tree.c:356
#define BAL_NEG(node)
Definition hb_tree.c:49
bool hb_tree_select(hb_tree *tree, size_t n, const void **key, void **datum)
Definition hb_tree.c:467
dict * hb_dict_new(dict_compare_func cmp_func)
Definition hb_tree.c:121
bool hb_itor_search_ge(hb_itor *itor, const void *key)
Definition hb_tree.c:649
void hb_itor_free(hb_itor *itor)
Definition hb_tree.c:616
hb_itor * hb_itor_new(hb_tree *tree)
Definition hb_tree.c:592
bool hb_itor_search_lt(hb_itor *itor, const void *key)
Definition hb_tree.c:648
bool hb_itor_prev(hb_itor *itor)
Definition hb_tree.c:626
void ** hb_tree_search_gt(hb_tree *tree, const void *key)
Definition hb_tree.c:360
hb_tree * hb_tree_new(dict_compare_func cmp_func)
Definition hb_tree.c:106
void hb_itor_invalidate(hb_itor *itor)
Definition hb_tree.c:618
size_t hb_tree_count(const hb_tree *tree)
Definition hb_tree.c:494
bool hb_itor_valid(const hb_itor *itor)
Definition hb_tree.c:617
size_t hb_tree_min_path_length(const hb_tree *tree)
Definition hb_tree.c:495
dict_insert_result hb_tree_insert(hb_tree *tree, void *key)
Definition hb_tree.c:278
void ** hb_tree_search_ge(hb_tree *tree, const void *key)
Definition hb_tree.c:359
bool hb_itor_nextn(hb_itor *itor, size_t count)
Definition hb_tree.c:632
#define BAL_MASK
Definition hb_tree.c:46
bool hb_itor_remove(hb_itor *itor)
Definition hb_tree.c:656
size_t hb_tree_free(hb_tree *tree, dict_delete_func delete_func)
Definition hb_tree.c:135
dict_remove_result hb_tree_remove(hb_tree *tree, const void *key)
Definition hb_tree.c:450
size_t hb_tree_max_path_length(const hb_tree *tree)
Definition hb_tree.c:496
int hb_itor_compare(const hb_itor *i1, const hb_itor *i2)
Definition hb_tree.c:651
bool hb_itor_last(hb_itor *itor)
Definition hb_tree.c:645
bool hb_itor_prevn(hb_itor *itor, size_t count)
Definition hb_tree.c:638
void ** hb_itor_datum(hb_itor *itor)
Definition hb_tree.c:653
bool hb_itor_next(hb_itor *itor)
Definition hb_tree.c:620
const void * hb_itor_key(const hb_itor *itor)
Definition hb_tree.c:652
bool hb_itor_search_le(hb_itor *itor, const void *key)
Definition hb_tree.c:647
bool hb_tree_verify(const hb_tree *tree)
Definition hb_tree.c:583
bool hb_itor_first(hb_itor *itor)
Definition hb_tree.c:644
size_t hb_tree_traverse(hb_tree *tree, dict_visit_func visit, void *user_data)
Definition hb_tree.c:461
void ** hb_tree_search_le(hb_tree *tree, const void *key)
Definition hb_tree.c:357
size_t hb_tree_total_path_length(const hb_tree *tree)
Definition hb_tree.c:497
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
hb_tree * tree
Definition hb_tree.c:56
hb_node * node
Definition hb_tree.c:56
hb_node * llink
Definition hb_tree.c:42
void * datum
Definition hb_tree.c:37
hb_node * pptr
Definition hb_tree.c:40
void * key
Definition hb_tree.c:36
hb_node * rlink
Definition hb_tree.c:43
intptr_t bal
Definition hb_tree.c:39
struct tree_node * rlink
Definition tree_common.c:34
struct tree_node * llink
Definition tree_common.c:34
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_traverse(void *Tree, dict_visit_func visit, void *user_data)
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