1 /* Copyright (C) 1995-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 /* Tree search for red/black trees.
19    The algorithm for adding nodes is taken from one of the many "Algorithms"
20    books by Robert Sedgewick, although the implementation differs.
21    The algorithm for deleting nodes can probably be found in a book named
22    "Introduction to Algorithms" by Cormen/Leiserson/Rivest.  At least that's
23    the book that my professor took most algorithms from during the "Data
24    Structures" course...
25 
26    Totally public domain.  */
27 
28 /* Red/black trees are binary trees in which the edges are colored either red
29    or black.  They have the following properties:
30    1. The number of black edges on every path from the root to a leaf is
31       constant.
32    2. No two red edges are adjacent.
33    Therefore there is an upper bound on the length of every path, it's
34    O(log n) where n is the number of nodes in the tree.  No path can be longer
35    than 1+2*P where P is the length of the shortest path in the tree.
36    Useful for the implementation:
37    3. If one of the children of a node is NULL, then the other one is red
38       (if it exists).
39 
40    In the implementation, not the edges are colored, but the nodes.  The color
41    interpreted as the color of the edge leading to this node.  The color is
42    meaningless for the root node, but we color the root node black for
43    convenience.  All added nodes are red initially.
44 
45    Adding to a red/black tree is rather easy.  The right place is searched
46    with a usual binary tree search.  Additionally, whenever a node N is
47    reached that has two red successors, the successors are colored black and
48    the node itself colored red.  This moves red edges up the tree where they
49    pose less of a problem once we get to really insert the new node.  Changing
50    N's color to red may violate rule 2, however, so rotations may become
51    necessary to restore the invariants.  Adding a new red leaf may violate
52    the same rule, so afterwards an additional check is run and the tree
53    possibly rotated.
54 
55    Deleting is hairy.  There are mainly two nodes involved: the node to be
56    deleted (n1), and another node that is to be unchained from the tree (n2).
57    If n1 has a successor (the node with a smallest key that is larger than
58    n1), then the successor becomes n2 and its contents are copied into n1,
59    otherwise n1 becomes n2.
60    Unchaining a node may violate rule 1: if n2 is black, one subtree is
61    missing one black edge afterwards.  The algorithm must try to move this
62    error upwards towards the root, so that the subtree that does not have
63    enough black edges becomes the whole tree.  Once that happens, the error
64    has disappeared.  It may not be necessary to go all the way up, since it
65    is possible that rotations and recoloring can fix the error before that.
66 
67    Although the deletion algorithm must walk upwards through the tree, we
68    do not store parent pointers in the nodes.  Instead, delete allocates a
69    small array of parent pointers and fills it while descending the tree.
70    Since we know that the length of a path is O(log n), where n is the number
71    of nodes, this is likely to use less memory.  */
72 
73 /* Tree rotations look like this:
74       A                C
75      / \              / \
76     B   C            A   G
77    / \ / \  -->     / \
78    D E F G         B   F
79                   / \
80                  D   E
81 
82    In this case, A has been rotated left.  This preserves the ordering of the
83    binary tree.  */
84 
85 #include <assert.h>
86 #include <stdalign.h>
87 #include <stddef.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <search.h>
91 
92 /* Assume malloc returns naturally aligned (alignof (max_align_t))
93    pointers so we can use the low bits to store some extra info.  This
94    works for the left/right node pointers since they are not user
95    visible and always allocated by malloc.  The user provides the key
96    pointer and so that can point anywhere and doesn't have to be
97    aligned.  */
98 #define USE_MALLOC_LOW_BIT 1
99 
100 #ifndef USE_MALLOC_LOW_BIT
101 typedef struct node_t
102 {
103   /* Callers expect this to be the first element in the structure - do not
104      move!  */
105   const void *key;
106   struct node_t *left_node;
107   struct node_t *right_node;
108   unsigned int is_red:1;
109 } *node;
110 
111 #define RED(N) (N)->is_red
112 #define SETRED(N) (N)->is_red = 1
113 #define SETBLACK(N) (N)->is_red = 0
114 #define SETNODEPTR(NP,P) (*NP) = (P)
115 #define LEFT(N) (N)->left_node
116 #define LEFTPTR(N) (&(N)->left_node)
117 #define SETLEFT(N,L) (N)->left_node = (L)
118 #define RIGHT(N) (N)->right_node
119 #define RIGHTPTR(N) (&(N)->right_node)
120 #define SETRIGHT(N,R) (N)->right_node = (R)
121 #define DEREFNODEPTR(NP) (*(NP))
122 
123 #else /* USE_MALLOC_LOW_BIT */
124 
125 typedef struct node_t
126 {
127   /* Callers expect this to be the first element in the structure - do not
128      move!  */
129   const void *key;
130   uintptr_t left_node; /* Includes whether the node is red in low-bit. */
131   uintptr_t right_node;
132 } *node;
133 
134 #define RED(N) (node)((N)->left_node & ((uintptr_t) 0x1))
135 #define SETRED(N) (N)->left_node |= ((uintptr_t) 0x1)
136 #define SETBLACK(N) (N)->left_node &= ~((uintptr_t) 0x1)
137 #define SETNODEPTR(NP,P) (*NP) = (node)((((uintptr_t)(*NP)) \
138 					 & (uintptr_t) 0x1) | (uintptr_t)(P))
139 #define LEFT(N) (node)((N)->left_node & ~((uintptr_t) 0x1))
140 #define LEFTPTR(N) (node *)(&(N)->left_node)
141 #define SETLEFT(N,L) (N)->left_node = (((N)->left_node & (uintptr_t) 0x1) \
142 				       | (uintptr_t)(L))
143 #define RIGHT(N) (node)((N)->right_node)
144 #define RIGHTPTR(N) (node *)(&(N)->right_node)
145 #define SETRIGHT(N,R) (N)->right_node = (uintptr_t)(R)
146 #define DEREFNODEPTR(NP) (node)((uintptr_t)(*(NP)) & ~((uintptr_t) 0x1))
147 
148 #endif /* USE_MALLOC_LOW_BIT */
149 typedef const struct node_t *const_node;
150 
151 #undef DEBUGGING
152 
153 #ifdef DEBUGGING
154 
155 /* Routines to check tree invariants.  */
156 
157 #define CHECK_TREE(a) check_tree(a)
158 
159 static void
check_tree_recurse(node p,int d_sofar,int d_total)160 check_tree_recurse (node p, int d_sofar, int d_total)
161 {
162   if (p == NULL)
163     {
164       assert (d_sofar == d_total);
165       return;
166     }
167 
168   check_tree_recurse (LEFT(p), d_sofar + (LEFT(p) && !RED(LEFT(p))),
169 		      d_total);
170   check_tree_recurse (RIGHT(p), d_sofar + (RIGHT(p) && !RED(RIGHT(p))),
171 		      d_total);
172   if (LEFT(p))
173     assert (!(RED(LEFT(p)) && RED(p)));
174   if (RIGHT(p))
175     assert (!(RED(RIGHT(p)) && RED(p)));
176 }
177 
178 static void
check_tree(node root)179 check_tree (node root)
180 {
181   int cnt = 0;
182   node p;
183   if (root == NULL)
184     return;
185   SETBLACK(root);
186   for(p = LEFT(root); p; p = LEFT(p))
187     cnt += !RED(p);
188   check_tree_recurse (root, 0, cnt);
189 }
190 
191 #else
192 
193 #define CHECK_TREE(a)
194 
195 #endif
196 
197 /* Possibly "split" a node with two red successors, and/or fix up two red
198    edges in a row.  ROOTP is a pointer to the lowest node we visited, PARENTP
199    and GPARENTP pointers to its parent/grandparent.  P_R and GP_R contain the
200    comparison values that determined which way was taken in the tree to reach
201    ROOTP.  MODE is 1 if we need not do the split, but must check for two red
202    edges between GPARENTP and ROOTP.  */
203 static void
maybe_split_for_insert(node * rootp,node * parentp,node * gparentp,int p_r,int gp_r,int mode)204 maybe_split_for_insert (node *rootp, node *parentp, node *gparentp,
205 			int p_r, int gp_r, int mode)
206 {
207   node root = DEREFNODEPTR(rootp);
208   node *rp, *lp;
209   node rpn, lpn;
210   rp = RIGHTPTR(root);
211   rpn = RIGHT(root);
212   lp = LEFTPTR(root);
213   lpn = LEFT(root);
214 
215   /* See if we have to split this node (both successors red).  */
216   if (mode == 1
217       || ((rpn) != NULL && (lpn) != NULL && RED(rpn) && RED(lpn)))
218     {
219       /* This node becomes red, its successors black.  */
220       SETRED(root);
221       if (rpn)
222 	SETBLACK(rpn);
223       if (lpn)
224 	SETBLACK(lpn);
225 
226       /* If the parent of this node is also red, we have to do
227 	 rotations.  */
228       if (parentp != NULL && RED(DEREFNODEPTR(parentp)))
229 	{
230 	  node gp = DEREFNODEPTR(gparentp);
231 	  node p = DEREFNODEPTR(parentp);
232 	  /* There are two main cases:
233 	     1. The edge types (left or right) of the two red edges differ.
234 	     2. Both red edges are of the same type.
235 	     There exist two symmetries of each case, so there is a total of
236 	     4 cases.  */
237 	  if ((p_r > 0) != (gp_r > 0))
238 	    {
239 	      /* Put the child at the top of the tree, with its parent
240 		 and grandparent as successors.  */
241 	      SETRED(p);
242 	      SETRED(gp);
243 	      SETBLACK(root);
244 	      if (p_r < 0)
245 		{
246 		  /* Child is left of parent.  */
247 		  SETLEFT(p,rpn);
248 		  SETNODEPTR(rp,p);
249 		  SETRIGHT(gp,lpn);
250 		  SETNODEPTR(lp,gp);
251 		}
252 	      else
253 		{
254 		  /* Child is right of parent.  */
255 		  SETRIGHT(p,lpn);
256 		  SETNODEPTR(lp,p);
257 		  SETLEFT(gp,rpn);
258 		  SETNODEPTR(rp,gp);
259 		}
260 	      SETNODEPTR(gparentp,root);
261 	    }
262 	  else
263 	    {
264 	      SETNODEPTR(gparentp,p);
265 	      /* Parent becomes the top of the tree, grandparent and
266 		 child are its successors.  */
267 	      SETBLACK(p);
268 	      SETRED(gp);
269 	      if (p_r < 0)
270 		{
271 		  /* Left edges.  */
272 		  SETLEFT(gp,RIGHT(p));
273 		  SETRIGHT(p,gp);
274 		}
275 	      else
276 		{
277 		  /* Right edges.  */
278 		  SETRIGHT(gp,LEFT(p));
279 		  SETLEFT(p,gp);
280 		}
281 	    }
282 	}
283     }
284 }
285 
286 /* Find or insert datum into search tree.
287    KEY is the key to be located, ROOTP is the address of tree root,
288    COMPAR the ordering function.  */
289 void *
__tsearch(const void * key,void ** vrootp,__compar_fn_t compar)290 __tsearch (const void *key, void **vrootp, __compar_fn_t compar)
291 {
292   node q, root;
293   node *parentp = NULL, *gparentp = NULL;
294   node *rootp = (node *) vrootp;
295   node *nextp;
296   int r = 0, p_r = 0, gp_r = 0; /* No they might not, Mr Compiler.  */
297 
298 #ifdef USE_MALLOC_LOW_BIT
299   static_assert (alignof (max_align_t) > 1, "malloc must return aligned ptrs");
300 #endif
301 
302   if (rootp == NULL)
303     return NULL;
304 
305   /* This saves some additional tests below.  */
306   root = DEREFNODEPTR(rootp);
307   if (root != NULL)
308     SETBLACK(root);
309 
310   CHECK_TREE (root);
311 
312   nextp = rootp;
313   while (DEREFNODEPTR(nextp) != NULL)
314     {
315       root = DEREFNODEPTR(rootp);
316       r = (*compar) (key, root->key);
317       if (r == 0)
318 	return root;
319 
320       maybe_split_for_insert (rootp, parentp, gparentp, p_r, gp_r, 0);
321       /* If that did any rotations, parentp and gparentp are now garbage.
322 	 That doesn't matter, because the values they contain are never
323 	 used again in that case.  */
324 
325       nextp = r < 0 ? LEFTPTR(root) : RIGHTPTR(root);
326       if (DEREFNODEPTR(nextp) == NULL)
327 	break;
328 
329       gparentp = parentp;
330       parentp = rootp;
331       rootp = nextp;
332 
333       gp_r = p_r;
334       p_r = r;
335     }
336 
337   q = (struct node_t *) malloc (sizeof (struct node_t));
338   if (q != NULL)
339     {
340       /* Make sure the malloc implementation returns naturally aligned
341 	 memory blocks when expected.  Or at least even pointers, so we
342 	 can use the low bit as red/black flag.  Even though we have a
343 	 static_assert to make sure alignof (max_align_t) > 1 there could
344 	 be an interposed malloc implementation that might cause havoc by
345 	 not obeying the malloc contract.  */
346 #ifdef USE_MALLOC_LOW_BIT
347       assert (((uintptr_t) q & (uintptr_t) 0x1) == 0);
348 #endif
349       SETNODEPTR(nextp,q);		/* link new node to old */
350       q->key = key;			/* initialize new node */
351       SETRED(q);
352       SETLEFT(q,NULL);
353       SETRIGHT(q,NULL);
354 
355       if (nextp != rootp)
356 	/* There may be two red edges in a row now, which we must avoid by
357 	   rotating the tree.  */
358 	maybe_split_for_insert (nextp, rootp, parentp, r, p_r, 1);
359     }
360 
361   return q;
362 }
363 libc_hidden_def (__tsearch)
weak_alias(__tsearch,tsearch)364 weak_alias (__tsearch, tsearch)
365 
366 
367 /* Find datum in search tree.
368    KEY is the key to be located, ROOTP is the address of tree root,
369    COMPAR the ordering function.  */
370 void *
371 __tfind (const void *key, void *const *vrootp, __compar_fn_t compar)
372 {
373   node root;
374   node *rootp = (node *) vrootp;
375 
376   if (rootp == NULL)
377     return NULL;
378 
379   root = DEREFNODEPTR(rootp);
380   CHECK_TREE (root);
381 
382   while (DEREFNODEPTR(rootp) != NULL)
383     {
384       root = DEREFNODEPTR(rootp);
385       int r;
386 
387       r = (*compar) (key, root->key);
388       if (r == 0)
389 	return root;
390 
391       rootp = r < 0 ? LEFTPTR(root) : RIGHTPTR(root);
392     }
393   return NULL;
394 }
395 libc_hidden_def (__tfind)
weak_alias(__tfind,tfind)396 weak_alias (__tfind, tfind)
397 
398 
399 /* Delete node with given key.
400    KEY is the key to be deleted, ROOTP is the address of the root of tree,
401    COMPAR the comparison function.  */
402 void *
403 __tdelete (const void *key, void **vrootp, __compar_fn_t compar)
404 {
405   node p, q, r, retval;
406   int cmp;
407   node *rootp = (node *) vrootp;
408   node root, unchained;
409   /* Stack of nodes so we remember the parents without recursion.  It's
410      _very_ unlikely that there are paths longer than 40 nodes.  The tree
411      would need to have around 250.000 nodes.  */
412   int stacksize = 40;
413   int sp = 0;
414   node **nodestack = alloca (sizeof (node *) * stacksize);
415 
416   if (rootp == NULL)
417     return NULL;
418   p = DEREFNODEPTR(rootp);
419   if (p == NULL)
420     return NULL;
421 
422   CHECK_TREE (p);
423 
424   root = DEREFNODEPTR(rootp);
425   while ((cmp = (*compar) (key, root->key)) != 0)
426     {
427       if (sp == stacksize)
428 	{
429 	  node **newstack;
430 	  stacksize += 20;
431 	  newstack = alloca (sizeof (node *) * stacksize);
432 	  nodestack = memcpy (newstack, nodestack, sp * sizeof (node *));
433 	}
434 
435       nodestack[sp++] = rootp;
436       p = DEREFNODEPTR(rootp);
437       if (cmp < 0)
438 	{
439 	  rootp = LEFTPTR(p);
440 	  root = LEFT(p);
441 	}
442       else
443 	{
444 	  rootp = RIGHTPTR(p);
445 	  root = RIGHT(p);
446 	}
447       if (root == NULL)
448 	return NULL;
449     }
450 
451   /* This is bogus if the node to be deleted is the root... this routine
452      really should return an integer with 0 for success, -1 for failure
453      and errno = ESRCH or something.  */
454   retval = p;
455 
456   /* We don't unchain the node we want to delete. Instead, we overwrite
457      it with its successor and unchain the successor.  If there is no
458      successor, we really unchain the node to be deleted.  */
459 
460   root = DEREFNODEPTR(rootp);
461 
462   r = RIGHT(root);
463   q = LEFT(root);
464 
465   if (q == NULL || r == NULL)
466     unchained = root;
467   else
468     {
469       node *parentp = rootp, *up = RIGHTPTR(root);
470       node upn;
471       for (;;)
472 	{
473 	  if (sp == stacksize)
474 	    {
475 	      node **newstack;
476 	      stacksize += 20;
477 	      newstack = alloca (sizeof (node *) * stacksize);
478 	      nodestack = memcpy (newstack, nodestack, sp * sizeof (node *));
479 	    }
480 	  nodestack[sp++] = parentp;
481 	  parentp = up;
482 	  upn = DEREFNODEPTR(up);
483 	  if (LEFT(upn) == NULL)
484 	    break;
485 	  up = LEFTPTR(upn);
486 	}
487       unchained = DEREFNODEPTR(up);
488     }
489 
490   /* We know that either the left or right successor of UNCHAINED is NULL.
491      R becomes the other one, it is chained into the parent of UNCHAINED.  */
492   r = LEFT(unchained);
493   if (r == NULL)
494     r = RIGHT(unchained);
495   if (sp == 0)
496     SETNODEPTR(rootp,r);
497   else
498     {
499       q = DEREFNODEPTR(nodestack[sp-1]);
500       if (unchained == RIGHT(q))
501 	SETRIGHT(q,r);
502       else
503 	SETLEFT(q,r);
504     }
505 
506   if (unchained != root)
507     root->key = unchained->key;
508   if (!RED(unchained))
509     {
510       /* Now we lost a black edge, which means that the number of black
511 	 edges on every path is no longer constant.  We must balance the
512 	 tree.  */
513       /* NODESTACK now contains all parents of R.  R is likely to be NULL
514 	 in the first iteration.  */
515       /* NULL nodes are considered black throughout - this is necessary for
516 	 correctness.  */
517       while (sp > 0 && (r == NULL || !RED(r)))
518 	{
519 	  node *pp = nodestack[sp - 1];
520 	  p = DEREFNODEPTR(pp);
521 	  /* Two symmetric cases.  */
522 	  if (r == LEFT(p))
523 	    {
524 	      /* Q is R's brother, P is R's parent.  The subtree with root
525 		 R has one black edge less than the subtree with root Q.  */
526 	      q = RIGHT(p);
527 	      if (RED(q))
528 		{
529 		  /* If Q is red, we know that P is black. We rotate P left
530 		     so that Q becomes the top node in the tree, with P below
531 		     it.  P is colored red, Q is colored black.
532 		     This action does not change the black edge count for any
533 		     leaf in the tree, but we will be able to recognize one
534 		     of the following situations, which all require that Q
535 		     is black.  */
536 		  SETBLACK(q);
537 		  SETRED(p);
538 		  /* Left rotate p.  */
539 		  SETRIGHT(p,LEFT(q));
540 		  SETLEFT(q,p);
541 		  SETNODEPTR(pp,q);
542 		  /* Make sure pp is right if the case below tries to use
543 		     it.  */
544 		  nodestack[sp++] = pp = LEFTPTR(q);
545 		  q = RIGHT(p);
546 		}
547 	      /* We know that Q can't be NULL here.  We also know that Q is
548 		 black.  */
549 	      if ((LEFT(q) == NULL || !RED(LEFT(q)))
550 		  && (RIGHT(q) == NULL || !RED(RIGHT(q))))
551 		{
552 		  /* Q has two black successors.  We can simply color Q red.
553 		     The whole subtree with root P is now missing one black
554 		     edge.  Note that this action can temporarily make the
555 		     tree invalid (if P is red).  But we will exit the loop
556 		     in that case and set P black, which both makes the tree
557 		     valid and also makes the black edge count come out
558 		     right.  If P is black, we are at least one step closer
559 		     to the root and we'll try again the next iteration.  */
560 		  SETRED(q);
561 		  r = p;
562 		}
563 	      else
564 		{
565 		  /* Q is black, one of Q's successors is red.  We can
566 		     repair the tree with one operation and will exit the
567 		     loop afterwards.  */
568 		  if (RIGHT(q) == NULL || !RED(RIGHT(q)))
569 		    {
570 		      /* The left one is red.  We perform the same action as
571 			 in maybe_split_for_insert where two red edges are
572 			 adjacent but point in different directions:
573 			 Q's left successor (let's call it Q2) becomes the
574 			 top of the subtree we are looking at, its parent (Q)
575 			 and grandparent (P) become its successors. The former
576 			 successors of Q2 are placed below P and Q.
577 			 P becomes black, and Q2 gets the color that P had.
578 			 This changes the black edge count only for node R and
579 			 its successors.  */
580 		      node q2 = LEFT(q);
581 		      if (RED(p))
582 			SETRED(q2);
583 		      else
584 			SETBLACK(q2);
585 		      SETRIGHT(p,LEFT(q2));
586 		      SETLEFT(q,RIGHT(q2));
587 		      SETRIGHT(q2,q);
588 		      SETLEFT(q2,p);
589 		      SETNODEPTR(pp,q2);
590 		      SETBLACK(p);
591 		    }
592 		  else
593 		    {
594 		      /* It's the right one.  Rotate P left. P becomes black,
595 			 and Q gets the color that P had.  Q's right successor
596 			 also becomes black.  This changes the black edge
597 			 count only for node R and its successors.  */
598 		      if (RED(p))
599 			SETRED(q);
600 		      else
601 			SETBLACK(q);
602 		      SETBLACK(p);
603 
604 		      SETBLACK(RIGHT(q));
605 
606 		      /* left rotate p */
607 		      SETRIGHT(p,LEFT(q));
608 		      SETLEFT(q,p);
609 		      SETNODEPTR(pp,q);
610 		    }
611 
612 		  /* We're done.  */
613 		  sp = 1;
614 		  r = NULL;
615 		}
616 	    }
617 	  else
618 	    {
619 	      /* Comments: see above.  */
620 	      q = LEFT(p);
621 	      if (RED(q))
622 		{
623 		  SETBLACK(q);
624 		  SETRED(p);
625 		  SETLEFT(p,RIGHT(q));
626 		  SETRIGHT(q,p);
627 		  SETNODEPTR(pp,q);
628 		  nodestack[sp++] = pp = RIGHTPTR(q);
629 		  q = LEFT(p);
630 		}
631 	      if ((RIGHT(q) == NULL || !RED(RIGHT(q)))
632 		  && (LEFT(q) == NULL || !RED(LEFT(q))))
633 		{
634 		  SETRED(q);
635 		  r = p;
636 		}
637 	      else
638 		{
639 		  if (LEFT(q) == NULL || !RED(LEFT(q)))
640 		    {
641 		      node q2 = RIGHT(q);
642 		      if (RED(p))
643 			SETRED(q2);
644 		      else
645 			SETBLACK(q2);
646 		      SETLEFT(p,RIGHT(q2));
647 		      SETRIGHT(q,LEFT(q2));
648 		      SETLEFT(q2,q);
649 		      SETRIGHT(q2,p);
650 		      SETNODEPTR(pp,q2);
651 		      SETBLACK(p);
652 		    }
653 		  else
654 		    {
655 		      if (RED(p))
656 			SETRED(q);
657 		      else
658 			SETBLACK(q);
659 		      SETBLACK(p);
660 		      SETBLACK(LEFT(q));
661 		      SETLEFT(p,RIGHT(q));
662 		      SETRIGHT(q,p);
663 		      SETNODEPTR(pp,q);
664 		    }
665 		  sp = 1;
666 		  r = NULL;
667 		}
668 	    }
669 	  --sp;
670 	}
671       if (r != NULL)
672 	SETBLACK(r);
673     }
674 
675   free (unchained);
676   return retval;
677 }
678 libc_hidden_def (__tdelete)
weak_alias(__tdelete,tdelete)679 weak_alias (__tdelete, tdelete)
680 
681 
682 /* Walk the nodes of a tree.
683    ROOT is the root of the tree to be walked, ACTION the function to be
684    called at each node.  LEVEL is the level of ROOT in the whole tree.  */
685 static void
686 trecurse (const void *vroot, __action_fn_t action, int level)
687 {
688   const_node root = (const_node) vroot;
689 
690   if (LEFT(root) == NULL && RIGHT(root) == NULL)
691     (*action) (root, leaf, level);
692   else
693     {
694       (*action) (root, preorder, level);
695       if (LEFT(root) != NULL)
696 	trecurse (LEFT(root), action, level + 1);
697       (*action) (root, postorder, level);
698       if (RIGHT(root) != NULL)
699 	trecurse (RIGHT(root), action, level + 1);
700       (*action) (root, endorder, level);
701     }
702 }
703 
704 
705 /* Walk the nodes of a tree.
706    ROOT is the root of the tree to be walked, ACTION the function to be
707    called at each node.  */
708 void
__twalk(const void * vroot,__action_fn_t action)709 __twalk (const void *vroot, __action_fn_t action)
710 {
711   const_node root = (const_node) vroot;
712 
713   CHECK_TREE ((node) root);
714 
715   if (root != NULL && action != NULL)
716     trecurse (root, action, 0);
717 }
718 libc_hidden_def (__twalk)
weak_alias(__twalk,twalk)719 weak_alias (__twalk, twalk)
720 
721 /* twalk_r is the same as twalk, but with a closure parameter instead
722    of the level.  */
723 static void
724 trecurse_r (const void *vroot, void (*action) (const void *, VISIT, void *),
725 	    void *closure)
726 {
727   const_node root = (const_node) vroot;
728 
729   if (LEFT(root) == NULL && RIGHT(root) == NULL)
730     (*action) (root, leaf, closure);
731   else
732     {
733       (*action) (root, preorder, closure);
734       if (LEFT(root) != NULL)
735 	trecurse_r (LEFT(root), action, closure);
736       (*action) (root, postorder, closure);
737       if (RIGHT(root) != NULL)
738 	trecurse_r (RIGHT(root), action, closure);
739       (*action) (root, endorder, closure);
740     }
741 }
742 
743 void
__twalk_r(const void * vroot,void (* action)(const void *,VISIT,void *),void * closure)744 __twalk_r (const void *vroot, void (*action) (const void *, VISIT, void *),
745 	   void *closure)
746 {
747   const_node root = (const_node) vroot;
748 
749   CHECK_TREE ((node) root);
750 
751   if (root != NULL && action != NULL)
752     trecurse_r (root, action, closure);
753 }
754 libc_hidden_def (__twalk_r)
weak_alias(__twalk_r,twalk_r)755 weak_alias (__twalk_r, twalk_r)
756 
757 /* The standardized functions miss an important functionality: the
758    tree cannot be removed easily.  We provide a function to do this.  */
759 static void
760 tdestroy_recurse (node root, __free_fn_t freefct)
761 {
762   if (LEFT(root) != NULL)
763     tdestroy_recurse (LEFT(root), freefct);
764   if (RIGHT(root) != NULL)
765     tdestroy_recurse (RIGHT(root), freefct);
766   (*freefct) ((void *) root->key);
767   /* Free the node itself.  */
768   free (root);
769 }
770 
771 void
__tdestroy(void * vroot,__free_fn_t freefct)772 __tdestroy (void *vroot, __free_fn_t freefct)
773 {
774   node root = (node) vroot;
775 
776   CHECK_TREE (root);
777 
778   if (root != NULL)
779     tdestroy_recurse (root, freefct);
780 }
781 libc_hidden_def (__tdestroy)
782 weak_alias (__tdestroy, tdestroy)
783