| 1 | /* Copyright (C) 1995-2024 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 |
| 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 |
| 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 |
| 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 * |
| 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, mode: 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 (size: 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 (rootp: nextp, parentp: rootp, gparentp: parentp, p_r: r, gp_r: p_r, mode: 1); |
| 359 | } |
| 360 | |
| 361 | return q; |
| 362 | } |
| 363 | libc_hidden_def (__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) |
| 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 (ptr: unchained); |
| 676 | return retval; |
| 677 | } |
| 678 | libc_hidden_def (__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: level + 1); |
| 697 | (*action) (root, postorder, level); |
| 698 | if (RIGHT(root) != NULL) |
| 699 | trecurse (RIGHT(root), action, level: 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 |
| 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 (vroot: root, action, level: 0); |
| 717 | } |
| 718 | libc_hidden_def (__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 |
| 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 (vroot: root, action, closure); |
| 753 | } |
| 754 | libc_hidden_def (__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 (ptr: root); |
| 769 | } |
| 770 | |
| 771 | void |
| 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 | |