1 /*
2 * Copyright (C) 1995-1997 by Sam Rushing <rushing@nightmare.com>
3 *
4 * All Rights Reserved
5 *
6 * Permission to use, copy, modify, and distribute this software and
7 * its documentation for any purpose and without fee is hereby
8 * granted, provided that the above copyright notice appear in all
9 * copies and that both that copyright notice and this permission
10 * notice appear in supporting documentation, and that the name of Sam
11 * Rushing not be used in advertising or publicity pertaining to
12 * distribution of the software without specific, written prior
13 * permission.
14 *
15 * SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 */
24
25 /* $Id: avl.c,v 1.11 2004/01/27 02:16:25 karl Exp $ */
26
27 /*
28 * This is a fairly straightfoward translation of a prototype
29 * written in python, 'avl_tree.py'. Read that file first.
30 */
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h>
38
39 #include "avl.h"
40
41 avl_node *
avl_node_new(void * key,avl_node * parent)42 avl_node_new (void * key,
43 avl_node * parent)
44 {
45 avl_node * node = (avl_node *) malloc (sizeof (avl_node));
46
47 if (!node) {
48 return NULL;
49 } else {
50 node->parent = parent;
51 node->key = key;
52 node->left = NULL;
53 node->right = NULL;
54 node->rank_and_balance = 0;
55 AVL_SET_BALANCE (node, 0);
56 AVL_SET_RANK (node, 1);
57 #ifdef HAVE_AVL_NODE_LOCK
58 thread_rwlock_create(&node->rwlock);
59 #endif
60 return node;
61 }
62 }
63
64 avl_tree *
avl_tree_new(avl_key_compare_fun_type compare_fun,void * compare_arg)65 avl_tree_new (avl_key_compare_fun_type compare_fun,
66 void * compare_arg)
67 {
68 avl_tree * t = (avl_tree *) malloc (sizeof (avl_tree));
69
70 if (!t) {
71 return NULL;
72 } else {
73 avl_node * root = avl_node_new((void *)NULL, (avl_node *) NULL);
74 if (!root) {
75 free (t);
76 return NULL;
77 } else {
78 t->root = root;
79 t->height = 0;
80 t->length = 0;
81 t->compare_fun = compare_fun;
82 t->compare_arg = compare_arg;
83 thread_rwlock_create(&t->rwlock);
84 return t;
85 }
86 }
87 }
88
89 static void
avl_tree_free_helper(avl_node * node,avl_free_key_fun_type free_key_fun)90 avl_tree_free_helper (avl_node * node, avl_free_key_fun_type free_key_fun)
91 {
92 if (node->left) {
93 avl_tree_free_helper (node->left, free_key_fun);
94 }
95 if (free_key_fun)
96 free_key_fun (node->key);
97 if (node->right) {
98 avl_tree_free_helper (node->right, free_key_fun);
99 }
100 #ifdef HAVE_AVL_NODE_LOCK
101 thread_rwlock_destroy (&node->rwlock);
102 #endif
103 free (node);
104 }
105
106 void
avl_tree_free(avl_tree * tree,avl_free_key_fun_type free_key_fun)107 avl_tree_free (avl_tree * tree, avl_free_key_fun_type free_key_fun)
108 {
109 if (tree->length) {
110 avl_tree_free_helper (tree->root->right, free_key_fun);
111 }
112 if (tree->root) {
113 #ifdef HAVE_AVL_NODE_LOCK
114 thread_rwlock_destroy(&tree->root->rwlock);
115 #endif
116 free (tree->root);
117 }
118 thread_rwlock_destroy(&tree->rwlock);
119 free (tree);
120 }
121
122 int
avl_insert(avl_tree * ob,void * key)123 avl_insert (avl_tree * ob,
124 void * key)
125 {
126 if (!(ob->root->right)) {
127 avl_node * node = avl_node_new (key, ob->root);
128 if (!node) {
129 return -1;
130 } else {
131 ob->root->right = node;
132 ob->length = ob->length + 1;
133 return 0;
134 }
135 } else { /* not self.right == None */
136 avl_node *t, *p, *s, *q, *r;
137 int a;
138
139 t = ob->root;
140 s = p = t->right;
141
142 while (1) {
143 if (ob->compare_fun (ob->compare_arg, key, p->key) < 1) {
144 /* move left */
145 AVL_SET_RANK (p, (AVL_GET_RANK (p) + 1));
146 q = p->left;
147 if (!q) {
148 /* insert */
149 avl_node * q_node = avl_node_new (key, p);
150 if (!q_node) {
151 return (-1);
152 } else {
153 q = q_node;
154 p->left = q;
155 break;
156 }
157 } else if (AVL_GET_BALANCE(q)) {
158 t = p;
159 s = q;
160 }
161 p = q;
162 } else {
163 /* move right */
164 q = p->right;
165 if (!q) {
166 /* insert */
167 avl_node * q_node = avl_node_new (key, p);
168 if (!q_node) {
169 return -1;
170 } else {
171 q = q_node;
172 p->right = q;
173 break;
174 }
175 } else if (AVL_GET_BALANCE(q)) {
176 t = p;
177 s = q;
178 }
179 p = q;
180 }
181 }
182
183 ob->length = ob->length + 1;
184
185 /* adjust balance factors */
186 if (ob->compare_fun (ob->compare_arg, key, s->key) < 1) {
187 r = p = s->left;
188 } else {
189 r = p = s->right;
190 }
191 while (p != q) {
192 if (ob->compare_fun (ob->compare_arg, key, p->key) < 1) {
193 AVL_SET_BALANCE (p, -1);
194 p = p->left;
195 } else {
196 AVL_SET_BALANCE (p, +1);
197 p = p->right;
198 }
199 }
200
201 /* balancing act */
202
203 if (ob->compare_fun (ob->compare_arg, key, s->key) < 1) {
204 a = -1;
205 } else {
206 a = +1;
207 }
208
209 if (AVL_GET_BALANCE (s) == 0) {
210 AVL_SET_BALANCE (s, a);
211 ob->height = ob->height + 1;
212 return 0;
213 } else if (AVL_GET_BALANCE (s) == -a) {
214 AVL_SET_BALANCE (s, 0);
215 return 0;
216 } else if (AVL_GET_BALANCE(s) == a) {
217 if (AVL_GET_BALANCE (r) == a) {
218 /* single rotation */
219 p = r;
220 if (a == -1) {
221 s->left = r->right;
222 if (r->right) {
223 r->right->parent = s;
224 }
225 r->right = s;
226 s->parent = r;
227 AVL_SET_RANK (s, (AVL_GET_RANK (s) - AVL_GET_RANK (r)));
228 } else {
229 s->right = r->left;
230 if (r->left) {
231 r->left->parent = s;
232 }
233 r->left = s;
234 s->parent = r;
235 AVL_SET_RANK (r, (AVL_GET_RANK (r) + AVL_GET_RANK (s)));
236 }
237 AVL_SET_BALANCE (s, 0);
238 AVL_SET_BALANCE (r, 0);
239 } else if (AVL_GET_BALANCE (r) == -a) {
240 /* double rotation */
241 if (a == -1) {
242 p = r->right;
243 r->right = p->left;
244 if (p->left) {
245 p->left->parent = r;
246 }
247 p->left = r;
248 r->parent = p;
249 s->left = p->right;
250 if (p->right) {
251 p->right->parent = s;
252 }
253 p->right = s;
254 s->parent = p;
255 AVL_SET_RANK (p, (AVL_GET_RANK (p) + AVL_GET_RANK (r)));
256 AVL_SET_RANK (s, (AVL_GET_RANK (s) - AVL_GET_RANK (p)));
257 } else {
258 p = r->left;
259 r->left = p->right;
260 if (p->right) {
261 p->right->parent = r;
262 }
263 p->right = r;
264 r->parent = p;
265 s->right = p->left;
266 if (p->left) {
267 p->left->parent = s;
268 }
269 p->left = s;
270 s->parent = p;
271 AVL_SET_RANK (r, (AVL_GET_RANK (r) - AVL_GET_RANK (p)));
272 AVL_SET_RANK (p, (AVL_GET_RANK (p) + AVL_GET_RANK (s)));
273 }
274 if (AVL_GET_BALANCE (p) == a) {
275 AVL_SET_BALANCE (s, -a);
276 AVL_SET_BALANCE (r, 0);
277 } else if (AVL_GET_BALANCE (p) == -a) {
278 AVL_SET_BALANCE (s, 0);
279 AVL_SET_BALANCE (r, a);
280 } else {
281 AVL_SET_BALANCE (s, 0);
282 AVL_SET_BALANCE (r, 0);
283 }
284 AVL_SET_BALANCE (p, 0);
285 }
286 /* finishing touch */
287 if (s == t->right) {
288 t->right = p;
289 } else {
290 t->left = p;
291 }
292 p->parent = t;
293 }
294 }
295 return 0;
296 }
297
298 int
avl_get_by_index(avl_tree * tree,unsigned long index,void ** value_address)299 avl_get_by_index (avl_tree * tree,
300 unsigned long index,
301 void ** value_address)
302 {
303 avl_node * p = tree->root->right;
304 unsigned long m = index + 1;
305 while (1) {
306 if (!p) {
307 return -1;
308 }
309 if (m < AVL_GET_RANK(p)) {
310 p = p->left;
311 } else if (m > AVL_GET_RANK(p)) {
312 m = m - AVL_GET_RANK(p);
313 p = p->right;
314 } else {
315 *value_address = p->key;
316 return 0;
317 }
318 }
319 }
320
321 int
avl_get_by_key(avl_tree * tree,void * key,void ** value_address)322 avl_get_by_key (avl_tree * tree,
323 void * key,
324 void **value_address)
325 {
326 avl_node * x = tree->root->right;
327 if (!x) {
328 return -1;
329 }
330 while (1) {
331 int compare_result = tree->compare_fun (tree->compare_arg, key, x->key);
332 if (compare_result < 0) {
333 if (x->left) {
334 x = x->left;
335 } else {
336 return -1;
337 }
338 } else if (compare_result > 0) {
339 if (x->right) {
340 x = x->right;
341 } else {
342 return -1;
343 }
344 } else {
345 *value_address = x->key;
346 return 0;
347 }
348 }
349 }
350
avl_delete(avl_tree * tree,void * key,avl_free_key_fun_type free_key_fun)351 int avl_delete(avl_tree *tree, void *key, avl_free_key_fun_type free_key_fun)
352 {
353 avl_node *x, *y, *p, *q, *r, *top, *x_child;
354 int shortened_side, shorter;
355
356 x = tree->root->right;
357 if (!x) {
358 return -1;
359 }
360 while (1) {
361 int compare_result = tree->compare_fun (tree->compare_arg, key, x->key);
362 if (compare_result < 0) {
363 /* move left
364 * We will be deleting from the left, adjust this node's
365 * rank accordingly
366 */
367 AVL_SET_RANK (x, (AVL_GET_RANK(x) - 1));
368 if (x->left) {
369 x = x->left;
370 } else {
371 /* Oops! now we have to undo the rank changes
372 * all the way up the tree
373 */
374 AVL_SET_RANK(x, (AVL_GET_RANK (x) + 1));
375 while (x != tree->root->right) {
376 if (x->parent->left == x) {
377 AVL_SET_RANK(x->parent, (AVL_GET_RANK (x->parent) + 1));
378 }
379 x = x->parent;
380 }
381 return -1; /* key not in tree */
382 }
383 } else if (compare_result > 0) {
384 /* move right */
385 if (x->right) {
386 x = x->right;
387 } else {
388 AVL_SET_RANK(x, (AVL_GET_RANK (x) + 1));
389 while (x != tree->root->right) {
390 if (x->parent->left == x) {
391 AVL_SET_RANK(x->parent, (AVL_GET_RANK (x->parent) + 1));
392 }
393 x = x->parent;
394 }
395 return -1; /* key not in tree */
396 }
397 } else {
398 break;
399 }
400 }
401
402 if (x->left && x->right) {
403 void * temp_key;
404
405 /* The complicated case.
406 * reduce this to the simple case where we are deleting
407 * a node with at most one child.
408 */
409
410 /* find the immediate predecessor <y> */
411 y = x->left;
412 while (y->right) {
413 y = y->right;
414 }
415 /* swap <x> with <y> */
416 temp_key = x->key;
417 x->key = y->key;
418 y->key = temp_key;
419 /* we know <x>'s left subtree lost a node because that's
420 * where we took it from
421 */
422 AVL_SET_RANK (x, (AVL_GET_RANK (x) - 1));
423 x = y;
424 }
425 /* now <x> has at most one child
426 * scoot this child into the place of <x>
427 */
428 if (x->left) {
429 x_child = x->left;
430 x_child->parent = x->parent;
431 } else if (x->right) {
432 x_child = x->right;
433 x_child->parent = x->parent;
434 } else {
435 x_child = NULL;
436 }
437
438 /* now tell <x>'s parent that a grandchild became a child */
439 if (x == x->parent->left) {
440 x->parent->left = x_child;
441 shortened_side = -1;
442 } else {
443 x->parent->right = x_child;
444 shortened_side = +1;
445 }
446
447 /*
448 * the height of the subtree <x>
449 * has now been shortened. climb back up
450 * the tree, rotating when necessary to adjust
451 * for the change.
452 */
453 shorter = 1;
454 p = x->parent;
455
456 /* return the key and node to storage */
457 if (free_key_fun)
458 free_key_fun (x->key);
459 #ifdef HAVE_AVL_NODE_LOCK
460 thread_rwlock_destroy (&x->rwlock);
461 #endif
462 free (x);
463
464 while (shorter && p->parent) {
465
466 /* case 1: height unchanged */
467 if (AVL_GET_BALANCE(p) == 0) {
468 if (shortened_side == -1) {
469 /* we removed a left child, the tree is now heavier
470 * on the right
471 */
472 AVL_SET_BALANCE (p, +1);
473 } else {
474 /* we removed a right child, the tree is now heavier
475 * on the left
476 */
477 AVL_SET_BALANCE (p, -1);
478 }
479 shorter = 0;
480
481 } else if (AVL_GET_BALANCE (p) == shortened_side) {
482 /* case 2: taller subtree shortened, height reduced */
483 AVL_SET_BALANCE (p, 0);
484 } else {
485 /* case 3: shorter subtree shortened */
486 top = p->parent;
487 /* set <q> to the taller of the two subtrees of <p> */
488 if (shortened_side == 1) {
489 q = p->left;
490 } else {
491 q = p->right;
492 }
493 if (AVL_GET_BALANCE (q) == 0) {
494 /* case 3a: height unchanged */
495 if (shortened_side == -1) {
496 /* single rotate left */
497 q->parent = p->parent;
498 p->right = q->left;
499 if (q->left) {
500 q->left->parent = p;
501 }
502 q->left = p;
503 p->parent = q;
504 AVL_SET_RANK (q, (AVL_GET_RANK (q) + AVL_GET_RANK (p)));
505 } else {
506 /* single rotate right */
507 q->parent = p->parent;
508 p->left = q->right;
509 if (q->right) {
510 q->right->parent = p;
511 }
512 q->right = p;
513 p->parent = q;
514 AVL_SET_RANK (p, (AVL_GET_RANK (p) - AVL_GET_RANK (q)));
515 }
516 shorter = 0;
517 AVL_SET_BALANCE (q, shortened_side);
518 AVL_SET_BALANCE (p, (- shortened_side));
519 } else if (AVL_GET_BALANCE (q) == AVL_GET_BALANCE (p)) {
520 /* case 3b: height reduced */
521 if (shortened_side == -1) {
522 /* single rotate left */
523 q->parent = p->parent;
524 p->right = q->left;
525 if (q->left) {
526 q->left->parent = p;
527 }
528 q->left = p;
529 p->parent = q;
530 AVL_SET_RANK (q, (AVL_GET_RANK (q) + AVL_GET_RANK (p)));
531 } else {
532 /* single rotate right */
533 q->parent = p->parent;
534 p->left = q->right;
535 if (q->right) {
536 q->right->parent = p;
537 }
538 q->right = p;
539 p->parent = q;
540 AVL_SET_RANK (p, (AVL_GET_RANK (p) - AVL_GET_RANK (q)));
541 }
542 shorter = 1;
543 AVL_SET_BALANCE (q, 0);
544 AVL_SET_BALANCE (p, 0);
545 } else {
546 /* case 3c: height reduced, balance factors opposite */
547 if (shortened_side == 1) {
548 /* double rotate right */
549 /* first, a left rotation around q */
550 r = q->right;
551 r->parent = p->parent;
552 q->right = r->left;
553 if (r->left) {
554 r->left->parent = q;
555 }
556 r->left = q;
557 q->parent = r;
558 /* now, a right rotation around p */
559 p->left = r->right;
560 if (r->right) {
561 r->right->parent = p;
562 }
563 r->right = p;
564 p->parent = r;
565 AVL_SET_RANK (r, (AVL_GET_RANK (r) + AVL_GET_RANK (q)));
566 AVL_SET_RANK (p, (AVL_GET_RANK (p) - AVL_GET_RANK (r)));
567 } else {
568 /* double rotate left */
569 /* first, a right rotation around q */
570 r = q->left;
571 r->parent = p->parent;
572 q->left = r->right;
573 if (r->right) {
574 r->right->parent = q;
575 }
576 r->right = q;
577 q->parent = r;
578 /* now a left rotation around p */
579 p->right = r->left;
580 if (r->left) {
581 r->left->parent = p;
582 }
583 r->left = p;
584 p->parent = r;
585 AVL_SET_RANK (q, (AVL_GET_RANK (q) - AVL_GET_RANK (r)));
586 AVL_SET_RANK (r, (AVL_GET_RANK (r) + AVL_GET_RANK (p)));
587 }
588 if (AVL_GET_BALANCE (r) == shortened_side) {
589 AVL_SET_BALANCE (q, (- shortened_side));
590 AVL_SET_BALANCE (p, 0);
591 } else if (AVL_GET_BALANCE (r) == (- shortened_side)) {
592 AVL_SET_BALANCE (q, 0);
593 AVL_SET_BALANCE (p, shortened_side);
594 } else {
595 AVL_SET_BALANCE (q, 0);
596 AVL_SET_BALANCE (p, 0);
597 }
598 AVL_SET_BALANCE (r, 0);
599 q = r;
600 }
601 /* a rotation has caused <q> (or <r> in case 3c) to become
602 * the root. let <p>'s former parent know this.
603 */
604 if (top->left == p) {
605 top->left = q;
606 } else {
607 top->right = q;
608 }
609 /* end case 3 */
610 p = q;
611 }
612 x = p;
613 p = x->parent;
614 /* shortened_side tells us which side we came up from */
615 if (x == p->left) {
616 shortened_side = -1;
617 } else {
618 shortened_side = +1;
619 }
620 } /* end while(shorter) */
621 /* when we're all done, we're one shorter */
622 tree->length = tree->length - 1;
623 return (0);
624 }
625
626 static int
avl_iterate_inorder_helper(avl_node * node,avl_iter_fun_type iter_fun,void * iter_arg)627 avl_iterate_inorder_helper (avl_node * node,
628 avl_iter_fun_type iter_fun,
629 void * iter_arg)
630 {
631 int result;
632 if (node->left) {
633 result = avl_iterate_inorder_helper (node->left, iter_fun, iter_arg);
634 if (result != 0) {
635 return result;
636 }
637 }
638 result = (iter_fun (node->key, iter_arg));
639 if (result != 0) {
640 return result;
641 }
642 if (node->right) {
643 result = avl_iterate_inorder_helper (node->right, iter_fun, iter_arg);
644 if (result != 0) {
645 return result;
646 }
647 }
648 return 0;
649 }
650
651 int
avl_iterate_inorder(avl_tree * tree,avl_iter_fun_type iter_fun,void * iter_arg)652 avl_iterate_inorder (avl_tree * tree,
653 avl_iter_fun_type iter_fun,
654 void * iter_arg)
655 {
656 int result;
657
658 if (tree->length) {
659 result = avl_iterate_inorder_helper (tree->root->right, iter_fun, iter_arg);
660 return (result);
661 } else {
662 return 0;
663 }
664 }
665
avl_get_first(avl_tree * tree)666 avl_node *avl_get_first(avl_tree *tree)
667 {
668 avl_node *node;
669
670 node = tree->root->right;
671 if (node == NULL || node->key == NULL) return NULL;
672
673 while (node->left)
674 node = node->left;
675
676 return node;
677 }
678
avl_get_prev(avl_node * node)679 avl_node *avl_get_prev(avl_node *node)
680 {
681 if (node->left) {
682 node = node->left;
683 while (node->right) {
684 node = node->right;
685 }
686
687 return node;
688 } else {
689 avl_node *child = node;
690 while (node->parent && node->parent->key) {
691 node = node->parent;
692 if (child == node->right) {
693 return node;
694 }
695 child = node;
696 }
697
698 return NULL;
699 }
700 }
701
avl_get_next(avl_node * node)702 avl_node *avl_get_next(avl_node *node)
703 {
704 if (node->right) {
705 node = node->right;
706 while (node->left) {
707 node = node->left;
708 }
709
710 return node;
711 } else {
712 avl_node *child = node;
713 while (node->parent && node->parent->key) {
714 node = node->parent;
715 if (child == node->left) {
716 return node;
717 }
718 child = node;
719 }
720
721 return NULL;
722 }
723 }
724
725 /* iterate a function over a range of indices, using get_predecessor */
726
727 int
avl_iterate_index_range(avl_tree * tree,avl_iter_index_fun_type iter_fun,unsigned long low,unsigned long high,void * iter_arg)728 avl_iterate_index_range (avl_tree * tree,
729 avl_iter_index_fun_type iter_fun,
730 unsigned long low,
731 unsigned long high,
732 void * iter_arg)
733 {
734 unsigned long m;
735 unsigned long num_left;
736 avl_node * node;
737
738 if (high > tree->length) {
739 return -1;
740 }
741 num_left = (high - low);
742 /* find the <high-1>th node */
743 m = high;
744 node = tree->root->right;
745 while (1) {
746 if (m < AVL_GET_RANK (node)) {
747 node = node->left;
748 } else if (m > AVL_GET_RANK (node)) {
749 m = m - AVL_GET_RANK (node);
750 node = node->right;
751 } else {
752 break;
753 }
754 }
755 /* call <iter_fun> on <node>, <get_pred(node)>, ... */
756 while (num_left) {
757 num_left = num_left - 1;
758 if (iter_fun (num_left, node->key, iter_arg) != 0) {
759 return -1;
760 }
761 node = avl_get_prev (node);
762 }
763 return 0;
764 }
765
766 /* If <key> is present in the tree, return that key's node, and set <*index>
767 * appropriately. If not, return NULL, and set <*index> to the position
768 * representing the closest preceding value.
769 */
770
771 static avl_node *
avl_get_index_by_key(avl_tree * tree,void * key,unsigned long * index)772 avl_get_index_by_key (avl_tree * tree,
773 void * key,
774 unsigned long * index)
775 {
776 avl_node * x = tree->root->right;
777 unsigned long m;
778
779 if (!x) {
780 return NULL;
781 }
782 m = AVL_GET_RANK (x);
783
784 while (1) {
785 int compare_result = tree->compare_fun (tree->compare_arg, key, x->key);
786 if (compare_result < 0) {
787 if (x->left) {
788 m = m - AVL_GET_RANK(x);
789 x = x->left;
790 m = m + AVL_GET_RANK(x);
791 } else {
792 *index = m - 2;
793 return NULL;
794 }
795 } else if (compare_result > 0) {
796 if (x->right) {
797 x = x->right;
798 m = m + AVL_GET_RANK(x);
799 } else {
800 *index = m - 1;
801 return NULL;
802 }
803 } else {
804 *index = m - 1;
805 return x;
806 }
807 }
808 }
809
810 /* return the (low index, high index) pair that spans the given key */
811
812 int
avl_get_span_by_key(avl_tree * tree,void * key,unsigned long * low,unsigned long * high)813 avl_get_span_by_key (avl_tree * tree,
814 void * key,
815 unsigned long * low,
816 unsigned long * high)
817 {
818 unsigned long m, i, j;
819 avl_node * node;
820
821 node = avl_get_index_by_key (tree, key, &m);
822
823 /* did we find an exact match?
824 * if so, we have to search left and right
825 * to find the span, since we know nothing about
826 * the arrangement of like keys.
827 */
828 if (node) {
829 avl_node * left, * right;
830 /* search left */
831 left = avl_get_prev (node);
832 i = m;
833 while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, key, left->key) == 0)) {
834 left = avl_get_prev (left);
835 i = i - 1;
836 }
837 /* search right */
838 right = avl_get_next (node);
839 j = m;
840 while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, key, right->key) == 0)) {
841 right = avl_get_next (right);
842 j = j + 1;
843 }
844 *low = i;
845 *high = j + 1;
846 return 0;
847 } else {
848 *low = *high = m;
849 }
850 return 0;
851 }
852
853 /* return the (low index, high index) pair that spans the given key */
854
855 int
avl_get_span_by_two_keys(avl_tree * tree,void * low_key,void * high_key,unsigned long * low,unsigned long * high)856 avl_get_span_by_two_keys (avl_tree * tree,
857 void * low_key,
858 void * high_key,
859 unsigned long * low,
860 unsigned long * high)
861 {
862 unsigned long i, j;
863 avl_node * low_node, * high_node;
864 int order;
865
866 /* we may need to swap them */
867 order = tree->compare_fun (tree->compare_arg, low_key, high_key);
868 if (order > 0) {
869 void * temp = low_key;
870 low_key = high_key;
871 high_key = temp;
872 }
873
874 low_node = avl_get_index_by_key (tree, low_key, &i);
875 high_node = avl_get_index_by_key (tree, high_key, &j);
876
877 if (low_node) {
878 avl_node * left;
879 /* search left */
880 left = avl_get_prev (low_node);
881 while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, low_key, left->key) == 0)) {
882 left = avl_get_prev (left);
883 i = i - 1;
884 }
885 } else {
886 i = i + 1;
887 }
888 if (high_node) {
889 avl_node * right;
890 /* search right */
891 right = avl_get_next (high_node);
892 while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, high_key, right->key) == 0)) {
893 right = avl_get_next (right);
894 j = j + 1;
895 }
896 } else {
897 j = j + 1;
898 }
899
900 *low = i;
901 *high = j;
902 return 0;
903 }
904
905
906 int
avl_get_item_by_key_most(avl_tree * tree,void * key,void ** value_address)907 avl_get_item_by_key_most (avl_tree * tree,
908 void * key,
909 void **value_address)
910 {
911 avl_node * x = tree->root->right;
912 *value_address = NULL;
913
914 if (!x) {
915 return -1;
916 }
917 while (1) {
918 int compare_result = tree->compare_fun (tree->compare_arg, key, x->key);
919
920 if (compare_result == 0) {
921 *value_address = x->key;
922 return 0;
923 } else if (compare_result < 0) {
924 /* the given key is less than the current key */
925 if (x->left) {
926 x = x->left;
927 } else {
928 if (*value_address)
929 return 0;
930 else
931 return -1;
932 }
933 } else {
934 /* the given key is more than the current key */
935 /* save this value, it might end up being the right one! */
936 *value_address = x->key;
937 if (x->right) {
938 /* there is a bigger entry */
939 x = x->right;
940 } else {
941 if (*value_address)
942 return 0;
943 else
944 return -1;
945 }
946 }
947 }
948 }
949
950 int
avl_get_item_by_key_least(avl_tree * tree,void * key,void ** value_address)951 avl_get_item_by_key_least (avl_tree * tree,
952 void * key,
953 void **value_address)
954 {
955 avl_node * x = tree->root->right;
956 *value_address = NULL;
957
958 if (!x) {
959 return -1;
960 }
961 while (1) {
962 int compare_result = tree->compare_fun (tree->compare_arg, key, x->key);
963 if (compare_result == 0) {
964 *value_address = x->key;
965 return 0; /* exact match */
966 } else if (compare_result < 0) {
967 /* the given key is less than the current key */
968 /* save this value, it might end up being the right one! */
969 *value_address = x->key;
970 if (x->left) {
971 x = x->left;
972 } else {
973 if (*value_address) /* we have found a valid entry */
974 return 0;
975 else
976 return -1;
977 }
978 } else {
979 if (x->right) {
980 /* there is a bigger entry */
981 x = x->right;
982 } else {
983 if (*value_address) /* we have found a valid entry */
984 return 0;
985 else
986 return -1;
987 }
988 }
989 }
990 }
991
992 #define AVL_MAX(X, Y) ((X) > (Y) ? (X) : (Y))
993
994 static long
avl_verify_balance(avl_node * node)995 avl_verify_balance (avl_node * node)
996 {
997 if (!node) {
998 return 0;
999 } else {
1000 long lh = avl_verify_balance (node->left);
1001 long rh = avl_verify_balance (node->right);
1002 if ((rh - lh) != AVL_GET_BALANCE(node)) {
1003 return 0;
1004 }
1005 if (((lh - rh) > 1) || ((lh - rh) < -1)) {
1006 return 0;
1007 }
1008 return (1 + AVL_MAX (lh, rh));
1009 }
1010 }
1011
1012 static void
avl_verify_parent(avl_node * node,avl_node * parent)1013 avl_verify_parent (avl_node * node, avl_node * parent)
1014 {
1015 if (node->parent != parent) {
1016 return;
1017 }
1018 if (node->left) {
1019 avl_verify_parent (node->left, node);
1020 }
1021 if (node->right) {
1022 avl_verify_parent (node->right, node);
1023 }
1024 }
1025
1026 static long
avl_verify_rank(avl_node * node)1027 avl_verify_rank (avl_node * node)
1028 {
1029 if (!node) {
1030 return 0;
1031 } else {
1032 unsigned long num_left=0, num_right=0;
1033 if (node->left) {
1034 num_left = avl_verify_rank (node->left);
1035 }
1036 if (node->right) {
1037 num_right = avl_verify_rank (node->right);
1038 }
1039 if (AVL_GET_RANK (node) != num_left + 1) {
1040 fprintf (stderr, "invalid rank at node %ld\n", (long) node->key);
1041 exit (1);
1042 }
1043 return (num_left + num_right + 1);
1044 }
1045 }
1046
1047 /* sanity-check the tree */
1048
1049 int
avl_verify(avl_tree * tree)1050 avl_verify (avl_tree * tree)
1051 {
1052 if (tree->length) {
1053 avl_verify_balance (tree->root->right);
1054 avl_verify_parent (tree->root->right, tree->root);
1055 avl_verify_rank (tree->root->right);
1056 }
1057 return (0);
1058 }
1059
1060 /*
1061 * These structures are accumulated on the stack during print_tree
1062 * and are used to keep track of the width and direction of each
1063 * branch in the history of a particular line <node>.
1064 */
1065
1066 typedef struct _link_node {
1067 struct _link_node * parent;
1068 char direction;
1069 int width;
1070 } link_node;
1071
1072 static char balance_chars[3] = {'\\', '-', '/'};
1073
1074 static int
default_key_printer(char * buffer,void * key)1075 default_key_printer (char * buffer, void * key)
1076 {
1077 return snprintf (buffer, AVL_KEY_PRINTER_BUFLEN, "%p", key);
1078 }
1079
1080 /*
1081 * When traveling the family tree, a change in direction
1082 * indicates when to print a connector. This is kinda crazy,
1083 * we use the stack to build a linked list, and then travel
1084 * it backwards using recursion.
1085 */
1086
1087 static void
print_connectors(link_node * link)1088 print_connectors (link_node * link)
1089 {
1090 if (link->parent) {
1091 print_connectors (link->parent);
1092 }
1093 if (link->parent && (link->parent->direction != link->direction) && (link->parent->parent)) {
1094 int i;
1095 fprintf (stdout, "|");
1096 for (i=0; i < (link->width - 1); i++) {
1097 fprintf (stdout, " ");
1098 }
1099 } else {
1100 int i;
1101 for (i=0; i < (link->width); i++) {
1102 fprintf (stdout, " ");
1103 }
1104 }
1105 }
1106
1107 /*
1108 * The <key_printer> function writes a representation of the
1109 * key into <buffer> (which is conveniently fixed in size to add
1110 * the spice of danger). It should return the size of the
1111 * representation.
1112 */
1113
1114 static void
print_node(avl_key_printer_fun_type key_printer,avl_node * node,link_node * link)1115 print_node (avl_key_printer_fun_type key_printer,
1116 avl_node * node,
1117 link_node * link)
1118 {
1119 char buffer[AVL_KEY_PRINTER_BUFLEN];
1120 unsigned int width;
1121 width = key_printer (buffer, node->key);
1122
1123 if (node->right) {
1124 link_node here;
1125 here.parent = link;
1126 here.direction = 1;
1127 here.width = width + 11;
1128 print_node (key_printer, node->right, &here);
1129 }
1130 print_connectors (link);
1131 fprintf (stdout, "+-[%c %s %03d]",
1132 balance_chars[AVL_GET_BALANCE(node)+1],
1133 buffer,
1134 (int)AVL_GET_RANK(node));
1135 if (node->left || node->right) {
1136 fprintf (stdout, "-|\n");
1137 } else {
1138 fprintf (stdout, "\n");
1139 }
1140 if (node->left) {
1141 link_node here;
1142 here.parent = link;
1143 here.direction = -1;
1144 here.width = width + 11;
1145 print_node (key_printer, node->left, &here);
1146 }
1147 }
1148
1149 void
avl_print_tree(avl_tree * tree,avl_key_printer_fun_type key_printer)1150 avl_print_tree (avl_tree * tree, avl_key_printer_fun_type key_printer)
1151 {
1152 link_node top = {NULL, 0, 0};
1153 if (!key_printer) {
1154 key_printer = default_key_printer;
1155 }
1156 if (tree->length) {
1157 print_node (key_printer, tree->root->right, &top);
1158 } else {
1159 fprintf (stdout, "<empty tree>\n");
1160 }
1161 }
1162
1163
avl_tree_rlock(avl_tree * tree)1164 void avl_tree_rlock(avl_tree *tree)
1165 {
1166 thread_rwlock_rlock(&tree->rwlock);
1167 }
1168
avl_tree_wlock(avl_tree * tree)1169 void avl_tree_wlock(avl_tree *tree)
1170 {
1171 thread_rwlock_wlock(&tree->rwlock);
1172 }
1173
avl_tree_unlock(avl_tree * tree)1174 void avl_tree_unlock(avl_tree *tree)
1175 {
1176 thread_rwlock_unlock(&tree->rwlock);
1177 }
1178
1179 #ifdef HAVE_AVL_NODE_LOCK
avl_node_rlock(avl_node * node)1180 void avl_node_rlock(avl_node *node)
1181 {
1182 thread_rwlock_rlock(&node->rwlock);
1183 }
1184
avl_node_wlock(avl_node * node)1185 void avl_node_wlock(avl_node *node)
1186 {
1187 thread_rwlock_wlock(&node->rwlock);
1188 }
1189
avl_node_unlock(avl_node * node)1190 void avl_node_unlock(avl_node *node)
1191 {
1192 thread_rwlock_unlock(&node->rwlock);
1193 }
1194 #endif
1195