1 
2 /* pyavl -- File "avl.c" */
3 
4 /* AVL trees with RANK field and parent pointers */
5 
6 #include "avl.h"
7 
8 #ifdef AVL_SHOW_ERROR_ON
9 #define AVL_SHOW_ERROR(fmt,arg)	fprintf(stderr, "! avl.c: " fmt, arg)
10 #else
11 #define AVL_SHOW_ERROR(fmt,arg) (void) (fmt), (void) (arg)
12 #endif
13 
14 const void *
avl_default_item_copy(const void * item)15 avl_default_item_copy (const void *item)
16 {
17   return (const void *) item;
18 }
19 
20 void *
avl_default_item_dispose(void * item)21 avl_default_item_dispose (void *item)
22 {
23   (void)item; /* for -Wall */
24   return (void *) NULL;
25 }
26 
27 #ifndef MPW_C
28 typedef uint32_t rbal_t;		/* integral type to encode rank and skew bits */
29 #else
30 typedef UInt32 rbal_t;
31 #endif
32 
33 /*
34  * avl_node structure
35  */
36 
37 typedef struct avl_node
38 {
39   struct avl_node *sub[2];
40   struct avl_node *up;
41   rbal_t rbal;
42   void *item;
43 }
44 avl_node;
45 
46 /*
47  * avl_tree structure
48  */
49 
50 struct avl_tree_
51 {
52   avl_node *root;
53   avl_size_t count;				/* how many nodes in tree rooted at [root] */
54   avl_compare_func compare;		/* compare items */
55   avl_item_copy_func copy;
56   avl_item_dispose_func dispose;
57   avl_alloc_func alloc;			/* to allocate memory (same signature as malloc) */
58   avl_dealloc_func dealloc;		/* to deallocate memory (same signature as free) */
59   void *param;
60 };
61 
62 #define Item_Compare(cmp, tree, item1, item2)\
63             (*cmp)(tree->param, item1, item2)
64 
65 /* patches (November 2004) */
66 
67 #if AVL_CMPERR != 0
68 #define CMPERR_CHECK__FIND(param)      if (avl_errcmp_occurred(param))  return NULL
69 #define CMPERR_CHECK__INDEX(param)     if (avl_errcmp_occurred(param))  return 0
70 #define CMPERR_CHECK__SPAN(param)      if (avl_errcmp_occurred(param))  return -2
71 #define CMPERR_CHECK__INS(param)       if (avl_errcmp_occurred(param))  return -2
72 #define CMPERR_CHECK__DEL(param)		(avl_errcmp_occurred(param) ? -2 : 0)
73 #define CMPERR_CHECK__SPLIT(param)     if (avl_errcmp_occurred(param))  return -2
74 #define CMPERR_CHECK__VERIFY(param)    && (!avl_errcmp_occurred(param))
75 #else
76 #define CMPERR_CHECK__FIND(param)      (void) param
77 #define CMPERR_CHECK__INDEX(param)     (void) param
78 #define CMPERR_CHECK__SPAN(param)      (void) param
79 #define CMPERR_CHECK__INS(param)       (void) param
80 #define CMPERR_CHECK__DEL(param)		0
81 #define CMPERR_CHECK__SPLIT(param)     (void) param
82 #define CMPERR_CHECK__VERIFY(param)	/* nothing */
83 #endif
84 
85 #define sub_left(a)     (a)->sub[0]
86 #define sub_right(a)    (a)->sub[1]
87 #define get_item(a)     (a)->item
88 
89 /* RANK(a) = size of left subtree + 1 */
90 
91 #define rbal(a)\
92  (a)->rbal
93 #define rzero(a)\
94  ( rbal(a) & ~3 )
95 #define get_bal(a)\
96  ( rbal(a) & 3 )
97 #define is_lskew(a)\
98  ( rbal(a) & 1 )
99 #define is_rskew(a)\
100  ( rbal(a)>>1 & 1)
101 #define set_lskew(a)\
102   ( rbal(a) |= 1 )
103 #define set_rskew(a)\
104   ( rbal(a) |= 2 )
105 #define set_skew(a,d)\
106   ( rbal(a) |= (1 << d) )
107 #define unset_lskew(a)\
108   ( rbal(a) &= ~1 )
109 #define unset_rskew(a)\
110   ( rbal(a) &= ~2 )
111 #define get_rank(a)\
112  ( rbal(a) >> 2 )
113 #define set_rank(a,r)\
114  ( rbal(a) = (r<<2 | get_bal(a))  )
115 #define incr_rank(a,r)\
116  ( rbal(a) += r<<2 )
117 #define decr_rank(a,r)\
118  ( rbal(a) -= r<<2 )
119 
120 #define AVL_MIN_DEPTH   0
121 
122 /*** Node management ***/
123 
124 #define DETACH_FUNC     1		/* nonzero to use function not macro */
125 
126 /* helper structure */
127 typedef enum
128 {
129   OP_BACKUP, OP_DETACH, OP_FREE
130 }
131 whichop_t;
132 struct ptr_handler
133 {
134   whichop_t whichop;
135   void *ptr;
136 };
137 
138 #define ini_ptr_handler(h,op)   struct ptr_handler h = { OP_##op, NULL }
139 #define clear_node(a)                                           \
140     sub_left(a) = NULL;                                         \
141     sub_right(a) = NULL;                                        \
142     (a)->up = NULL;                                             \
143     rbal(a) = 4u
144 
145 /* Called by 'avl_ins', 'avl_dup', 'node_slice' */
146 static avl_node *
new_node(void * item,avl_node * up,avl_tree t)147 new_node (void *item, avl_node * up, avl_tree t)
148 {
149   avl_node *a = (*t->alloc) (sizeof (avl_node));
150 
151   if (a != NULL)
152 	{
153 	  sub_left (a) = NULL;
154 	  sub_right (a) = NULL;
155 	  a->up = up;
156 	  a->rbal = 4u;
157 	  a->item = (*t->copy) (item);
158 	}
159   return a;
160 }
161 
162 static void
free_node(avl_node * a,avl_tree t)163 free_node (avl_node * a, avl_tree t)
164 {
165   a->item = (*t->dispose) (a->item);
166   (*t->dealloc) (a);
167 }
168 
169 #define backup_item(backup,item,t)  if (backup == NULL) ; else *backup = (*t->copy)(item)
170 
171 #if ! DETACH_FUNC
172 
173 /* macro to detach node [a] from tree [t] */
174 #define detach_node(a,t,h)  { struct ptr_handler *ch = h;       \
175     clear_node(a);                                              \
176     do {                                                        \
177         if (ch == NULL) ;                                       \
178         else if (ch->whichop == OP_DETACH){                     \
179             ch->ptr = a;                                        \
180             break;                                              \
181         } else if (ch->whichop == OP_BACKUP){                   \
182             ch->ptr = (*t->copy)(a->item);                      \
183         }                                                       \
184         free_node(a, t);                                        \
185     } while (0);}                                               \
186     t->count--
187 #else
188 
189 /* function to detach node [a] from tree [t] */
190 static void
detach_node(avl_node * a,avl_tree t,struct ptr_handler * h)191 detach_node (avl_node * a, avl_tree t, struct ptr_handler *h)
192 {
193   clear_node (a);
194   do
195 	{
196 	  if (h == NULL);
197 	  else if (h->whichop == OP_DETACH)
198 		{
199 		  h->ptr = a;
200 		  break;
201 		}
202 	  else if (h->whichop == OP_BACKUP)
203 		{
204 		  h->ptr = (*t->copy) (a->item);
205 		}
206 	  free_node (a, t);
207 	}
208   while (0);
209   t->count--;
210 }
211 #endif /* DETACH_FUNC */
212 
213 /*** Tree methods ***/
214 
215 avl_tree
avl_create(avl_compare_func compare,avl_item_copy_func copy,avl_item_dispose_func dispose,avl_alloc_func alloc,avl_dealloc_func dealloc,void * param)216 avl_create (avl_compare_func compare, avl_item_copy_func copy,
217 			avl_item_dispose_func dispose, avl_alloc_func alloc,
218 			avl_dealloc_func dealloc, void *param)
219 {
220   avl_tree t = (*alloc) (sizeof (struct avl_tree_));
221 
222   if (t == NULL)
223 	AVL_SHOW_ERROR ("%s\n", "couldn't create new handle in avl_create()");
224   else
225 	{
226 	  t->root = NULL;
227 	  t->count = 0;
228 	  t->param = param;
229 	  t->compare = compare;
230 	  t->copy = copy;
231 	  t->dispose = dispose;
232 	  t->alloc = alloc;
233 	  t->dealloc = dealloc;
234 	}
235   return t;
236 }
237 
238 /* Empty the tree, using rotations */
239 
240 static void
node_empty(avl_tree t)241 node_empty (avl_tree t)
242 {
243   avl_node *a, *p;
244 
245   for (a = t->root; a != NULL;)
246 	{
247 	  p = a;
248 	  if (sub_right (a) == NULL)
249 		a = sub_left (a);
250 	  else
251 		{
252 		  while (sub_left (a) != NULL)
253 			{
254 			  /* rotR(a) */
255 			  a = sub_left (a);
256 			  sub_left (p) = sub_right (a);
257 			  sub_right (a) = p;
258 			  p = a;
259 			}
260 		  a = sub_right (p);
261 		}
262 	  free_node (p, t);
263 	  t->count--;
264 	}
265   t->root = NULL;
266 }
267 
268 /* [t] is an existing tree handle */
269 
270 /* this function invokes node_empty() */
271 
272 void
avl_reset(avl_tree t,avl_compare_func compare,avl_item_copy_func copy,avl_item_dispose_func dispose,avl_alloc_func alloc,avl_dealloc_func dealloc)273 avl_reset (avl_tree t,
274 		   avl_compare_func compare,
275 		   avl_item_copy_func copy,
276 		   avl_item_dispose_func dispose,
277 		   avl_alloc_func alloc, avl_dealloc_func dealloc)
278 {
279   if (t == NULL)
280 	return;
281   node_empty (t);
282   t->compare = compare;
283   t->copy = copy;
284   t->dispose = dispose;
285   t->alloc = alloc;
286   t->dealloc = dealloc;
287 }
288 
289 void
avl_empty(avl_tree t)290 avl_empty (avl_tree t)
291 {
292   if (t != NULL)
293 	node_empty (t);
294 }
295 
296 /* Destroy nodes, free handle */
297 
298 void
avl_destroy(avl_tree t)299 avl_destroy (avl_tree t)
300 {
301 #ifndef AVL_NULLCHECKS
302   if (t == NULL)
303 	return;
304 #endif
305   node_empty (t);
306   (*t->dealloc) (t);
307 }
308 
309 avl_tree
avl_dup(avl_tree t,void * param)310 avl_dup (avl_tree t, void *param)
311 {
312 #ifndef AVL_NULLCHECKS
313   if (t == NULL)
314 	return NULL;
315 #endif
316   {
317 	avl_tree tt = avl_create (
318 							   /*(avl_compare_func) */ t->compare,
319 							   /*(avl_item_copy_func) */ t->copy,
320 							   /*(avl_item_dispose_func) */ t->dispose,
321 							   /*(avl_alloc_func) */ t->alloc,
322 							   /*(avl_dealloc_func) */ t->dealloc,
323 							   param);
324 
325 	if (tt == NULL)
326 	  {
327 		AVL_SHOW_ERROR ("%s\n", "couldn't create new handle in avl_dup()");
328 		return NULL;
329 	  }
330 
331 	tt->count = t->count;
332 
333 	if (t->root == NULL)
334 	  return tt;
335 
336 	{
337 	  avl_node *a, *c, *s;
338 
339 	  a = t->root;
340 	  tt->root = c = new_node (get_item (a), NULL, t);
341 	  if (c == NULL)
342 		goto abort;
343 
344 	  sub_right (c) = NULL;		/*!!! */
345 	  rbal (c) = rbal (a);
346 
347 	  while (1)
348 		{
349 		  while (sub_left (a) != NULL)
350 			{
351 			  a = sub_left (a);
352 			  sub_left (c) = s = new_node (get_item (a), NULL, t);
353 			  if (s == NULL)
354 				goto recover;
355 			  s->up = c;
356 			  sub_right (s) = c;
357 			  c = s;
358 			  rbal (c) = rbal (a);
359 			}
360 
361 		  sub_left (c) = NULL;
362 
363 		  while (sub_right (a) == NULL)
364 			{
365 			  s = sub_right (c);
366 			  sub_right (c) = NULL;
367 			  c = s;
368 			  /* Find successor of [a] in original tree */
369 			  do
370 				{
371 				  s = a;
372 				  a = s->up;
373 				  if (a == NULL)
374 					return tt;
375 				}
376 			  while (s != sub_left (a));
377 			}
378 
379 		  a = sub_right (a);
380 		  s = new_node (get_item (a), NULL, t);
381 		  if (s == NULL)
382 			goto recover;
383 		  sub_right (s) = sub_right (c);
384 		  sub_right (c) = s;
385 		  s->up = c;
386 		  c = s;
387 		  rbal (c) = rbal (a);
388 		}
389 	  /* recovery code     */
390 	recover:
391 	  while (1)
392 		{
393 		  s = sub_right (c);
394 		  sub_right (c) = NULL;
395 		  if (s == NULL)
396 			break;
397 		  c = s;
398 		}
399 	  node_empty (tt);
400 
401 	abort:
402 	  (*t->dealloc) (tt);
403 	  AVL_SHOW_ERROR ("%s\n", "couldn't allocate node in avl_dup()");
404 	  return NULL;
405 	}
406   }
407 }
408 
409 avl_bool_t
avl_isempty(avl_tree t)410 avl_isempty (avl_tree t)
411 {
412 #ifndef AVL_NULLCHECKS
413   return t == NULL || t->root == NULL;
414 #else
415   return t->root == NULL;
416 #endif
417 }
418 
419 avl_size_t
avl_size(avl_tree t)420 avl_size (avl_tree t)
421 {
422 #ifndef AVL_NULLCHECKS
423   return t == NULL ? 0 : t->count;
424 #else
425   return t->count;
426 #endif
427 }
428 
429 static int
depth(avl_node * a)430 depth (avl_node * a)
431 {
432   int h = AVL_MIN_DEPTH;
433 
434   for (; a != NULL; ++h)
435 	a = a->sub[is_rskew (a)];
436   return h;
437 }
438 
439 static avl_node *
node_first(avl_node * a)440 node_first (avl_node * a)
441 {
442   while (sub_left (a) != NULL)
443 	a = sub_left (a);
444   return a;
445 }
446 
447 static avl_node *
node_last(avl_node * a)448 node_last (avl_node * a)
449 {
450   while (sub_right (a) != NULL)
451 	a = sub_right (a);
452   return a;
453 }
454 
455 /* [a] : non-null */
456 
457 static avl_node *
node_next(avl_node * a)458 node_next (avl_node * a)
459 {
460   if (sub_right (a) != NULL)
461 	return node_first (sub_right (a));
462   {
463 	avl_node *p;
464 
465 	do
466 	  {
467 		p = a;
468 		a = p->up;
469 	  }
470 	while (a != NULL && sub_right (a) == p);
471 	return a;
472   }
473 }
474 
475 /* [a] : non-null */
476 
477 static avl_node *
node_prev(avl_node * a)478 node_prev (avl_node * a)
479 {
480   if (sub_left (a) != NULL)
481 	return node_last (sub_left (a));
482   {
483 	avl_node *p;
484 
485 	do
486 	  {
487 		p = a;
488 		a = p->up;
489 	  }
490 	while (a != NULL && sub_left (a) == p);
491 	return a;
492   }
493 }
494 
495 static avl_node *
node_find(const void * item,avl_tree t)496 node_find (const void *item, avl_tree t)
497 {
498   avl_node *a = t->root;
499   avl_compare_func cmp = t->compare;
500   int c;
501 
502   while (a != NULL)
503 	{
504 	  c = Item_Compare (cmp, t, item, get_item (a));
505 	  CMPERR_CHECK__FIND (t->param);
506 	  if (c < 0)
507 		a = a->sub[0];
508 	  else if (c)
509 		a = a->sub[1];
510 	  else
511 		break;
512 	}
513   return a;
514 }
515 
516 #if 0==1
517 static avl_node **
518 avl_search (const void *item, avl_tree t, int *dir)
519 {
520   if (t->root == NULL)
521 	return &t->root;
522   {
523 	avl_node **r = &t->root;
524 	avl_node *a = *r;
525 	avl_compare_func cmp = t->compare;
526 	int c;
527 
528 	while (1)
529 	  {
530 		c = Item_Compare (cmp, t, item, get_item (a));
531 		if (!c)
532 		  break;
533 		r = &a->sub[c = c > 0];
534 		if (*r == NULL)
535 		  {
536 			*dir = c;
537 			break;
538 		  }
539 		a = *r;
540 	  }
541 
542 	return r;
543   }
544 }
545 #endif
546 
547 static avl_size_t
get_index(avl_node * a)548 get_index (avl_node * a)
549 {
550   avl_size_t n = get_rank (a);
551   avl_node *p;
552 
553   while ((p = a->up) != NULL)
554 	{
555 	  if (a != sub_left (p))
556 		n += get_rank (p);
557 	  a = p;
558 	}
559   return n;
560 }
561 
562 /* Find item by index */
563 
564 static avl_node *
node_find_index(avl_size_t idx,avl_tree t)565 node_find_index (avl_size_t idx, avl_tree t)
566 {
567   avl_node *a = t->root;
568   int c;
569 
570   if (idx == 0 || idx > t->count)
571 	return NULL;
572   if (idx == 1)
573 	return node_first (a);
574   if (idx == t->count)
575 	return node_last (a);
576 
577   while ((c = (int)(idx - get_rank (a))) != 0)
578 	{
579 	  if (c < 0)
580 		a = sub_left (a);
581 	  else
582 		{
583 		    idx = (avl_size_t)c;
584 		  a = sub_right (a);
585 		}
586 	}
587 
588   return a;
589 }
590 
591 /* Rebalance starting from node [a] where a->sub[d_]
592  * is deeper post-insertion
593  */
594 
595 static avl_code_t
rebalance_ins(avl_node * a,int dir,avl_tree t)596 rebalance_ins (avl_node * a, int dir, avl_tree t)
597 {
598   if (a != NULL)
599 	{
600 	  avl_node *p;
601 
602 	  while (1)
603 		{
604 		    incr_rank (a, (rbal_t)(!dir));
605 		  if (get_bal (a))
606 			break;
607 		  set_skew (a, dir);
608 		  p = a->up;
609 		  if (p == NULL)
610 			return 2;
611 		  dir = a != sub_left (p);
612 		  a = p;
613 		}
614 
615 	  /* Now bal(a) == -1 or +1 */
616 	  /* Rotate if need be */
617 
618 	  if (0 == dir)
619 		{
620 		  if (is_rskew (a))
621 			unset_rskew (a);
622 
623 		  else
624 			{
625 			  avl_node *u = a->up;
626 			  avl_node **r =
627 				u != NULL ? &u->sub[a != sub_left (u)] : &t->root;
628 
629 			  p = a;
630 
631 			  if (is_lskew (sub_left (p)))
632 				{
633 				  /* rotR(p) */
634 				  a = sub_left (p);
635 				  sub_left (p) = sub_right (a);
636 				  if (sub_right (a) != NULL)
637 					sub_right (a)->up = p;
638 				  sub_right (a) = p;
639 				  unset_lskew (p);
640 				  rbal (p) -= rzero (a);
641 				}
642 			  else
643 				{
644 				  /* rotLR(p) */
645 				  a = sub_right (sub_left (p));
646 				  sub_right (sub_left (p)) = sub_left (a);
647 				  if (sub_left (a) != NULL)
648 					sub_left (a)->up = sub_left (p);
649 				  sub_left (p)->up = a;
650 				  sub_left (a) = sub_left (p);
651 				  sub_left (p) = sub_right (a);
652 				  if (sub_right (a) != NULL)
653 					sub_right (a)->up = p;
654 				  sub_right (a) = p;
655 				  switch (get_bal (a))
656 					{
657 					case 0:	/* not skewed */
658 					  unset_lskew (p);
659 					  unset_rskew (sub_left (a));
660 					  break;
661 					case 1:	/* left skew */
662 					  unset_lskew (p);
663 					  set_rskew (p);
664 					  unset_rskew (sub_left (a));
665 					  break;
666 					case 2:	/* right skew */
667 					  unset_lskew (p);
668 					  unset_rskew (sub_left (a));
669 					  set_lskew (sub_left (a));
670 					}			/* switch */
671 				  rbal (a) += rzero (sub_left (a));
672 				  rbal (p) -= rzero (a);
673 				}				/* which rot */
674 			  rbal (a) &= ~3;
675 			  a->up = u;
676 			  p->up = a;
677 			  *r = a;
678 			}					/* rot or no rot ? */
679 		}
680 	  else
681 		{
682 		  /* direction == 1 */
683 
684 		  if (is_lskew (a))
685 			unset_lskew (a);
686 
687 		  else
688 			{
689 			  avl_node *u = a->up;
690 			  avl_node **r =
691 				u != NULL ? &u->sub[a != sub_left (u)] : &t->root;
692 
693 			  p = a;
694 			  if (is_rskew (sub_right (p)))
695 				{
696 				  /* rotL(p) */
697 				  a = sub_right (p);
698 				  sub_right (p) = sub_left (a);
699 				  if (sub_left (a) != NULL)
700 					sub_left (a)->up = p;
701 				  sub_left (a) = p;
702 				  unset_rskew (p);
703 				  rbal (a) += rzero (p);
704 				}
705 			  else
706 				{
707 				  /* rotRL(p) */
708 				  a = sub_left (sub_right (p));
709 				  sub_left (sub_right (p)) = sub_right (a);
710 				  if (sub_right (a) != NULL)
711 					sub_right (a)->up = sub_right (p);
712 				  sub_right (p)->up = a;
713 				  sub_right (a) = sub_right (p);
714 				  sub_right (p) = sub_left (a);
715 				  if (sub_left (a) != NULL)
716 					sub_left (a)->up = p;
717 				  sub_left (a) = p;
718 				  switch (get_bal (a))
719 					{
720 					case 0:	/* not skewed */
721 					  unset_rskew (p);
722 					  unset_lskew (sub_right (a));
723 					  break;
724 					case 1:	/* left skew */
725 					  unset_rskew (p);
726 					  unset_lskew (sub_right (a));
727 					  set_rskew (sub_right (a));
728 					  break;
729 					case 2:	/* right skew */
730 					  unset_rskew (p);
731 					  set_lskew (p);
732 					  unset_lskew (sub_right (a));
733 					}			/* switch */
734 				  rbal (sub_right (a)) -= rzero (a);
735 				  rbal (a) += rzero (p);
736 
737 				}				/* which rot */
738 
739 			  rbal (a) &= ~3;
740 			  a->up = u;
741 			  p->up = a;
742 			  *r = a;
743 			}					/* rot or not rot ? */
744 		}						/* if 0==dir */
745 
746 	  /* The tree rooted at 'a' is now valid */
747 	  /* Finish adjusting ranks */
748 
749 	  while ((p = a->up) != NULL)
750 		{
751 		  incr_rank (p, (rbal_t)(a == sub_left (p)));
752 		  a = p;
753 		}
754 
755 	  return 1;
756 
757 	}							/* if a != 0 */
758   return 2;
759 }
760 
761 /* detach [p] : non-null */
762 
763 /* only the linkage is tweaked */
764 
765 static avl_code_t
rebalance_del(avl_node * p,avl_tree t,void ** backup)766 rebalance_del (avl_node * p, avl_tree t, void **backup)
767 {
768   avl_node **r, *a, *c;
769   rbal_t bal;
770   int dir = 0;
771 
772   a = p->up;
773   if (a == NULL)
774 	r = &t->root;
775   else
776 	r = &a->sub[dir = p != sub_left (a)];
777 
778   c = sub_right (p);
779   if (c == NULL && sub_left (p) == NULL)
780 	*r = NULL;
781   else if (c == NULL || sub_left (p) == NULL)
782 	{
783 	  *r = c != NULL ? c : sub_left (p);
784 	  (*r)->up = a;
785 	}
786   else
787 	{
788 	  if (sub_left (c) == NULL)
789 		{
790 		  a = c;
791 		  dir = 1;
792 		}
793 	  else
794 		{
795 		  do
796 			c = sub_left (c);
797 		  while (sub_left (c) != NULL);
798 		  a = c->up;
799 		  dir = 0;
800 		  sub_left (a) = sub_right (c);
801 		  if (sub_right (c) != NULL)
802 			sub_right (c)->up = a;
803 		  sub_right (c) = sub_right (p);
804 		  sub_right (c)->up = c;
805 		}
806 	  sub_left (c) = sub_left (p);
807 	  sub_left (c)->up = c;
808 	  c->up = p->up;
809 	  rbal (c) = rbal (p);
810 	  *r = c;
811 	}
812 
813   backup_item (backup, p->item, t);
814   detach_node (p, t, NULL);
815 
816   /* Start backtracking : subtree of [a] in direction [dir] is less deep */
817 
818   for (;; a = (*r)->up)
819 	{
820 	  if (a == NULL)
821 		return 2;
822 
823 	  decr_rank (a, (rbal_t)(!dir));
824 	  bal = get_bal (a);
825 
826 	  if (0 == dir)
827 		{
828 		  if (bal == 0)
829 			{
830 			  set_rskew (a);
831 			  break;
832 			}
833 		  if (a->up == NULL)
834 			r = &t->root;
835 		  else
836 			{
837 			  dir = a != sub_left (a->up);
838 			  r = &a->up->sub[dir];
839 			}
840 		  if (bal & 1)
841 			unset_lskew (a);
842 		  if (get_bal (a))
843 			{
844 			  p = a;
845 			  bal = get_bal (sub_right (p));
846 			  if (!(bal & 1))
847 				{
848 				  /* bal = 0 or +1 */
849 				  /* rotL(p) */
850 				  a = sub_right (p);
851 				  sub_right (p) = sub_left (a);
852 				  if (sub_left (a) != NULL)
853 					sub_left (a)->up = p;
854 				  sub_left (a) = p;
855 				  if (bal)
856 					{
857 					  unset_rskew (p);
858 					  unset_rskew (a);
859 					}
860 				  else
861 					set_lskew (a);
862 				  rbal (a) += rzero (p);
863 				}
864 			  else
865 				{
866 				  /* rotRL(p) */
867 				  a = sub_left (sub_right (p));
868 				  sub_left (sub_right (p)) = sub_right (a);
869 				  if (sub_right (a) != NULL)
870 					sub_right (a)->up = sub_right (p);
871 				  sub_right (p)->up = a;
872 				  sub_right (a) = sub_right (p);
873 				  sub_right (p) = sub_left (a);
874 				  if (sub_left (a) != NULL)
875 					sub_left (a)->up = p;
876 				  sub_left (a) = p;
877 				  switch (get_bal (a))
878 					{
879 					case 0:	/* not skewed */
880 					  unset_rskew (p);
881 					  unset_lskew (sub_right (a));
882 					  break;
883 					case 1:	/* left skew */
884 					  unset_rskew (p);
885 					  unset_lskew (sub_right (a));
886 					  set_rskew (sub_right (a));
887 					  break;
888 					case 2:	/* right skew */
889 					  unset_rskew (p);
890 					  set_lskew (p);
891 					  unset_lskew (sub_right (a));
892 					}			/* switch */
893 				  rbal (a) &= ~3;
894 				  rbal (sub_right (a)) -= rzero (a);
895 				  rbal (a) += rzero (p);
896 
897 				}				/* which rot */
898 
899 			  a->up = p->up;
900 			  p->up = a;
901 			  /* Done with rotation */
902 			  *r = a;
903 			  if (bal == 0)
904 				break;
905 			}					/* if getbal(a) */
906 		}
907 	  else
908 		{
909 		  /* dir == 1 */
910 
911 		  if (bal == 0)
912 			{
913 			  set_lskew (a);
914 			  break;
915 			}
916 		  if (a->up == NULL)
917 			r = &t->root;
918 		  else
919 			{
920 			  dir = a != sub_left (a->up);
921 			  r = &a->up->sub[dir];
922 			}
923 		  if (bal & 2)
924 			unset_rskew (a);
925 		  if (get_bal (a))
926 			{
927 			  p = a;
928 			  bal = get_bal (sub_left (p));
929 			  if (!(bal & 2))
930 				{
931 				  /* bal = 0 or -1 */
932 				  /* rotR(p) */
933 				  a = sub_left (p);
934 				  sub_left (p) = sub_right (a);
935 				  if (sub_right (a) != NULL)
936 					sub_right (a)->up = p;
937 				  sub_right (a) = p;
938 				  if (bal)
939 					{
940 					  unset_lskew (p);
941 					  unset_lskew (a);
942 					}
943 				  else
944 					set_rskew (a);
945 				  rbal (p) -= rzero (a);
946 				}
947 			  else
948 				{
949 				  /* rotLR(p) */
950 				  a = sub_right (sub_left (p));
951 				  sub_right (sub_left (p)) = sub_left (a);
952 				  if (sub_left (a) != NULL)
953 					sub_left (a)->up = sub_left (p);
954 				  sub_left (p)->up = a;
955 				  sub_left (a) = sub_left (p);
956 				  sub_left (p) = sub_right (a);
957 				  if (sub_right (a) != NULL)
958 					sub_right (a)->up = p;
959 				  sub_right (a) = p;
960 				  switch (get_bal (a))
961 					{
962 					case 0:	/* not skewed */
963 					  unset_lskew (p);
964 					  unset_rskew (sub_left (a));
965 					  break;
966 					case 1:	/* left skew */
967 					  unset_lskew (p);
968 					  set_rskew (p);
969 					  unset_rskew (sub_left (a));
970 					  break;
971 					case 2:	/* right skew */
972 					  unset_lskew (p);
973 					  unset_rskew (sub_left (a));
974 					  set_lskew (sub_left (a));
975 					}			/* switch */
976 				  rbal (a) &= ~3;
977 				  rbal (a) += rzero (sub_left (a));
978 				  rbal (p) -= rzero (a);
979 				}				/* which rot */
980 
981 			  a->up = p->up;
982 			  p->up = a;
983 			  /* Done with rotation */
984 			  *r = a;
985 			  if (bal == 0)
986 				break;
987 			}					/* if getbal(a) */
988 		}						/* if dir==0 else 1 */
989 	}							/* for */
990 
991   /* Finish adjusting ranks */
992   while ((p = a->up) != NULL)
993 	{
994           decr_rank (p, (rbal_t)(a == sub_left (p)));
995 	  a = p;
996 	}
997 
998   return 1;
999 }
1000 
1001 void *
avl_first(avl_tree t)1002 avl_first (avl_tree t)
1003 {
1004 #ifndef AVL_NULLCHECKS
1005   if (t == NULL || t->root == NULL)
1006 #else
1007   if (t->root == NULL)
1008 #endif
1009 	return NULL;
1010   return get_item (node_first (t->root));
1011 }
1012 
1013 void *
avl_last(avl_tree t)1014 avl_last (avl_tree t)
1015 {
1016 #ifndef AVL_NULLCHECKS
1017   if (t == NULL || t->root == NULL)
1018 #else
1019   if (t->root == NULL)
1020 #endif
1021 	return NULL;
1022   return get_item (node_last (t->root));
1023 }
1024 
1025 void *
avl_find(const void * item,avl_tree t)1026 avl_find (const void *item, avl_tree t)
1027 {
1028   avl_node *a;
1029 
1030 #ifndef AVL_NULLCHECKS
1031   if (t == NULL)
1032 	return NULL;
1033 #endif
1034   a = node_find (item, t);
1035   return a != NULL ? get_item (a) : NULL;
1036 }
1037 
1038 /*
1039  * Return smallest index i in [1:len] s.t. tree[i] matches [item],
1040  * or zero if not found
1041  */
1042 
1043 avl_size_t
avl_index(const void * item,avl_tree t)1044 avl_index (const void *item, avl_tree t)
1045 {
1046 #ifndef AVL_NULLCHECKS
1047   if (item == NULL || t == NULL || t->root == NULL)
1048 #else
1049   if (t->root == NULL)
1050 #endif
1051 	return 0;
1052 
1053   {
1054 	avl_compare_func cmp = t->compare;
1055 	avl_node *a, *p;
1056 	avl_size_t idx = 0, n = 0;
1057 	int c;
1058 
1059 	for (a = t->root;;)
1060 	  {
1061 		c = Item_Compare (cmp, t, item, get_item (a));
1062 		CMPERR_CHECK__INDEX (t->param);
1063 		if (!c)
1064 		  idx = n + get_rank (a);
1065 		else if (c > 0)
1066 		  n += get_rank (a);
1067 		p = a->sub[c > 0];
1068 		if (p == NULL)
1069 		  return idx;
1070 		a = p;
1071 	  }
1072   }
1073 }
1074 
1075 /* (lo,hi) where
1076  * lo smallest index s.t. t[lo] >= lo_item, or t->count+1 and
1077  * hi greatest index s.t. t[hi] <= hi_item, or 0
1078  */
1079 avl_code_t
avl_span(const void * lo_item,const void * hi_item,avl_tree t,avl_size_t * lo_idx,avl_size_t * hi_idx)1080 avl_span (const void *lo_item,
1081 		  const void *hi_item,
1082 		  avl_tree t, avl_size_t * lo_idx, avl_size_t * hi_idx)
1083 {
1084   *lo_idx = t->count + 1;
1085   *hi_idx = 0;
1086 
1087 #ifndef AVL_NULLCHECKS
1088   if (t == NULL || t->root == NULL)
1089 #else
1090   if (t->root == NULL)
1091 #endif
1092 	return -1;
1093 
1094   {
1095 	avl_compare_func cmp = t->compare;
1096 	avl_node *a;
1097 	avl_size_t n = 0;
1098 	int c;
1099 
1100 	c = Item_Compare (cmp, t, lo_item, hi_item) > 0;
1101 	CMPERR_CHECK__SPAN (t->param);
1102 	if (c > 0)
1103 	  {
1104 		const void *temp = lo_item;
1105 
1106 		lo_item = hi_item;
1107 		hi_item = temp;
1108 	  }
1109 
1110 	a = t->root;
1111 	do
1112 	  {
1113 		c = Item_Compare (cmp, t, lo_item, get_item (a));
1114 		CMPERR_CHECK__SPAN (t->param);
1115 		if (c > 0)
1116 		  {
1117 			n += get_rank (a);
1118 			a = sub_right (a);
1119 		  }
1120 		else
1121 		  {
1122 			*lo_idx = n + get_rank (a);
1123 			a = sub_left (a);
1124 		  }
1125 	  }
1126 	while (a);
1127 
1128 	a = t->root;
1129 	do
1130 	  {
1131 		c = Item_Compare (cmp, t, hi_item, get_item (a));
1132 		CMPERR_CHECK__SPAN (t->param);
1133 		if (c < 0)
1134 		  {
1135 			a = sub_left (a);
1136 		  }
1137 		else
1138 		  {
1139 			*hi_idx += get_rank (a);
1140 			a = sub_right (a);
1141 		  }
1142 	  }
1143 	while (a);
1144 	return 0;
1145   }
1146 }
1147 
1148 /*
1149  * Find the smallest item in tree [t] that is GEQ the passed item
1150  */
1151 
1152 void *
avl_find_atleast(const void * item,avl_tree t)1153 avl_find_atleast (const void *item, avl_tree t)
1154 {
1155 #ifndef AVL_NULLCHECKS
1156   if (t == NULL || t->root == NULL)
1157 #else
1158   if (t->root == NULL)
1159 #endif
1160 	return NULL;
1161   {
1162 	avl_compare_func cmp = t->compare;
1163 	avl_node *a = t->root;
1164 	void *p = NULL;
1165 	int c;
1166 
1167 	do
1168 	  {
1169 		c = Item_Compare (cmp, t, item, get_item (a));
1170 		CMPERR_CHECK__FIND (t->param);
1171 		if (c > 0)
1172 		  {
1173 			a = sub_right (a);
1174 		  }
1175 		else
1176 		  {
1177 			p = get_item (a);
1178 			a = sub_left (a);
1179 		  }
1180 	  }
1181 	while (a);
1182 	return p;
1183   }
1184 }
1185 
1186 /*
1187  * Find the greatest item in tree [t] that is LEQ the passed item
1188  */
1189 
1190 void *
avl_find_atmost(const void * item,avl_tree t)1191 avl_find_atmost (const void *item, avl_tree t)
1192 {
1193 #ifndef AVL_NULLCHECKS
1194   if (t == NULL || t->root == NULL)
1195 #else
1196   if (t->root == NULL)
1197 #endif
1198 	return NULL;
1199   {
1200 	avl_compare_func cmp = t->compare;
1201 	avl_node *a = t->root;
1202 	void *p = NULL;
1203 	int c;
1204 
1205 	do
1206 	  {
1207 		c = Item_Compare (cmp, t, item, get_item (a));
1208 		CMPERR_CHECK__FIND (t->param);
1209 		if (c < 0)
1210 		  {
1211 			a = sub_left (a);
1212 		  }
1213 		else
1214 		  {
1215 			p = get_item (a);
1216 			a = sub_right (a);
1217 		  }
1218 	  }
1219 	while (a);
1220 	return p;
1221   }
1222 }
1223 
1224 /* Retrieve item of index [idx] in tree [t] */
1225 
1226 void *
avl_find_index(avl_size_t idx,avl_tree t)1227 avl_find_index (avl_size_t idx, avl_tree t)
1228 {
1229   avl_node *a;
1230 
1231 #ifndef AVL_NULLCHECKS
1232   if (t == NULL)
1233 	return NULL;
1234 #endif
1235   a = node_find_index (idx, t);
1236   return a != NULL ? get_item (a) : NULL;
1237 }
1238 
1239 #define attach_node(ptr,up,t)\
1240  ptr = new_node(item, up, t);\
1241  if (ptr == NULL){\
1242         AVL_SHOW_ERROR("%s\n", "couldn't allocate node");\
1243         return -1;\
1244  }\
1245  t->count++
1246 
1247 /* Iterative insertion */
1248 
1249 avl_code_t
avl_ins(void * item,avl_tree t,avl_bool_t allow_duplicates)1250 avl_ins (void *item, avl_tree t, avl_bool_t allow_duplicates)
1251 {
1252 #ifndef AVL_NULLCHECKS
1253   if (t == NULL)
1254 	return NULL;
1255   {
1256 #endif
1257 	avl_compare_func cmp = t->compare;
1258 	avl_node **r, *a;
1259 	int dir = 0;
1260 
1261 	for (r = &t->root, a = NULL; *r != NULL; r = &a->sub[dir = dir > 0])
1262 	  {
1263 		a = *r;
1264 		dir = Item_Compare (cmp, t, item, get_item (a));
1265 		CMPERR_CHECK__INS (t->param);
1266 		if (!dir && !allow_duplicates)
1267 		  return 0;
1268 	  }
1269 
1270 	attach_node (*r, a, t);
1271 
1272 	return rebalance_ins (a, dir, t);
1273 
1274 #ifndef AVL_NULLCHECKS
1275   }								/* end if non-empty tree */
1276 #endif
1277 }
1278 
1279 avl_code_t
avl_del(void * item,avl_tree t,void ** backup)1280 avl_del (void *item, avl_tree t, void **backup)
1281 {
1282 #ifndef AVL_NULLCHECKS
1283   if (t == NULL || t->root == NULL)
1284 #else
1285   if (t->root == NULL)
1286 #endif
1287 	return 0;
1288   {
1289 	avl_node *a = node_find (item, t);
1290 
1291 	if (a == NULL)
1292 	  return CMPERR_CHECK__DEL (t->param);
1293 	return rebalance_del (a, t, backup);
1294   }
1295 }
1296 
1297 /* helper function */
1298 static avl_code_t
node_del_first(avl_tree t,struct ptr_handler * h)1299 node_del_first (avl_tree t, struct ptr_handler *h)
1300 {
1301   avl_node *p, *a, *c;
1302   rbal_t bal;
1303 
1304   p = node_first (t->root);
1305   a = p->up;
1306   if (sub_right (p) != NULL)
1307 	sub_right (p)->up = a;
1308   if (a == NULL)
1309 	t->root = sub_right (p);
1310   else
1311 	sub_left (a) = sub_right (p);
1312 
1313   detach_node (p, t, h);
1314 
1315   /* Start backtracking : subtree of [a] in direction [0] is less deep */
1316 
1317   for (;; a = c)
1318 	{
1319 	  if (a == NULL)
1320 		return 2;
1321 
1322 	  decr_rank (a, 1);
1323 	  bal = get_bal (a);
1324 
1325 	  if (bal == 0)
1326 		{
1327 		  set_rskew (a);
1328 		  break;
1329 		}
1330 	  if (bal & 1)
1331 		unset_lskew (a);
1332 	  c = a->up;
1333 	  if (get_bal (a))
1334 		{
1335 		  p = a;
1336 		  bal = get_bal (sub_right (p));
1337 		  if (!(bal & 1))
1338 			{
1339 			  /* bal = 0 or +1 */
1340 			  /* rotL(p) */
1341 			  a = sub_right (p);
1342 			  sub_right (p) = sub_left (a);
1343 			  if (sub_left (a) != NULL)
1344 				sub_left (a)->up = p;
1345 			  sub_left (a) = p;
1346 			  if (bal)
1347 				{
1348 				  unset_rskew (p);
1349 				  unset_rskew (a);
1350 				}
1351 			  else
1352 				set_lskew (a);
1353 			  rbal (a) += rzero (p);
1354 			}
1355 		  else
1356 			{
1357 			  /* rotRL(p) */
1358 			  a = sub_left (sub_right (p));
1359 			  sub_left (sub_right (p)) = sub_right (a);
1360 			  if (sub_right (a) != NULL)
1361 				sub_right (a)->up = sub_right (p);
1362 			  sub_right (p)->up = a;
1363 			  sub_right (a) = sub_right (p);
1364 			  sub_right (p) = sub_left (a);
1365 			  if (sub_left (a) != NULL)
1366 				sub_left (a)->up = p;
1367 			  sub_left (a) = p;
1368 			  switch (get_bal (a))
1369 				{
1370 				case 0:		/* not skewed */
1371 				  unset_rskew (p);
1372 				  unset_lskew (sub_right (a));
1373 				  break;
1374 				case 1:		/* left skew */
1375 				  unset_rskew (p);
1376 				  unset_lskew (sub_right (a));
1377 				  set_rskew (sub_right (a));
1378 				  break;
1379 				case 2:		/* right skew */
1380 				  unset_rskew (p);
1381 				  set_lskew (p);
1382 				  unset_lskew (sub_right (a));
1383 				}				/* switch */
1384 			  rbal (a) &= ~3;
1385 			  rbal (sub_right (a)) -= rzero (a);
1386 			  rbal (a) += rzero (p);
1387 			}					/* which rot */
1388 
1389 		  a->up = p->up;
1390 		  p->up = a;
1391 		  /* Done with rotation */
1392 		  if (c != NULL)
1393 			sub_left (c) = a;
1394 		  else
1395 			t->root = a;
1396 		  if (bal == 0)
1397 			break;
1398 		}						/* if getbal(a) */
1399 	}							/* for */
1400 
1401   /* Finish adjusting ranks */
1402   while ((a = a->up) != NULL)
1403 	{
1404 	  decr_rank (a, 1);
1405 	}
1406 
1407   return 1;
1408 }
1409 
1410 /* helper function */
1411 static avl_code_t
node_del_last(avl_tree t,struct ptr_handler * h)1412 node_del_last (avl_tree t, struct ptr_handler *h)
1413 {
1414 
1415   avl_node *p, *a, *c;
1416   rbal_t bal;
1417 
1418   p = node_last (t->root);
1419   a = p->up;
1420   if (sub_left (p) != NULL)
1421 	sub_left (p)->up = a;
1422   if (a == NULL)
1423 	t->root = sub_left (p);
1424   else
1425 	sub_right (a) = sub_left (p);
1426 
1427   detach_node (p, t, h);
1428 
1429   /* Start backtracking : subtree of [a] in direction [1] is less deep */
1430 
1431   for (;; a = c)
1432 	{
1433 	  if (a == NULL)
1434 		return 2;
1435 
1436 	  bal = get_bal (a);
1437 	  if (bal == 0)
1438 		{
1439 		  set_lskew (a);
1440 		  break;
1441 		}
1442 	  if (bal & 2)
1443 		unset_rskew (a);
1444 	  c = a->up;
1445 	  if (get_bal (a))
1446 		{
1447 		  p = a;
1448 		  bal = get_bal (sub_left (p));
1449 		  if (!(bal & 2))
1450 			{
1451 			  /* bal = 0 or -1 */
1452 			  /* rotR(p) */
1453 			  a = sub_left (p);
1454 			  sub_left (p) = sub_right (a);
1455 			  if (sub_right (a) != NULL)
1456 				sub_right (a)->up = p;
1457 			  sub_right (a) = p;
1458 			  if (bal)
1459 				{
1460 				  unset_lskew (p);
1461 				  unset_lskew (a);
1462 				}
1463 			  else
1464 				set_rskew (a);
1465 			  rbal (p) -= rzero (a);
1466 			}
1467 		  else
1468 			{
1469 			  /* rotLR(p) */
1470 			  a = sub_right (sub_left (p));
1471 			  sub_right (sub_left (p)) = sub_left (a);
1472 			  if (sub_left (a) != NULL)
1473 				sub_left (a)->up = sub_left (p);
1474 			  sub_left (p)->up = a;
1475 			  sub_left (a) = sub_left (p);
1476 			  sub_left (p) = sub_right (a);
1477 			  if (sub_right (a) != NULL)
1478 				sub_right (a)->up = p;
1479 			  sub_right (a) = p;
1480 			  switch (get_bal (a))
1481 				{
1482 				case 0:		/* not skewed */
1483 				  unset_lskew (p);
1484 				  unset_rskew (sub_left (a));
1485 				  break;
1486 				case 1:		/* left skew */
1487 				  unset_lskew (p);
1488 				  set_rskew (p);
1489 				  unset_rskew (sub_left (a));
1490 				  break;
1491 				case 2:		/* right skew */
1492 				  unset_lskew (p);
1493 				  unset_rskew (sub_left (a));
1494 				  set_lskew (sub_left (a));
1495 				}				/* switch */
1496 			  rbal (a) &= ~3;
1497 			  rbal (a) += rzero (sub_left (a));
1498 			  rbal (p) -= rzero (a);
1499 			}					/* which rot */
1500 
1501 		  a->up = p->up;
1502 		  p->up = a;
1503 		  /* Done with rotation */
1504 		  if (c != NULL)
1505 			sub_right (c) = a;
1506 		  else
1507 			t->root = a;
1508 		  if (bal == 0)
1509 			break;
1510 		}						/* if getbal(a) */
1511 	}							/* for */
1512 
1513   return 1;
1514 }
1515 
1516 /* [p] : juncture node (zeroed out) */
1517 
1518 /* [n] : rank of [p] in resulting tree */
1519 
1520 /* [delta] = depth_1 - depth_0 */
1521 
1522 static avl_code_t
join_left(avl_node * p,avl_node ** r0,avl_node * r1,int delta,int n)1523 join_left (avl_node * p, avl_node ** r0, avl_node * r1, int delta, int n)
1524 {
1525   avl_node *a = NULL, **r = r0;
1526 
1527   if (r1 == NULL)
1528 	{
1529 	  while (*r != NULL)
1530 		{
1531 		  a = *r;
1532 		  n -= (int)get_rank (a);
1533 		  r = &sub_right (a);
1534 		}
1535 	}
1536   else
1537 	{
1538 	  while (delta < -1)
1539 		{
1540 		  a = *r;
1541 		  delta += (int)(is_lskew (a) + 1);
1542 		  n -= (int)get_rank (a);
1543 		  r = &sub_right (a);
1544 		}
1545 	  r1->up = p;
1546 	  if (*r != NULL)
1547 		(*r)->up = p;
1548 	  if (delta)
1549 		set_lskew (p);
1550 	}
1551 
1552   /* at this point bal(*r) = -1 or 0 */
1553   sub_left (p) = *r;
1554   sub_right (p) = r1;
1555   p->up = a;
1556   set_rank (p, n);
1557   *r = p;
1558 
1559   for (;;)
1560 	{
1561 	  if (a == NULL)
1562 		return 2;
1563 	  if (get_bal (a))
1564 		break;
1565 	  set_rskew (a);
1566 	  a = a->up;
1567 	}
1568 
1569   /* Rotate if need be */
1570   /* No (+2,0) rotation to do */
1571 
1572   if (is_lskew (a))
1573 	unset_lskew (a);
1574 
1575   else
1576 	{
1577 	  avl_node *p = a;
1578 
1579 	  if (is_rskew (sub_right (p)))
1580 		{
1581 		  /* rotL(p) */
1582 		  a = sub_right (p);
1583 		  sub_right (p) = sub_left (a);
1584 		  if (sub_left (a) != NULL)
1585 			sub_left (a)->up = p;
1586 		  sub_left (a) = p;
1587 		  unset_rskew (p);
1588 		  rbal (a) += rzero (p);
1589 		}
1590 	  else
1591 		{
1592 		  /* rotRL(p) */
1593 		  a = sub_left (sub_right (p));
1594 		  sub_left (sub_right (p)) = sub_right (a);
1595 		  if (sub_right (a) != NULL)
1596 			sub_right (a)->up = sub_right (p);
1597 		  sub_right (p)->up = a;
1598 		  sub_right (a) = sub_right (p);
1599 		  sub_right (p) = sub_left (a);
1600 		  if (sub_left (a) != NULL)
1601 			sub_left (a)->up = p;
1602 		  sub_left (a) = p;
1603 		  switch (get_bal (a))
1604 			{
1605 			case 0:			/* not skewed */
1606 			  unset_rskew (p);
1607 			  unset_lskew (sub_right (a));
1608 			  break;
1609 			case 1:			/* left skew */
1610 			  unset_rskew (p);
1611 			  unset_lskew (sub_right (a));
1612 			  set_rskew (sub_right (a));
1613 			  break;
1614 			case 2:			/* right skew */
1615 			  unset_rskew (p);
1616 			  set_lskew (p);
1617 			  unset_lskew (sub_right (a));
1618 			}					/* switch */
1619 		  rbal (sub_right (a)) -= rzero (a);
1620 		  rbal (a) += rzero (p);
1621 		}						/* which rot */
1622 
1623 	  rbal (a) &= ~3;
1624 	  a->up = p->up;
1625 	  p->up = a;
1626 	  if (a->up != NULL)
1627 		sub_right (a->up) = a;
1628 	  else
1629 		*r0 = a;
1630 	}							/* rot or not rot */
1631 
1632   return 1;
1633 }
1634 
1635 /* [p] : juncture node */
1636 
1637 /* [n] : rank of [p] in resulting tree */
1638 
1639 static avl_code_t
join_right(avl_node * p,avl_node * r0,avl_node ** r1,int delta,int n)1640 join_right (avl_node * p, avl_node * r0, avl_node ** r1, int delta, int n)
1641 {
1642   avl_node *a = NULL, **r = r1;
1643 
1644   if (r0 == NULL)
1645 	{
1646 	  while (*r != NULL)
1647 		{
1648 		  a = *r;
1649 		  incr_rank (a, (rbal_t)n);
1650 		  r = &sub_left (a);
1651 		}
1652 	  n = 1;
1653 	}
1654   else
1655 	{
1656 	  while (delta > +1)
1657 		{
1658 		  a = *r;
1659 		  delta -= (int)(is_rskew (a) + 1);
1660 		  incr_rank (a, (rbal_t)n);
1661 		  r = &sub_left (a);
1662 		}
1663 	  r0->up = p;
1664 	  if (*r != NULL)
1665 		(*r)->up = p;
1666 	  if (delta)
1667 		set_rskew (p);
1668 	}
1669 
1670   /* at this point bal(*r) = +1 or 0 */
1671   sub_left (p) = r0;
1672   sub_right (p) = *r;
1673   set_rank (p, n);
1674   p->up = a;
1675   *r = p;
1676 
1677   for (;;)
1678 	{
1679 	  if (a == NULL)
1680 		return 2;
1681 	  if (get_bal (a))
1682 		break;
1683 	  set_lskew (a);
1684 	  a = a->up;
1685 	}
1686 
1687   /* Rotate if need be */
1688   /* No (-2,0) rotation to do */
1689 
1690   if (is_rskew (a))
1691 	unset_rskew (a);
1692 
1693   else
1694 	{
1695 	  avl_node *p = a;
1696 
1697 	  if (is_lskew (sub_left (p)))
1698 		{
1699 		  /* rotR(p) */
1700 		  a = sub_left (p);
1701 		  sub_left (p) = sub_right (a);
1702 		  if (sub_right (a) != NULL)
1703 			sub_right (a)->up = p;
1704 		  sub_right (a) = p;
1705 		  unset_lskew (p);
1706 		  rbal (p) -= rzero (a);
1707 		}
1708 	  else
1709 		{
1710 		  /* rotLR(p) */
1711 		  a = sub_right (sub_left (p));
1712 		  sub_right (sub_left (p)) = sub_left (a);
1713 		  if (sub_left (a) != NULL)
1714 			sub_left (a)->up = sub_left (p);
1715 		  sub_left (p)->up = a;
1716 		  sub_left (a) = sub_left (p);
1717 		  sub_left (p) = sub_right (a);
1718 		  if (sub_right (a) != NULL)
1719 			sub_right (a)->up = p;
1720 		  sub_right (a) = p;
1721 		  switch (get_bal (a))
1722 			{
1723 			case 0:			/* not skewed */
1724 			  unset_lskew (p);
1725 			  unset_rskew (sub_left (a));
1726 			  break;
1727 			case 1:			/* left skew */
1728 			  unset_lskew (p);
1729 			  set_rskew (p);
1730 			  unset_rskew (sub_left (a));
1731 			  break;
1732 			case 2:			/* right skew */
1733 			  unset_lskew (p);
1734 			  unset_rskew (sub_left (a));
1735 			  set_lskew (sub_left (a));
1736 			}					/* end switch */
1737 		  rbal (a) += rzero (sub_left (a));
1738 		  rbal (p) -= rzero (a);
1739 		}						/* end which rot */
1740 
1741 	  rbal (a) &= ~3;
1742 	  a->up = p->up;
1743 	  p->up = a;
1744 	  if (a->up != NULL)
1745 		sub_left (a->up) = a;
1746 	  else
1747 		*r1 = a;
1748 	}							/* end rot or not rot */
1749 
1750   return 1;
1751 }
1752 
1753 avl_code_t
avl_del_first(avl_tree t,void ** backup)1754 avl_del_first (avl_tree t, void **backup)
1755 {
1756 #ifndef AVL_NULLCHECKS
1757   if (t == NULL || t->root == NULL)
1758 #else
1759   if (t->root == NULL)
1760 #endif
1761 	return 0;
1762   {
1763 	avl_code_t rv;
1764 
1765 	if (backup == NULL)
1766 	  {
1767 		rv = node_del_first (t, NULL);
1768 	  }
1769 	else
1770 	  {
1771 		ini_ptr_handler (h, BACKUP);
1772 		rv = node_del_first (t, &h);
1773 		*backup = h.ptr;
1774 	  }
1775 	return rv;
1776   }
1777 }
1778 
1779 avl_code_t
avl_del_last(avl_tree t,void ** backup)1780 avl_del_last (avl_tree t, void **backup)
1781 {
1782 #ifndef AVL_NULLCHECKS
1783   if (t == NULL || t->root == NULL)
1784 #else
1785   if (t->root == NULL)
1786 #endif
1787 	return 0;
1788   {
1789 	avl_code_t rv;
1790 
1791 	if (backup == NULL)
1792 	  {
1793 		rv = node_del_last (t, NULL);
1794 	  }
1795 	else
1796 	  {
1797 		ini_ptr_handler (h, BACKUP);
1798 		rv = node_del_last (t, &h);
1799 		*backup = h.ptr;
1800 	  }
1801 	return rv;
1802   }
1803 }
1804 
1805 avl_code_t
avl_ins_index(void * item,avl_size_t idx,avl_tree t)1806 avl_ins_index (void *item, avl_size_t idx, avl_tree t)
1807 {
1808   avl_node *p;
1809 
1810   if (idx == 0 || t == NULL || idx > t->count + 1)
1811 	return 0;
1812 
1813   attach_node (p, NULL, t);
1814   /* Note: 'attach_node' macro increments t->count */
1815 
1816   if (idx == 1)
1817 	{
1818 	  return join_right (p, (avl_node *) NULL, &t->root, /*delta= */ 0, 1);
1819 	}
1820   else if (idx == t->count)
1821 	{
1822 	  return
1823 	      join_left (p, &t->root, (avl_node *) NULL, /*delta= */ 0, (int)t->count);
1824 	}
1825   else
1826 	{
1827 	  avl_node *a = node_find_index (idx - 1, t);
1828 	  int dir;
1829 
1830 	  if (sub_right (a) != NULL)
1831 		{
1832 		  a = node_first (sub_right (a));
1833 		  sub_left (a) = p;
1834 		  dir = 0;
1835 		}
1836 	  else
1837 		{
1838 		  sub_right (a) = p;
1839 		  dir = 1;
1840 		}
1841 
1842 	  p->up = a;
1843 	  return rebalance_ins (a, dir, t);
1844 	}
1845 }
1846 
1847 avl_code_t
avl_del_index(avl_size_t idx,avl_tree t,void ** backup)1848 avl_del_index (avl_size_t idx, avl_tree t, void **backup)
1849 {
1850 #ifndef AVL_NULLCHECKS
1851   if (t == NULL)
1852 	return 0;
1853 #endif
1854 
1855   if (idx == 0 || idx > t->count)
1856 	return 0;
1857   if (idx == 1)
1858 	return avl_del_first (t, backup);
1859   if (idx == t->count)
1860 	return avl_del_last (t, backup);
1861   {
1862 	avl_node *a = node_find_index (idx, t);
1863 
1864 	return rebalance_del (a, t, backup);
1865   }
1866 }
1867 
1868 /*
1869  * Outcome: [t0] handles the concatenation of [t0] and [t1]
1870  */
1871 
1872 void
avl_cat(avl_tree t0,avl_tree t1)1873 avl_cat (avl_tree t0, avl_tree t1)
1874 {
1875 #ifndef AVL_NULLCHECKS
1876   if (t0 == NULL || t1 == NULL || t1->root == NULL)
1877 #else
1878   if (t1->root == NULL)
1879 #endif
1880 	return;
1881 
1882   if (t0->root == NULL)
1883 	{
1884 	  t0->root = t1->root;
1885 	  t0->count = t1->count;
1886 	  t1->root = NULL;
1887 	  t1->count = 0;
1888 
1889 	}
1890   else
1891 	{
1892 	  int delta = depth (t1->root) - depth (t0->root);
1893 
1894 	  ini_ptr_handler (h, DETACH);
1895 
1896 	  if (delta <= 0)
1897 		{
1898 		  if (node_del_first (t1, &h) == 2)
1899 			--delta;
1900 		  (void) join_left ((avl_node *) h.ptr, &t0->root, t1->root, delta,
1901 				    (int)(t0->count + 1));
1902 		}
1903 	  else
1904 		{
1905 		  if (node_del_last (t0, &h) == 2)
1906 			++delta;
1907 		  (void) join_right ((avl_node *) h.ptr, t0->root, &t1->root, delta,
1908 				     (int)(t0->count + 1));
1909 		  t0->root = t1->root;
1910 		}
1911 
1912 	  t1->root = NULL;
1913 	  t0->count += t1->count + 1;
1914 	  t1->count = 0;
1915 	}
1916 }
1917 
1918 /*
1919  * - [t0] and [t1] are existing handles
1920  * - See Donald Knuth, TAOCP Vol.3 "Sorting and searching"
1921  */
1922 
1923 avl_code_t
avl_split(const void * item,avl_tree t,avl_tree t0,avl_tree t1)1924 avl_split (const void *item, avl_tree t, avl_tree t0, avl_tree t1)
1925 {
1926 #ifndef AVL_NULLCHECKS
1927   if (t == NULL || t->root == NULL)
1928 #else
1929   if (t->root == NULL)
1930 #endif /* AVL_NULLCHECKS */
1931 	return 0;
1932 
1933   t0->root = NULL;
1934   t1->root = NULL;
1935   t0->count = 0;
1936   t1->count = 0;
1937 
1938   {
1939 	avl_compare_func cmp = t->compare;
1940 	avl_node *a, *p, *sn;		/* sn: split node */
1941 	int d_, k, na, an[AVL_STACK_CAPACITY];
1942 
1943 	/* invariant: [na]= size of tree rooted at [a] plus one */
1944 
1945 	for (a = t->root, na = (int)(t->count + 1), k = 0;;)
1946 	  {
1947 		d_ = Item_Compare (cmp, t, item, get_item (a));
1948 		CMPERR_CHECK__SPLIT (t->param);
1949 		if (!d_)
1950 		  break;
1951 		p = a->sub[d_ = d_ > 0];
1952 		if (p == NULL)
1953 		  return 0;
1954 		an[k++] = na;
1955 		if (d_)
1956 		    na -= (int)get_rank (a);
1957 		else
1958 		    na = (int)get_rank (a);
1959 		a = p;
1960 	  }
1961 
1962 	/* record split node */
1963 	sn = a;
1964 
1965 	if (k == 0)
1966 	  {
1967 		t0->root = sub_left (a);
1968 		t1->root = sub_right (a);
1969 		if (t0->root != NULL)
1970 		  t0->root->up = NULL;
1971 		if (t1->root != NULL)
1972 		  t1->root->up = NULL;
1973 		t0->count = get_rank (a) - 1;
1974 		t1->count = t->count - get_rank (a);
1975 	  }
1976 	else
1977 	  {
1978 		avl_node *r[2], *rr;
1979 		int h[2], ha, hh;
1980 		avl_size_t n[2], nn;
1981 
1982 		r[0] = sub_left (a);
1983 		r[1] = sub_right (a);
1984 		if (r[0] != NULL)
1985 		  r[0]->up = NULL;
1986 		if (r[1] != NULL)
1987 		  r[1]->up = NULL;
1988 		ha = depth (a);
1989 		h[0] = ha - (is_rskew (a) ? 2 : 1);
1990 		h[1] = ha - (is_lskew (a) ? 2 : 1);
1991 		n[0] = get_rank (a);	/* size of r[0] plus one */
1992 		n[1] = (avl_size_t)na - n[0];		/* size of r[1] plus one */
1993 
1994 		for (p = a->up, d_ = a != sub_left (p);;)
1995 		  {
1996 
1997 			a = p;				/* a: juncture node */
1998 			p = a->up;
1999 
2000 			if (d_ == 0)
2001 			  {
2002 				hh = h[1];
2003 				ha += (is_rskew (a) ? 2 : 1);
2004 				h[1] = ha - (is_lskew (a) ? 2 : 1);
2005 				nn = n[1];
2006 				n[1] += (avl_size_t)(an[k - 1] - (int)get_rank (a));
2007 				if (p != NULL)
2008 				  d_ = a != sub_left (p);
2009 				rbal (a) = 0;
2010 
2011 				if (h[1] >= hh)
2012 				  {
2013 					rr = r[1];
2014 					r[1] = sub_right (a);
2015 					if (r[1] != NULL)
2016 					  r[1]->up = NULL;
2017 					h[1] += (2 == join_right (a, rr, r + 1, h[1] - hh, (int)nn));
2018 				  }
2019 				else
2020 				  {
2021 					h[1] =
2022 					  hh + (2 ==
2023 							join_left (a, r + 1, sub_right (a), h[1] - hh,
2024 								   (int)nn));
2025 				  }
2026 			  }
2027 			else
2028 			  {
2029 				hh = h[0];
2030 				ha += (is_lskew (a) ? 2 : 1);
2031 				h[0] = ha - (is_rskew (a) ? 2 : 1);
2032 				nn = get_rank (a);
2033 				n[0] += nn;
2034 				if (p != NULL)
2035 				  d_ = a != sub_left (p);
2036 				rbal (a) = 0;
2037 
2038 				if (h[0] >= hh)
2039 				  {
2040 					rr = r[0];
2041 					r[0] = sub_left (a);
2042 					if (r[0] != NULL)
2043 					  r[0]->up = NULL;
2044 					h[0] += (2 == join_left (a, r, rr, hh - h[0], (int)nn));
2045 				  }
2046 				else
2047 				  {
2048 					h[0] =
2049 					  hh + (2 ==
2050 						join_right (a, sub_left (a), r, hh - h[0], (int)nn));
2051 				  }
2052 			  }
2053 
2054 			if (--k == 0)
2055 			  break;
2056 		  }						/* for p */
2057 
2058 		t0->root = r[0];
2059 		t1->root = r[1];
2060 		t0->count = n[0] - 1;
2061 		t1->count = n[1] - 1;
2062 	  }							/* if k==0 */
2063 
2064 	/* Detach split node */
2065 	detach_node (sn, t, NULL);
2066 	t->root = NULL;
2067 	t->count = 0;
2068 
2069 	return 1;
2070   }
2071 }
2072 
2073 /* Inorder traversal */
2074 
2075 void
avl_walk(avl_tree t,avl_item_func proc,void * param)2076 avl_walk (avl_tree t, avl_item_func proc, void *param)
2077 {
2078 #ifndef AVL_NULLCHECKS
2079   if (t == NULL || t->root == NULL)
2080 #else
2081   if (t->root == NULL)
2082 #endif
2083 	return;
2084 
2085   {
2086 	avl_node *a = t->root, *p;
2087 
2088 	while (1)
2089 	  {
2090 		while (sub_left (a) != NULL)
2091 		  a = sub_left (a);
2092 
2093 		while (1)
2094 		  {
2095 			(*proc) (get_item (a), param);
2096 			if (sub_right (a) != NULL)
2097 			  break;
2098 			do
2099 			  {
2100 				p = a;
2101 				a = p->up;
2102 				if (a == NULL)
2103 				  return;
2104 			  }
2105 			while (p != sub_left (a));
2106 		  }
2107 		a = sub_right (a);
2108 	  }
2109   }
2110 }
2111 
2112 /* recursive helper for 'avl_slice' */
2113 static int
node_slice(avl_node ** root,avl_node ** cur,avl_tree tree,avl_size_t len)2114 node_slice (avl_node ** root, avl_node ** cur, avl_tree tree, avl_size_t len)
2115 {
2116   avl_size_t mid = len / 2;
2117 
2118   if (mid == 0)
2119 	{
2120 	  if ((*root = new_node ((*cur)->item, /*parent */ NULL, tree)) == NULL)
2121 		return -1;
2122 	  sub_left (*root) = NULL;
2123 	  sub_right (*root) = NULL;
2124 	  rbal (*root) = 4;
2125 	  *cur = node_next (*cur);
2126 	  return 0;
2127 
2128 	}
2129   else if ((*root = new_node (NULL, /*parent */ NULL, tree)) == NULL)
2130 	{
2131 	  return -1;
2132 	}
2133   else
2134 	{
2135 	  avl_node *p = *root;
2136 	  int h0, h1 = -1;
2137 
2138 	  rbal (p) = (mid + 1) << 2;
2139 
2140 	  if ((h0 = node_slice (&sub_left (p), cur, tree, mid)) < 0)
2141 		return -1;
2142 
2143 	  p->item = (*tree->copy) ((*cur)->item);
2144 	  sub_left (p)->up = p;
2145 
2146 	  *cur = node_next (*cur);
2147 
2148 	  if (len -= mid + 1)
2149 		{
2150 		  if ((h1 = node_slice (&sub_right (p), cur, tree, len)) < 0)
2151 			return -1;
2152 		  sub_right (p)->up = p;
2153 		}
2154 
2155 	  if (h0 > h1)
2156 		set_lskew (p);
2157 	  else if (h0 < h1)
2158 		{
2159 		  set_rskew (p);
2160 		  return 1 + h1;
2161 		}
2162 	  return 1 + h0;
2163 	}
2164 }
2165 
2166 /* Return a slice t[lo,hi) as a new tree */
2167 
2168 avl_tree
avl_slice(avl_tree t,avl_size_t lo_idx,avl_size_t hi_idx,void * param)2169 avl_slice (avl_tree t, avl_size_t lo_idx, avl_size_t hi_idx, void *param)
2170 {
2171 #ifndef AVL_NULLCHECKS
2172   if (t == NULL)
2173 	return NULL;
2174 #endif /* AVL_NULLCHECKS */
2175 
2176   if (lo_idx > hi_idx || lo_idx > t->count)
2177 	return NULL;
2178   if (lo_idx < 1)
2179 	lo_idx = 1;
2180   if (hi_idx > t->count + 1)
2181 	hi_idx = t->count + 1;
2182 
2183   {
2184 	avl_tree tt = avl_create (t->compare,
2185 							  t->copy,
2186 							  t->dispose,
2187 							  t->alloc,
2188 							  t->dealloc,
2189 							  param);
2190 
2191 	if (tt == NULL)
2192 	  {
2193 		AVL_SHOW_ERROR ("%s\n",
2194 						"couldn't allocate new handle in avl_slice()");
2195 		return NULL;
2196 	  }
2197 
2198 	if (lo_idx < hi_idx)
2199 	  {
2200 		avl_node *cur = node_find_index (lo_idx, t);
2201 
2202 		if (node_slice (&tt->root, &cur, t, tt->count = hi_idx - lo_idx) < 0)
2203 		  {
2204 			AVL_SHOW_ERROR ("%s\n", "couldn't allocate node in avl_slice()");
2205 			node_empty (tt);
2206 			(*t->dealloc) (tt);
2207 			return NULL;
2208 		  }
2209 		tt->root->up = NULL;
2210 	  }
2211 	return tt;
2212   }
2213 }
2214 
2215 /* recursive helper for 'avl_xload' */
2216 
2217 static int
node_load(avl_node ** root,avl_itersource cur,void ** pres,avl_tree desc,avl_size_t len)2218 node_load (avl_node ** root, avl_itersource cur, void **pres, avl_tree desc,
2219 		   avl_size_t len)
2220 {
2221   avl_size_t mid = len / 2;
2222 
2223   if (mid == 0)
2224 	{
2225 	  if (0 != (*cur->f) (cur, pres)
2226 		  || (*root = new_node (*pres, /*parent */ NULL, desc)) == NULL)
2227 		return -1;
2228 	  sub_left (*root) = NULL;
2229 	  sub_right (*root) = NULL;
2230 	  rbal (*root) = 4;
2231 	  return 0;
2232 
2233 	}
2234   else if ((*root = new_node (NULL, /*parent */ NULL, desc)) == NULL)
2235 	{
2236 	  return -1;
2237 	}
2238   else
2239 	{
2240 	  avl_node *p = *root;
2241 	  int h0, h1 = -1;
2242 
2243 	  rbal (p) = (mid + 1) << 2;
2244 
2245 	  if ((h0 = node_load (&sub_left (p), cur, pres, desc, mid)) < 0)
2246 		return -1;
2247 
2248 	  if (0 != (*cur->f) (cur, pres))
2249 		return -1;
2250 
2251 	  p->item = (*desc->copy) (*pres);
2252 	  sub_left (p)->up = p;
2253 
2254 	  if (len -= mid + 1)
2255 		{
2256 		  if ((h1 = node_load (&sub_right (p), cur, pres, desc, len)) < 0)
2257 			return -1;
2258 		  sub_right (p)->up = p;
2259 		}
2260 
2261 	  if (h0 > h1)
2262 		set_lskew (p);
2263 	  else if (h0 < h1)
2264 		{
2265 		  set_rskew (p);
2266 		  return 1 + h1;
2267 		}
2268 	  return 1 + h0;
2269 	}
2270 }
2271 
2272 /* Load 'len' items from itersource */
2273 
2274 avl_tree
avl_xload(avl_itersource src,void ** pres,avl_size_t len,avl_config conf,void * tree_param)2275 avl_xload (avl_itersource src, void **pres, avl_size_t len, avl_config conf,
2276 		   void *tree_param)
2277 {
2278 #ifndef AVL_NULLCHECKS
2279   if (src == NULL)
2280 	return NULL;
2281   {
2282 #endif /* AVL_NULLCHECKS */
2283 
2284 	avl_tree tt = avl_create (conf->compare,
2285 							  conf->copy,
2286 							  conf->dispose,
2287 							  conf->alloc,
2288 							  conf->dealloc,
2289 							  tree_param);
2290 
2291 	if (tt == NULL)
2292 	  {
2293 		AVL_SHOW_ERROR ("%s\n", "couldn't allocate new handle in avl_load()");
2294 		return NULL;
2295 	  }
2296 
2297 	if (len)
2298 	  {
2299 		if (node_load (&tt->root, src, pres, tt, tt->count = len) < 0)
2300 		  {
2301 			AVL_SHOW_ERROR ("%s\n", "couldn't allocate node in avl_load()");
2302 			node_empty (tt);
2303 			(*tt->dealloc) (tt);
2304 			return NULL;
2305 		  }
2306 		tt->root->up = NULL;
2307 	  }
2308 	return tt;
2309 #ifndef AVL_NULLCHECKS
2310   }
2311 #endif
2312 }
2313 
2314 #ifdef HAVE_AVL_VERIFY
2315 
2316 /* Verification routine */
2317 typedef enum
2318 {
2319   okay = 0,
2320   bad_parent = 1,
2321   bad_rank = 2,
2322   out_of_balance = 3,
2323   out_of_order = 4,
2324   diff_mismatch = 5,
2325   count_mismatch = 6
2326 }
2327 avl_verify_code;
2328 
2329 static avl_bool_t
avl_error(avl_verify_code err)2330 avl_error (avl_verify_code err)
2331 {
2332   static char *errmess[] = {
2333 	"Bad parent link",
2334 	"Rank error",
2335 	"Out of balance",
2336 	"Out of order",
2337 	"Differential mismatch",
2338 	"Count mismatch"
2339   };
2340 
2341   AVL_SHOW_ERROR ("Invalid avl_tree: %s\n", errmess[err - 1]);
2342   return avl_false;
2343 }
2344 
2345 static int bals[] = { 1, 0, 2 };
2346 
2347 /*
2348    helper for recursive 'avl_verify' function
2349    return 0 iff okay
2350  */
2351 
2352 static avl_verify_code
node_verify(avl_node * root,avl_tree tree,int * h,avl_size_t * c,avl_node * up)2353 node_verify (avl_node * root, avl_tree tree, int *h, avl_size_t * c,
2354 			 avl_node * up)
2355 {
2356   avl_verify_code err = okay;
2357 
2358   if (root == NULL)
2359 	*h = AVL_MIN_DEPTH, *c = 0;
2360   else
2361 	{
2362 #define AVL_ASSERT(expr,n) if (expr) ; else { err = n; break; }
2363 #define CHECK(err) if (err) break
2364 
2365 	  avl_node *left, *right;
2366 	  avl_size_t c_[2];
2367 	  int h_[2], delta;
2368 
2369 	  left = sub_left (root);
2370 	  right = sub_right (root);
2371 	  do
2372 		{
2373 		  AVL_ASSERT (root->up == up, bad_parent);
2374 		  CHECK (err = node_verify (left, tree, h_, c_, root));
2375 		  AVL_ASSERT (get_rank (root) == *c_ + 1, bad_rank);
2376 		  CHECK (err = node_verify (right, tree, h_ + 1, c_ + 1, root));
2377 		  delta = h_[1] - h_[0];
2378 		  AVL_ASSERT (delta >= -1 && delta <= +1, out_of_balance);
2379 		  AVL_ASSERT (get_bal (root) == bals[delta + 1], diff_mismatch);
2380 		  AVL_ASSERT (left == NULL
2381 					  || (Item_Compare (tree->compare, tree, get_item (left),
2382 										get_item (root)) <=
2383 						  0 CMPERR_CHECK__VERIFY (tree->param)),
2384 					  out_of_order);
2385 		  AVL_ASSERT (right == NULL
2386 					  ||
2387 					  (Item_Compare
2388 					   (tree->compare, tree, get_item (root),
2389 						get_item (right)) <=
2390 					   0 CMPERR_CHECK__VERIFY (tree->param)), out_of_order);
2391 		  *h = 1 + (h_[0] > h_[1] ? h_[0] : h_[1]);
2392 		  *c = 1 + c_[0] + c_[1];
2393 		}
2394 	  while (0);
2395 	}
2396   return err;
2397 }
2398 
2399 avl_bool_t
avl_verify(avl_tree t)2400 avl_verify (avl_tree t)
2401 {
2402 #ifndef AVL_NULLCHECKS
2403   if (t == NULL)
2404 	return avl_false;
2405 #endif /* AVL_NULLCHECKS */
2406   {
2407 	int h;
2408 	avl_size_t c;
2409 	avl_verify_code err;
2410 
2411 	err = node_verify (t->root, t, &h, &c, (avl_node *) NULL);
2412 	if (err)
2413 	  return avl_error (err);
2414 	if (c != t->count)
2415 	  return avl_error (count_mismatch);
2416 	return avl_true;
2417   }
2418 }
2419 #endif /* HAVE_AVL_VERIFY */
2420 
2421 /****************
2422  *               *
2423  *   ITERATORS   *
2424  *               *
2425  ****************/
2426 
2427 typedef enum
2428 {
2429   AVL_ITERATOR_PRE,
2430   AVL_ITERATOR_POST,
2431   AVL_ITERATOR_INTREE
2432 }
2433 avl_status_t;
2434 
2435 struct avl_iterator_
2436 {
2437   avl_node *pos;
2438   avl_tree tree;
2439   avl_status_t status;
2440 };
2441 
2442 #define get_root(i)             i->tree->root
2443 #define is_pre(i)               i->status == AVL_ITERATOR_PRE
2444 #define is_post(i)              i->status == AVL_ITERATOR_POST
2445 #define set_pre_iterator(i)     i->status = AVL_ITERATOR_PRE
2446 #define set_post_iterator(i)    i->status = AVL_ITERATOR_POST
2447 #define set_in_iterator(i)      i->status = AVL_ITERATOR_INTREE
2448 
2449 /* Position existing iterator [iter] at node matching [item] in its own tree,
2450  * if it exists ; otherwise do nothing
2451  */
2452 
2453 void
avl_iterator_seek(const void * item,avl_iterator iter)2454 avl_iterator_seek (const void *item, avl_iterator iter)
2455 {
2456   avl_node *p = node_find (item, iter->tree);
2457 
2458   if (p != NULL)
2459 	{
2460 	  set_in_iterator (iter);
2461 	  iter->pos = p;
2462 	}
2463 }
2464 
2465 void
avl_iterator_seek_index(avl_size_t idx,avl_iterator iter)2466 avl_iterator_seek_index (avl_size_t idx, avl_iterator iter)
2467 {
2468   avl_node *p = node_find_index (idx, iter->tree);
2469 
2470   if (p != NULL)
2471 	{
2472 	  set_in_iterator (iter);
2473 	  iter->pos = p;
2474 	}
2475 }
2476 
2477 /* Return item pointer at current position */
2478 
2479 void *
avl_iterator_cur(avl_iterator iter)2480 avl_iterator_cur (avl_iterator iter)
2481 {
2482   return iter->pos != NULL ? get_item (iter->pos) : NULL;
2483 }
2484 
2485 avl_size_t
avl_iterator_count(avl_iterator iter)2486 avl_iterator_count (avl_iterator iter)
2487 {
2488   return iter->tree->count;
2489 }
2490 
2491 avl_size_t
avl_iterator_index(avl_iterator iter)2492 avl_iterator_index (avl_iterator iter)
2493 {
2494   if (iter->pos != NULL)
2495 	return get_index (iter->pos);
2496   else if (is_pre (iter))
2497 	return 0;
2498   else
2499 	return iter->tree->count + 1;
2500 }
2501 
2502 /* Rustic: */
2503 
2504 avl_iterator
avl_iterator_new(avl_tree t,avl_ini_t ini,...)2505 avl_iterator_new (avl_tree t, avl_ini_t ini, ...)
2506 {
2507   va_list args;
2508   avl_iterator iter = NULL;
2509 
2510   va_start (args, ini);
2511 
2512   if (t == NULL)
2513 	goto finish;
2514 
2515   if ((iter = (*t->alloc) (sizeof (struct avl_iterator_))) == NULL)
2516 	{
2517 	  AVL_SHOW_ERROR ("%s\n", "couldn't create iterator");
2518 	  goto finish;
2519 	}
2520 
2521   iter->pos = NULL;
2522   iter->tree = t;
2523 
2524   if (ini != AVL_ITERATOR_INI_INTREE)
2525 	{
2526 	  iter->status =
2527 		(ini == AVL_ITERATOR_INI_PRE) ? AVL_ITERATOR_PRE : AVL_ITERATOR_POST;
2528 	}
2529   else
2530 	{
2531 	  const void *item = NULL;
2532 
2533 	  item = va_arg (args, const void *);
2534 
2535 	  set_pre_iterator (iter);
2536 
2537 	  if (item == NULL)
2538 		AVL_SHOW_ERROR ("%s\n", "missing argument to avl_iterator_new()");
2539 	  else
2540 		avl_iterator_seek (item, iter);
2541 	}
2542 
2543 finish:
2544   va_end (args);
2545   return iter;
2546 }
2547 
2548 /*
2549  * The following used to write to memory after it was freed.
2550  * Corrected by: David Turner <novalis@openplans.org>
2551  */
2552 void
avl_iterator_kill(avl_iterator iter)2553 avl_iterator_kill (avl_iterator iter)
2554 {
2555   if (iter != NULL)
2556 	{
2557 	  avl_dealloc_func dealloc = iter->tree->dealloc;
2558 	  iter->pos = NULL;
2559 	  iter->tree = NULL;
2560 	  (*dealloc) (iter);
2561 	}
2562 }
2563 
2564 void *
avl_iterator_next(avl_iterator iter)2565 avl_iterator_next (avl_iterator iter)
2566 {
2567   avl_node *a = iter->pos;
2568 
2569   if (is_post (iter))
2570 	return NULL;
2571 
2572   if (is_pre (iter))
2573 	{
2574 	  a = get_root (iter);
2575 	  if (a != NULL)
2576 		{
2577 		  a = node_first (a);
2578 		  set_in_iterator (iter);
2579 		}
2580 	}
2581   else
2582 	{
2583 	  a = node_next (a);
2584 	  if (a == NULL)
2585 		set_post_iterator (iter);
2586 	}
2587 
2588   iter->pos = a;
2589   return a != NULL ? get_item (a) : NULL;
2590 }
2591 
2592 void *
avl_iterator_prev(avl_iterator iter)2593 avl_iterator_prev (avl_iterator iter)
2594 {
2595   avl_node *a = iter->pos;
2596 
2597   if (is_pre (iter))
2598 	return NULL;
2599 
2600   if (is_post (iter))
2601 	{
2602 	  a = get_root (iter);
2603 	  if (a != NULL)
2604 		{
2605 		  a = node_last (a);
2606 		  set_in_iterator (iter);
2607 		}
2608 	}
2609   else
2610 	{
2611 	  a = node_prev (a);
2612 	  if (a == NULL)
2613 		set_pre_iterator (iter);
2614 	}
2615 
2616   iter->pos = a;
2617   return a != NULL ? get_item (a) : NULL;
2618 }
2619 
2620 /* Remove node at current position */
2621 
2622 /* Move cursor to next position */
2623 
2624 avl_code_t
avl_iterator_del(avl_iterator iter,void ** backup)2625 avl_iterator_del (avl_iterator iter, void **backup)
2626 {
2627   if (iter == NULL || iter->pos == NULL)
2628 	return 0;
2629   {
2630 	avl_node *a = iter->pos, *p;
2631 
2632 	p = node_next (a);
2633 	if (p == NULL)
2634 	  set_post_iterator (iter);
2635 	iter->pos = p;
2636 	return rebalance_del (a, iter->tree, backup);
2637   }
2638 }
2639