libdict 1.0.7
Data Structure C Library
Loading...
Searching...
No Matches
tree_common.c
Go to the documentation of this file.
1/*
2 * libdict - common definitions for binary search trees.
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 "tree_common.h"
29
30#include <string.h>
31#include "dict_private.h"
32
36
37typedef struct {
39} tree;
40
44
45void
46tree_node_rot_left(void* Tree, void* Node)
47{
48 tree_node* const n = Node;
49 tree_node* const nr = n->rlink;
50 ASSERT(nr != NULL);
51 if ((n->rlink = nr->llink) != NULL)
52 n->rlink->parent = n;
53 nr->llink = n;
54
55 tree_node* p = n->parent;
56 n->parent = nr;
57 nr->parent = p;
58 *(p == NULL ? &((tree*)Tree)->root : p->llink == n ? &p->llink : &p->rlink) = nr;
59}
60
61void
62tree_node_rot_right(void* Tree, void* Node)
63{
64 tree_node* const n = Node;
65 tree_node* const nl = n->llink;
66 ASSERT(nl != NULL);
67 if ((n->llink = nl->rlink) != NULL)
68 n->llink->parent = n;
69 nl->rlink = n;
70
71 tree_node* const p = n->parent;
72 n->parent = nl;
73 nl->parent = p;
74 *(p == NULL ? &((tree*)Tree)->root : p->llink == n ? &p->llink : &p->rlink) = nl;
75}
76
77void*
78tree_node_prev(void* Node)
79{
80 tree_node* node = Node;
81 if (node->llink)
82 return tree_node_max(node->llink);
83 tree_node* parent = node->parent;
84 while (parent && parent->llink == node) {
85 node = parent;
86 parent = parent->parent;
87 }
88 return parent;
89}
90
91void*
92tree_node_next(void* Node)
93{
94 tree_node* node = Node;
95 if (node->rlink)
96 return tree_node_min(node->rlink);
97 tree_node* parent = node->parent;
98 while (parent && parent->rlink == node) {
99 node = parent;
100 parent = parent->parent;
101 }
102 return parent;
103}
104
105void*
106tree_node_min(void* Node)
107{
108 tree_node* node = Node;
109 if (!node)
110 return NULL;
111 while (node->llink)
112 node = node->llink;
113 return node;
114}
115
116void*
117tree_node_max(void* Node)
118{
119 tree_node* node = Node;
120 if (!node)
121 return NULL;
122 while (node->rlink)
123 node = node->rlink;
124 return node;
125}
126
127void*
128tree_search_node(void* Tree, const void* key)
129{
130 tree* t = Tree;
131 for (tree_node* node = t->root; node;) {
132 const int cmp = t->cmp_func(key, node->key);
133 if (cmp < 0)
134 node = node->llink;
135 else if (cmp)
136 node = node->rlink;
137 else
138 return node;
139 }
140 return NULL;
141}
142
143void**
144tree_search(void* Tree, const void* key)
145{
146 tree_node* node = tree_search_node(Tree, key);
147 return node ? &node->datum : NULL;
148}
149
150void*
151tree_search_le_node(void* Tree, const void* key)
152{
153 tree* t = Tree;
154 tree_node* node = t->root, *ret = NULL;
155 while (node) {
156 const int cmp = t->cmp_func(key, node->key);
157 if (cmp == 0)
158 return node;
159 if (cmp < 0) {
160 node = node->llink;
161 } else {
162 ret = node;
163 node = node->rlink;
164 }
165 }
166 return ret;
167}
168
169void**
170tree_search_le(void* Tree, const void* key)
171{
172 tree_node* node = tree_search_le_node(Tree, key);
173 return node ? &node->datum : NULL;
174}
175
176void*
177tree_search_lt_node(void* Tree, const void* key)
178{
179 tree* t = Tree;
180 tree_node* node = t->root, *ret = NULL;
181 while (node) {
182 const int cmp = t->cmp_func(key, node->key);
183 if (cmp <= 0) {
184 node = node->llink;
185 } else {
186 ret = node;
187 node = node->rlink;
188 }
189 }
190 return ret;
191}
192
193void**
194tree_search_lt(void* Tree, const void* key)
195{
196 tree_node* node = tree_search_lt_node(Tree, key);
197 return node ? &node->datum : NULL;
198}
199
200void*
201tree_search_ge_node(void* Tree, const void* key)
202{
203 tree* t = Tree;
204 tree_node* node = t->root, *ret = NULL;
205 while (node) {
206 const int cmp = t->cmp_func(key, node->key);
207 if (cmp == 0) {
208 return node;
209 }
210 if (cmp < 0) {
211 ret = node;
212 node = node->llink;
213 } else {
214 node = node->rlink;
215 }
216 }
217 return ret;
218}
219
220void**
221tree_search_ge(void* Tree, const void* key)
222{
223 tree_node* node = tree_search_ge_node(Tree, key);
224 return node ? &node->datum : NULL;
225}
226
227void*
228tree_search_gt_node(void* Tree, const void* key)
229{
230 tree* t = Tree;
231 tree_node* node = t->root, *ret = NULL;
232 while (node) {
233 const int cmp = t->cmp_func(key, node->key);
234 if (cmp < 0) {
235 ret = node;
236 node = node->llink;
237 } else {
238 node = node->rlink;
239 }
240 }
241 return ret;
242}
243
244void**
245tree_search_gt(void* Tree, const void* key)
246{
247 tree_node* node = tree_search_gt_node(Tree, key);
248 return node ? &node->datum : NULL;
249}
250
251size_t
252tree_traverse(void* Tree, dict_visit_func visit, void* user_data)
253{
254 ASSERT(visit != NULL);
255
256 tree* t = Tree;
257 size_t count = 0;
258 if (t->root) {
259 tree_node* node = tree_node_min(t->root);
260 do {
261 ++count;
262 if (!visit(node->key, node->datum, user_data)) break;
263 node = tree_node_next(node);
264 } while (node);
265 }
266 return count;
267}
268
269bool
270tree_select(void *Tree, size_t n, const void **key, void **datum)
271{
272 tree* t = Tree;
273 if (n >= t->count) {
274 if (key)
275 *key = NULL;
276 if (datum)
277 *datum = NULL;
278 return false;
279 }
280 tree_node* node;
281 if (n >= t->count / 2) {
282 node = tree_node_max(t->root);
283 n = t->count - 1 - n;
284 while (n--)
285 node = tree_node_prev(node);
286 } else {
287 node = tree_node_min(t->root);
288 while (n--)
289 node = tree_node_next(node);
290 }
291 if (key)
292 *key = node->key;
293 if (datum)
294 *datum = node->datum;
295 return true;
296}
297
298size_t
299tree_count(const void* Tree)
300{
301 return ((const tree*)Tree)->count;
302}
303
304/* Checks one node of tree_verify_common()'s traversal: its key lies strictly
305 * between the bounds inherited from its ancestors (NULL meaning unbounded), and
306 * its children link back to it. */
307static bool
308node_verify_common(const tree* t, const tree_node* node, const void* lower,
309 const void* upper)
310{
311 /* Global key ordering. Comparing a node only against its immediate parent
312 * would accept an entire subtree placed on the wrong side. */
313 if (lower)
314 VERIFY(t->cmp_func(lower, node->key) < 0);
315 if (upper)
316 VERIFY(t->cmp_func(upper, node->key) > 0);
317 if (node->llink)
318 VERIFY(node->llink->parent == node);
319 if (node->rlink)
320 VERIFY(node->rlink->parent == node);
321 return true;
322}
323
324/* Verifies the invariants every tree shares: root/parent link consistency,
325 * global key ordering, and that |count| matches the number of nodes reachable.
326 *
327 * This is iterative for the same reason the path-length statistics are: a
328 * degenerate sp_tree or tr_tree is as deep as it has nodes, so a recursive
329 * checker would overflow the stack on the very trees most likely to be
330 * malformed. It may only be used by trees with an untagged parent pointer --
331 * hb_tree and rb_tree pack bits into that field and must verify themselves. */
332bool
333tree_verify_common(const void* Tree)
334{
335 const tree* t = Tree;
336
337 VERIFY(t->root == NULL || t->root->parent == NULL);
338 if (t->root) {
339 VERIFY(t->count > 0);
340 } else {
341 VERIFY(t->count == 0);
342 }
343
344 /* (node, lower bound, upper bound) triples still to visit. A NULL bound
345 * means unbounded on that side. */
346 struct frame { const tree_node* node; const void* lower; const void* upper; };
347 struct frame* stack = NULL;
348 size_t size = 0, capacity = 0, count = 0;
349 bool ok = true, oom = false;
350
351#define PUSH(n, lo, hi) \
352 do { \
353 if (size == capacity) { \
354 const size_t cap = capacity ? capacity * 2 : 32; \
355 struct frame* items = MALLOC(cap * sizeof(*items)); \
356 if (!items) { oom = true; break; } \
357 if (stack) { \
358 memcpy(items, stack, size * sizeof(*items)); \
359 FREE(stack); \
360 } \
361 stack = items; \
362 capacity = cap; \
363 } \
364 stack[size].node = (n); \
365 stack[size].lower = (lo); \
366 stack[size].upper = (hi); \
367 ++size; \
368 } while (0)
369
370 if (t->root)
371 PUSH(t->root, NULL, NULL);
372
373 while (ok && !oom && size) {
374 const struct frame top = stack[--size];
375 const tree_node* const node = top.node;
376 if (!node_verify_common(t, node, top.lower, top.upper)) {
377 ok = false;
378 break;
379 }
380 ++count;
381 if (node->llink)
382 PUSH(node->llink, top.lower, node->key);
383 if (!oom && node->rlink)
384 PUSH(node->rlink, node->key, top.upper);
385 }
386#undef PUSH
387 if (stack)
388 FREE(stack);
389
390 if (oom) {
391 fprintf(stderr, "%s:%d (%s) out of memory\n", __FILE__, __LINE__, __func__);
392 return false;
393 }
394 if (!ok)
395 return false;
396 VERIFY(t->count == count);
397 return true;
398}
399
400size_t
401tree_clear(void* Tree, dict_delete_func delete_func)
402{
403 tree* t = Tree;
404 const size_t count = t->count;
405
406 tree_node* node = t->root;
407 while (node) {
408 if (node->llink || node->rlink) {
409 node = node->llink ? node->llink : node->rlink;
410 continue;
411 }
412 if (delete_func) delete_func(node->key, node->datum);
413 tree_node* const parent = node->parent;
414 /* Unlink before freeing: comparing a pointer to a freed object is UB. */
415 *(parent ? (parent->llink == node ? &parent->llink : &parent->rlink) : &t->root) = NULL;
416 FREE(node);
417 node = parent;
418 }
419 ASSERT(t->root == NULL);
420 t->count = 0;
421 return count;
422}
423
424size_t
425tree_free(void* Tree, dict_delete_func delete_func)
426{
427 const size_t count = tree_clear(Tree, delete_func);
428 FREE(Tree);
429 return count;
430}
431
432/* The three path-length statistics below share one iterative traversal.
433 *
434 * They must not recurse: a degenerate sp_tree or tr_tree (e.g. a treap given a
435 * constant priority function) is as deep as it has nodes, so recursion would
436 * overflow the stack on a few hundred thousand elements. They must also not
437 * walk parent pointers, because hb_tree and rb_tree pack bits into that field
438 * and only their own PARENT() macro may decode it -- so the traversal keeps an
439 * explicit, growable stack of (node, depth) pairs instead.
440 *
441 * Depths are 1-based, i.e. the root is at depth 1. */
442typedef struct {
444 size_t depth;
445} node_depth;
446
447typedef struct {
449 size_t size;
450 size_t capacity;
451} node_stack;
452
453/* Returns false only if memory could not be obtained. */
454static bool
455node_stack_push(node_stack* stack, const tree_node* node, size_t depth)
456{
457 if (stack->size == stack->capacity) {
458 const size_t capacity = stack->capacity ? stack->capacity * 2 : 32;
459 node_depth* items = MALLOC(capacity * sizeof(*items));
460 if (!items)
461 return false;
462 if (stack->items) {
463 memcpy(items, stack->items, stack->size * sizeof(*items));
464 FREE(stack->items);
465 }
466 stack->items = items;
467 stack->capacity = capacity;
468 }
469 stack->items[stack->size].node = node;
470 stack->items[stack->size].depth = depth;
471 ++stack->size;
472 return true;
473}
474
475/* Computes, over all nodes of |t|:
476 * |min_path| the shallowest depth at which a child link is absent,
477 * |max_path| the greatest node depth,
478 * |total_path| the sum of all node depths.
479 * Any output pointer may be NULL. Returns false if the traversal ran out of
480 * memory, in which case the outputs are not written. */
481static bool
482tree_path_lengths(const tree* t, size_t* min_path, size_t* max_path,
483 size_t* total_path)
484{
485 size_t min_len = 0, max_len = 0, total_len = 0;
486 node_stack stack = { NULL, 0, 0 };
487 bool ok = true;
488
489 if (t->root && !node_stack_push(&stack, t->root, 1))
490 ok = false;
491
492 while (ok && stack.size) {
493 const node_depth top = stack.items[--stack.size];
494 const tree_node* const node = top.node;
495 const size_t depth = top.depth;
496
497 if (depth > max_len)
498 max_len = depth;
499 total_len += depth;
500 if (!node->llink || !node->rlink) {
501 if (!min_len || depth < min_len)
502 min_len = depth;
503 }
504 if (node->llink && !node_stack_push(&stack, node->llink, depth + 1))
505 ok = false;
506 if (ok && node->rlink && !node_stack_push(&stack, node->rlink, depth + 1))
507 ok = false;
508 }
509 if (stack.items)
510 FREE(stack.items);
511
512 if (!ok)
513 return false;
514 if (min_path)
515 *min_path = min_len;
516 if (max_path)
517 *max_path = max_len;
518 if (total_path)
519 *total_path = total_len;
520 return true;
521}
522
523size_t
524tree_min_path_length(const void* Tree)
525{
526 size_t len = 0;
527 tree_path_lengths(Tree, &len, NULL, NULL);
528 return len;
529}
530
531size_t
532tree_max_path_length(const void* Tree)
533{
534 size_t len = 0;
535 tree_path_lengths(Tree, NULL, &len, NULL);
536 return len;
537}
538
539size_t
540tree_total_path_length(const void* Tree)
541{
542 size_t len = 0;
543 tree_path_lengths(Tree, NULL, NULL, &len);
544 return len;
545}
546
547bool
548tree_iterator_valid(const void* Iterator)
549{
550 return ((const tree_iterator*)Iterator)->node != NULL;
551}
552
553void
555{
556 ((tree_iterator*)Iterator)->node = NULL;
557}
558
559void
560tree_iterator_free(void* Iterator)
561{
562 tree_iterator* iterator = Iterator;
563 iterator->node = NULL;
564 FREE(iterator);
565}
566
567bool
568tree_iterator_next(void* Iterator)
569{
570 tree_iterator* iterator = Iterator;
571 if(iterator->node) {
572 iterator->node = tree_node_next(iterator->node);
573 if(iterator->node) return true;
574 }
575 return false;
576}
577
578bool
579tree_iterator_prev(void* Iterator)
580{
581 tree_iterator* iterator = Iterator;
582 if(iterator->node) {
583 iterator->node = tree_node_prev(iterator->node);
584 if(iterator->node) return true;
585 }
586 return false;
587}
588
589bool
590tree_iterator_nextn(void* Iterator, size_t count)
591{
592 tree_iterator* iterator = Iterator;
593 while (iterator->node && count--)
594 iterator->node = tree_node_next(iterator->node);
595 return iterator->node != NULL;
596}
597
598bool
599tree_iterator_prevn(void* Iterator, size_t count)
600{
601 tree_iterator* iterator = Iterator;
602 while (iterator->node && count--)
603 iterator->node = tree_node_prev(iterator->node);
604 return iterator->node != NULL;
605}
606
607bool
608tree_iterator_first(void* Iterator)
609{
610 tree_iterator* iterator = Iterator;
611 return (iterator->node = tree_node_min(iterator->tree->root)) != NULL;
612}
613
614bool
615tree_iterator_last(void* Iterator)
616{
617 tree_iterator* iterator = Iterator;
618 return (iterator->node = tree_node_max(iterator->tree->root)) != NULL;
619}
620
621bool
622tree_iterator_search(void* Iterator, const void* key)
623{
624 tree_iterator* iterator = Iterator;
625 return (iterator->node = tree_search_node(iterator->tree, key)) != NULL;
626}
627
628bool
629tree_iterator_search_le(void* Iterator, const void* key)
630{
631 tree_iterator* iterator = Iterator;
632 return (iterator->node = tree_search_le_node(iterator->tree, key)) != NULL;
633}
634
635bool
636tree_iterator_search_lt(void* Iterator, const void* key)
637{
638 tree_iterator* iterator = Iterator;
639 return (iterator->node = tree_search_lt_node(iterator->tree, key)) != NULL;
640}
641
642bool
643tree_iterator_search_ge(void* Iterator, const void* key)
644{
645 tree_iterator* iterator = Iterator;
646 return (iterator->node = tree_search_ge_node(iterator->tree, key)) != NULL;
647}
648
649bool
650tree_iterator_search_gt(void* Iterator, const void* key)
651{
652 tree_iterator* iterator = Iterator;
653 return (iterator->node = tree_search_gt_node(iterator->tree, key)) != NULL;
654}
655
656int
657tree_iterator_compare(const void* Iterator1, const void* Iterator2)
658{
659 const tree_iterator* itor1 = Iterator1;
660 const tree_iterator* itor2 = Iterator2;
661 ASSERT(itor1->tree == itor2->tree);
662 if (!itor1->node)
663 return !itor2->node ? 0 : -1;
664 if (!itor2->node)
665 return 1;
666 return itor1->tree->cmp_func(itor1->node->key, itor2->node->key);
667}
668
669const void*
670tree_iterator_key(const void* Iterator)
671{
672 const tree_iterator* iterator = Iterator;
673 return iterator->node ? iterator->node->key : NULL;
674}
675
676void**
677tree_iterator_datum(void* Iterator)
678{
679 tree_iterator* iterator = Iterator;
680 return iterator->node ? &iterator->node->datum : NULL;
681}
682
683void*
684tree_iterator_key_vt(void* Iterator)
685{
686 return dict_unconst(tree_iterator_key(Iterator));
687}
688
689int
690tree_iterator_compare_vt(void* Iterator1, void* Iterator2)
691{
692 return tree_iterator_compare(Iterator1, Iterator2);
693}
void(* dict_delete_func)(void *, void *)
A pointer to a function that is called when a key-value pair gets removed from a dictionary.
Definition dict.h:62
bool(* dict_visit_func)(const void *, void *, void *)
A pointer to a function used for iterating over dictionary contents.
Definition dict.h:64
#define FREE(p)
#define ASSERT(expr)
#define VERIFY(expr)
#define MALLOC(n)
size_t depth
const tree_node * node
node_depth * items
size_t size
size_t capacity
tree_node * node
Definition tree_common.c:42
struct tree_node * parent
Definition tree_common.c:34
struct tree_node * rlink
Definition tree_common.c:34
void * datum
Definition tree_common.c:34
void * key
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
bool tree_iterator_last(void *Iterator)
size_t tree_free(void *Tree, dict_delete_func delete_func)
void * tree_search_gt_node(void *Tree, const void *key)
void ** tree_iterator_datum(void *Iterator)
bool tree_iterator_next(void *Iterator)
void * tree_search_le_node(void *Tree, const void *key)
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_node_rot_left(void *Tree, void *Node)
Definition tree_common.c:46
void * tree_search_node(void *Tree, const void *key)
bool tree_verify_common(const void *Tree)
#define PUSH(n, lo, hi)
bool tree_iterator_search_le(void *Iterator, const void *key)
void * tree_search_lt_node(void *Tree, const void *key)
bool tree_iterator_valid(const void *Iterator)
size_t tree_count(const void *Tree)
struct tree_node tree_node
void ** tree_search_lt(void *Tree, const void *key)
size_t tree_clear(void *Tree, dict_delete_func delete_func)
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)
bool tree_iterator_nextn(void *Iterator, size_t count)
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)
bool tree_select(void *Tree, size_t n, const void **key, void **datum)
void tree_iterator_free(void *Iterator)
bool tree_iterator_prevn(void *Iterator, size_t count)
bool tree_iterator_search_lt(void *Iterator, const void *key)
void * tree_node_prev(void *Node)
Definition tree_common.c:78
bool tree_iterator_search_ge(void *Iterator, const void *key)
size_t tree_max_path_length(const void *Tree)
void * tree_iterator_key_vt(void *Iterator)
int tree_iterator_compare_vt(void *Iterator1, void *Iterator2)
bool tree_iterator_search_gt(void *Iterator, const void *key)
void ** tree_search_ge(void *Tree, const void *key)
void tree_node_rot_right(void *Tree, void *Node)
Definition tree_common.c:62
void ** tree_search_le(void *Tree, const void *key)
void * tree_search_ge_node(void *Tree, const void *key)
bool tree_iterator_search(void *Iterator, const void *key)
void * tree_node_next(void *Node)
Definition tree_common.c:92
bool tree_iterator_prev(void *Iterator)
#define TREE_NODE_FIELDS(node_type)
Definition tree_common.h:33
#define TREE_ITERATOR_FIELDS(tree_type, node_type)
Definition tree_common.h:54
#define TREE_FIELDS(node_type)
Definition tree_common.h:44