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