1 /*- 2 ******************************************************************************* 3 * 4 * cpp macro implementation of left-leaning 2-3 red-black trees. Parent 5 * pointers are not used, and color bits are stored in the least significant 6 * bit of right-child pointers (if RB_COMPACT is defined), thus making node 7 * linkage as compact as is possible for red-black trees. 8 * 9 * Usage: 10 * 11 * #include <stdint.h> 12 * #include <stdbool.h> 13 * #define NDEBUG // (Optional, see assert(3).) 14 * #include <assert.h> 15 * #define RB_COMPACT // (Optional, embed color bits in right-child pointers.) 16 * #include <rb.h> 17 * ... 18 * 19 ******************************************************************************* 20 */ 21 22 #ifndef RB_H_ 23 #define RB_H_ 24 25 #ifdef RB_COMPACT 26 /* Node structure. */ 27 #define rb_node(a_type) \ 28 struct { \ 29 a_type *rbn_left; \ 30 a_type *rbn_right_red; \ 31 } 32 #else 33 #define rb_node(a_type) \ 34 struct { \ 35 a_type *rbn_left; \ 36 a_type *rbn_right; \ 37 bool rbn_red; \ 38 } 39 #endif 40 41 /* Root structure. */ 42 #define rb_tree(a_type) \ 43 struct { \ 44 a_type *rbt_root; \ 45 a_type rbt_nil; \ 46 } 47 48 /* Left accessors. */ 49 #define rbtn_left_get(a_type, a_field, a_node) \ 50 ((a_node)->a_field.rbn_left) 51 #define rbtn_left_set(a_type, a_field, a_node, a_left) do { \ 52 (a_node)->a_field.rbn_left = a_left; \ 53 } while (0) 54 55 #ifdef RB_COMPACT 56 /* Right accessors. */ 57 #define rbtn_right_get(a_type, a_field, a_node) \ 58 ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red) \ 59 & ((ssize_t)-2))) 60 #define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ 61 (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \ 62 | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \ 63 } while (0) 64 65 /* Color accessors. */ 66 #define rbtn_red_get(a_type, a_field, a_node) \ 67 ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red) \ 68 & ((size_t)1))) 69 #define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ 70 (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t) \ 71 (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)) \ 72 | ((ssize_t)a_red)); \ 73 } while (0) 74 #define rbtn_red_set(a_type, a_field, a_node) do { \ 75 (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) \ 76 (a_node)->a_field.rbn_right_red) | ((size_t)1)); \ 77 } while (0) 78 #define rbtn_black_set(a_type, a_field, a_node) do { \ 79 (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t) \ 80 (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)); \ 81 } while (0) 82 #else 83 /* Right accessors. */ 84 #define rbtn_right_get(a_type, a_field, a_node) \ 85 ((a_node)->a_field.rbn_right) 86 #define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ 87 (a_node)->a_field.rbn_right = a_right; \ 88 } while (0) 89 90 /* Color accessors. */ 91 #define rbtn_red_get(a_type, a_field, a_node) \ 92 ((a_node)->a_field.rbn_red) 93 #define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ 94 (a_node)->a_field.rbn_red = (a_red); \ 95 } while (0) 96 #define rbtn_red_set(a_type, a_field, a_node) do { \ 97 (a_node)->a_field.rbn_red = true; \ 98 } while (0) 99 #define rbtn_black_set(a_type, a_field, a_node) do { \ 100 (a_node)->a_field.rbn_red = false; \ 101 } while (0) 102 #endif 103 104 /* Node initializer. */ 105 #define rbt_node_new(a_type, a_field, a_rbt, a_node) do { \ 106 rbtn_left_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \ 107 rbtn_right_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \ 108 rbtn_red_set(a_type, a_field, (a_node)); \ 109 } while (0) 110 111 /* Tree initializer. */ 112 #define rb_new(a_type, a_field, a_rbt) do { \ 113 (a_rbt)->rbt_root = &(a_rbt)->rbt_nil; \ 114 rbt_node_new(a_type, a_field, a_rbt, &(a_rbt)->rbt_nil); \ 115 rbtn_black_set(a_type, a_field, &(a_rbt)->rbt_nil); \ 116 } while (0) 117 118 /* Internal utility macros. */ 119 #define rbtn_first(a_type, a_field, a_rbt, a_root, r_node) do { \ 120 (r_node) = (a_root); \ 121 if ((r_node) != &(a_rbt)->rbt_nil) { \ 122 for (; \ 123 rbtn_left_get(a_type, a_field, (r_node)) != &(a_rbt)->rbt_nil;\ 124 (r_node) = rbtn_left_get(a_type, a_field, (r_node))) { \ 125 } \ 126 } \ 127 } while (0) 128 129 #define rbtn_last(a_type, a_field, a_rbt, a_root, r_node) do { \ 130 (r_node) = (a_root); \ 131 if ((r_node) != &(a_rbt)->rbt_nil) { \ 132 for (; rbtn_right_get(a_type, a_field, (r_node)) != \ 133 &(a_rbt)->rbt_nil; (r_node) = rbtn_right_get(a_type, a_field, \ 134 (r_node))) { \ 135 } \ 136 } \ 137 } while (0) 138 139 #define rbtn_rotate_left(a_type, a_field, a_node, r_node) do { \ 140 (r_node) = rbtn_right_get(a_type, a_field, (a_node)); \ 141 rbtn_right_set(a_type, a_field, (a_node), \ 142 rbtn_left_get(a_type, a_field, (r_node))); \ 143 rbtn_left_set(a_type, a_field, (r_node), (a_node)); \ 144 } while (0) 145 146 #define rbtn_rotate_right(a_type, a_field, a_node, r_node) do { \ 147 (r_node) = rbtn_left_get(a_type, a_field, (a_node)); \ 148 rbtn_left_set(a_type, a_field, (a_node), \ 149 rbtn_right_get(a_type, a_field, (r_node))); \ 150 rbtn_right_set(a_type, a_field, (r_node), (a_node)); \ 151 } while (0) 152 153 /* 154 * The rb_proto() macro generates function prototypes that correspond to the 155 * functions generated by an equivalently parameterized call to rb_gen(). 156 */ 157 158 #define rb_proto(a_attr, a_prefix, a_rbt_type, a_type) \ 159 a_attr void \ 160 a_prefix##new(a_rbt_type *rbtree); \ 161 a_attr bool \ 162 a_prefix##empty(a_rbt_type *rbtree); \ 163 a_attr a_type * \ 164 a_prefix##first(a_rbt_type *rbtree); \ 165 a_attr a_type * \ 166 a_prefix##last(a_rbt_type *rbtree); \ 167 a_attr a_type * \ 168 a_prefix##next(a_rbt_type *rbtree, a_type *node); \ 169 a_attr a_type * \ 170 a_prefix##prev(a_rbt_type *rbtree, a_type *node); \ 171 a_attr a_type * \ 172 a_prefix##search(a_rbt_type *rbtree, a_type *key); \ 173 a_attr a_type * \ 174 a_prefix##nsearch(a_rbt_type *rbtree, a_type *key); \ 175 a_attr a_type * \ 176 a_prefix##psearch(a_rbt_type *rbtree, a_type *key); \ 177 a_attr void \ 178 a_prefix##insert(a_rbt_type *rbtree, a_type *node); \ 179 a_attr void \ 180 a_prefix##remove(a_rbt_type *rbtree, a_type *node); \ 181 a_attr a_type * \ 182 a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ 183 a_rbt_type *, a_type *, void *), void *arg); \ 184 a_attr a_type * \ 185 a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ 186 a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg); 187 188 /* 189 * The rb_gen() macro generates a type-specific red-black tree implementation, 190 * based on the above cpp macros. 191 * 192 * Arguments: 193 * 194 * a_attr : Function attribute for generated functions (ex: static). 195 * a_prefix : Prefix for generated functions (ex: ex_). 196 * a_rb_type : Type for red-black tree data structure (ex: ex_t). 197 * a_type : Type for red-black tree node data structure (ex: ex_node_t). 198 * a_field : Name of red-black tree node linkage (ex: ex_link). 199 * a_cmp : Node comparison function name, with the following prototype: 200 * int (a_cmp *)(a_type *a_node, a_type *a_other); 201 * ^^^^^^ 202 * or a_key 203 * Interpretation of comparison function return values: 204 * -1 : a_node < a_other 205 * 0 : a_node == a_other 206 * 1 : a_node > a_other 207 * In all cases, the a_node or a_key macro argument is the first 208 * argument to the comparison function, which makes it possible 209 * to write comparison functions that treat the first argument 210 * specially. 211 * 212 * Assuming the following setup: 213 * 214 * typedef struct ex_node_s ex_node_t; 215 * struct ex_node_s { 216 * rb_node(ex_node_t) ex_link; 217 * }; 218 * typedef rb_tree(ex_node_t) ex_t; 219 * rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp) 220 * 221 * The following API is generated: 222 * 223 * static void 224 * ex_new(ex_t *tree); 225 * Description: Initialize a red-black tree structure. 226 * Args: 227 * tree: Pointer to an uninitialized red-black tree object. 228 * 229 * static bool 230 * ex_empty(ex_t *tree); 231 * Description: Determine whether tree is empty. 232 * Args: 233 * tree: Pointer to an initialized red-black tree object. 234 * Ret: True if tree is empty, false otherwise. 235 * 236 * static ex_node_t * 237 * ex_first(ex_t *tree); 238 * static ex_node_t * 239 * ex_last(ex_t *tree); 240 * Description: Get the first/last node in tree. 241 * Args: 242 * tree: Pointer to an initialized red-black tree object. 243 * Ret: First/last node in tree, or NULL if tree is empty. 244 * 245 * static ex_node_t * 246 * ex_next(ex_t *tree, ex_node_t *node); 247 * static ex_node_t * 248 * ex_prev(ex_t *tree, ex_node_t *node); 249 * Description: Get node's successor/predecessor. 250 * Args: 251 * tree: Pointer to an initialized red-black tree object. 252 * node: A node in tree. 253 * Ret: node's successor/predecessor in tree, or NULL if node is 254 * last/first. 255 * 256 * static ex_node_t * 257 * ex_search(ex_t *tree, ex_node_t *key); 258 * Description: Search for node that matches key. 259 * Args: 260 * tree: Pointer to an initialized red-black tree object. 261 * key : Search key. 262 * Ret: Node in tree that matches key, or NULL if no match. 263 * 264 * static ex_node_t * 265 * ex_nsearch(ex_t *tree, ex_node_t *key); 266 * static ex_node_t * 267 * ex_psearch(ex_t *tree, ex_node_t *key); 268 * Description: Search for node that matches key. If no match is found, 269 * return what would be key's successor/predecessor, were 270 * key in tree. 271 * Args: 272 * tree: Pointer to an initialized red-black tree object. 273 * key : Search key. 274 * Ret: Node in tree that matches key, or if no match, hypothetical node's 275 * successor/predecessor (NULL if no successor/predecessor). 276 * 277 * static void 278 * ex_insert(ex_t *tree, ex_node_t *node); 279 * Description: Insert node into tree. 280 * Args: 281 * tree: Pointer to an initialized red-black tree object. 282 * node: Node to be inserted into tree. 283 * 284 * static void 285 * ex_remove(ex_t *tree, ex_node_t *node); 286 * Description: Remove node from tree. 287 * Args: 288 * tree: Pointer to an initialized red-black tree object. 289 * node: Node in tree to be removed. 290 * 291 * static ex_node_t * 292 * ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *, 293 * ex_node_t *, void *), void *arg); 294 * static ex_node_t * 295 * ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *, 296 * ex_node_t *, void *), void *arg); 297 * Description: Iterate forward/backward over tree, starting at node. If 298 * tree is modified, iteration must be immediately 299 * terminated by the callback function that causes the 300 * modification. 301 * Args: 302 * tree : Pointer to an initialized red-black tree object. 303 * start: Node at which to start iteration, or NULL to start at 304 * first/last node. 305 * cb : Callback function, which is called for each node during 306 * iteration. Under normal circumstances the callback function 307 * should return NULL, which causes iteration to continue. If a 308 * callback function returns non-NULL, iteration is immediately 309 * terminated and the non-NULL return value is returned by the 310 * iterator. This is useful for re-starting iteration after 311 * modifying tree. 312 * arg : Opaque pointer passed to cb(). 313 * Ret: NULL if iteration completed, or the non-NULL callback return value 314 * that caused termination of the iteration. 315 */ 316 #define rb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp) \ 317 a_attr void \ 318 a_prefix##new(a_rbt_type *rbtree) { \ 319 rb_new(a_type, a_field, rbtree); \ 320 } \ 321 a_attr bool \ 322 a_prefix##empty(a_rbt_type *rbtree) { \ 323 return (rbtree->rbt_root == &rbtree->rbt_nil); \ 324 } \ 325 a_attr a_type * \ 326 a_prefix##first(a_rbt_type *rbtree) { \ 327 a_type *ret; \ 328 rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ 329 if (ret == &rbtree->rbt_nil) { \ 330 ret = NULL; \ 331 } \ 332 return (ret); \ 333 } \ 334 a_attr a_type * \ 335 a_prefix##last(a_rbt_type *rbtree) { \ 336 a_type *ret; \ 337 rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ 338 if (ret == &rbtree->rbt_nil) { \ 339 ret = NULL; \ 340 } \ 341 return (ret); \ 342 } \ 343 a_attr a_type * \ 344 a_prefix##next(a_rbt_type *rbtree, a_type *node) { \ 345 a_type *ret; \ 346 if (rbtn_right_get(a_type, a_field, node) != &rbtree->rbt_nil) { \ 347 rbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type, \ 348 a_field, node), ret); \ 349 } else { \ 350 a_type *tnode = rbtree->rbt_root; \ 351 assert(tnode != &rbtree->rbt_nil); \ 352 ret = &rbtree->rbt_nil; \ 353 while (true) { \ 354 int cmp = (a_cmp)(node, tnode); \ 355 if (cmp < 0) { \ 356 ret = tnode; \ 357 tnode = rbtn_left_get(a_type, a_field, tnode); \ 358 } else if (cmp > 0) { \ 359 tnode = rbtn_right_get(a_type, a_field, tnode); \ 360 } else { \ 361 break; \ 362 } \ 363 assert(tnode != &rbtree->rbt_nil); \ 364 } \ 365 } \ 366 if (ret == &rbtree->rbt_nil) { \ 367 ret = (NULL); \ 368 } \ 369 return (ret); \ 370 } \ 371 a_attr a_type * \ 372 a_prefix##prev(a_rbt_type *rbtree, a_type *node) { \ 373 a_type *ret; \ 374 if (rbtn_left_get(a_type, a_field, node) != &rbtree->rbt_nil) { \ 375 rbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type, \ 376 a_field, node), ret); \ 377 } else { \ 378 a_type *tnode = rbtree->rbt_root; \ 379 assert(tnode != &rbtree->rbt_nil); \ 380 ret = &rbtree->rbt_nil; \ 381 while (true) { \ 382 int cmp = (a_cmp)(node, tnode); \ 383 if (cmp < 0) { \ 384 tnode = rbtn_left_get(a_type, a_field, tnode); \ 385 } else if (cmp > 0) { \ 386 ret = tnode; \ 387 tnode = rbtn_right_get(a_type, a_field, tnode); \ 388 } else { \ 389 break; \ 390 } \ 391 assert(tnode != &rbtree->rbt_nil); \ 392 } \ 393 } \ 394 if (ret == &rbtree->rbt_nil) { \ 395 ret = (NULL); \ 396 } \ 397 return (ret); \ 398 } \ 399 a_attr a_type * \ 400 a_prefix##search(a_rbt_type *rbtree, a_type *key) { \ 401 a_type *ret; \ 402 int cmp; \ 403 ret = rbtree->rbt_root; \ 404 while (ret != &rbtree->rbt_nil \ 405 && (cmp = (a_cmp)(key, ret)) != 0) { \ 406 if (cmp < 0) { \ 407 ret = rbtn_left_get(a_type, a_field, ret); \ 408 } else { \ 409 ret = rbtn_right_get(a_type, a_field, ret); \ 410 } \ 411 } \ 412 if (ret == &rbtree->rbt_nil) { \ 413 ret = (NULL); \ 414 } \ 415 return (ret); \ 416 } \ 417 a_attr a_type * \ 418 a_prefix##nsearch(a_rbt_type *rbtree, a_type *key) { \ 419 a_type *ret; \ 420 a_type *tnode = rbtree->rbt_root; \ 421 ret = &rbtree->rbt_nil; \ 422 while (tnode != &rbtree->rbt_nil) { \ 423 int cmp = (a_cmp)(key, tnode); \ 424 if (cmp < 0) { \ 425 ret = tnode; \ 426 tnode = rbtn_left_get(a_type, a_field, tnode); \ 427 } else if (cmp > 0) { \ 428 tnode = rbtn_right_get(a_type, a_field, tnode); \ 429 } else { \ 430 ret = tnode; \ 431 break; \ 432 } \ 433 } \ 434 if (ret == &rbtree->rbt_nil) { \ 435 ret = (NULL); \ 436 } \ 437 return (ret); \ 438 } \ 439 a_attr a_type * \ 440 a_prefix##psearch(a_rbt_type *rbtree, a_type *key) { \ 441 a_type *ret; \ 442 a_type *tnode = rbtree->rbt_root; \ 443 ret = &rbtree->rbt_nil; \ 444 while (tnode != &rbtree->rbt_nil) { \ 445 int cmp = (a_cmp)(key, tnode); \ 446 if (cmp < 0) { \ 447 tnode = rbtn_left_get(a_type, a_field, tnode); \ 448 } else if (cmp > 0) { \ 449 ret = tnode; \ 450 tnode = rbtn_right_get(a_type, a_field, tnode); \ 451 } else { \ 452 ret = tnode; \ 453 break; \ 454 } \ 455 } \ 456 if (ret == &rbtree->rbt_nil) { \ 457 ret = (NULL); \ 458 } \ 459 return (ret); \ 460 } \ 461 a_attr void \ 462 a_prefix##insert(a_rbt_type *rbtree, a_type *node) { \ 463 struct { \ 464 a_type *node; \ 465 int cmp; \ 466 } path[sizeof(void *) << 4], *pathp; \ 467 rbt_node_new(a_type, a_field, rbtree, node); \ 468 /* Wind. */ \ 469 path->node = rbtree->rbt_root; \ 470 for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \ 471 int cmp = pathp->cmp = a_cmp(node, pathp->node); \ 472 assert(cmp != 0); \ 473 if (cmp < 0) { \ 474 pathp[1].node = rbtn_left_get(a_type, a_field, \ 475 pathp->node); \ 476 } else { \ 477 pathp[1].node = rbtn_right_get(a_type, a_field, \ 478 pathp->node); \ 479 } \ 480 } \ 481 pathp->node = node; \ 482 /* Unwind. */ \ 483 for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ 484 a_type *cnode = pathp->node; \ 485 if (pathp->cmp < 0) { \ 486 a_type *left = pathp[1].node; \ 487 rbtn_left_set(a_type, a_field, cnode, left); \ 488 if (rbtn_red_get(a_type, a_field, left)) { \ 489 a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ 490 if (rbtn_red_get(a_type, a_field, leftleft)) { \ 491 /* Fix up 4-node. */ \ 492 a_type *tnode; \ 493 rbtn_black_set(a_type, a_field, leftleft); \ 494 rbtn_rotate_right(a_type, a_field, cnode, tnode); \ 495 cnode = tnode; \ 496 } \ 497 } else { \ 498 return; \ 499 } \ 500 } else { \ 501 a_type *right = pathp[1].node; \ 502 rbtn_right_set(a_type, a_field, cnode, right); \ 503 if (rbtn_red_get(a_type, a_field, right)) { \ 504 a_type *left = rbtn_left_get(a_type, a_field, cnode); \ 505 if (rbtn_red_get(a_type, a_field, left)) { \ 506 /* Split 4-node. */ \ 507 rbtn_black_set(a_type, a_field, left); \ 508 rbtn_black_set(a_type, a_field, right); \ 509 rbtn_red_set(a_type, a_field, cnode); \ 510 } else { \ 511 /* Lean left. */ \ 512 a_type *tnode; \ 513 bool tred = rbtn_red_get(a_type, a_field, cnode); \ 514 rbtn_rotate_left(a_type, a_field, cnode, tnode); \ 515 rbtn_color_set(a_type, a_field, tnode, tred); \ 516 rbtn_red_set(a_type, a_field, cnode); \ 517 cnode = tnode; \ 518 } \ 519 } else { \ 520 return; \ 521 } \ 522 } \ 523 pathp->node = cnode; \ 524 } \ 525 /* Set root, and make it black. */ \ 526 rbtree->rbt_root = path->node; \ 527 rbtn_black_set(a_type, a_field, rbtree->rbt_root); \ 528 } \ 529 a_attr void \ 530 a_prefix##remove(a_rbt_type *rbtree, a_type *node) { \ 531 struct { \ 532 a_type *node; \ 533 int cmp; \ 534 } *pathp, *nodep, path[sizeof(void *) << 4]; \ 535 /* Wind. */ \ 536 nodep = NULL; /* Silence compiler warning. */ \ 537 path->node = rbtree->rbt_root; \ 538 for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \ 539 int cmp = pathp->cmp = a_cmp(node, pathp->node); \ 540 if (cmp < 0) { \ 541 pathp[1].node = rbtn_left_get(a_type, a_field, \ 542 pathp->node); \ 543 } else { \ 544 pathp[1].node = rbtn_right_get(a_type, a_field, \ 545 pathp->node); \ 546 if (cmp == 0) { \ 547 /* Find node's successor, in preparation for swap. */ \ 548 pathp->cmp = 1; \ 549 nodep = pathp; \ 550 for (pathp++; pathp->node != &rbtree->rbt_nil; \ 551 pathp++) { \ 552 pathp->cmp = -1; \ 553 pathp[1].node = rbtn_left_get(a_type, a_field, \ 554 pathp->node); \ 555 } \ 556 break; \ 557 } \ 558 } \ 559 } \ 560 assert(nodep->node == node); \ 561 pathp--; \ 562 if (pathp->node != node) { \ 563 /* Swap node with its successor. */ \ 564 bool tred = rbtn_red_get(a_type, a_field, pathp->node); \ 565 rbtn_color_set(a_type, a_field, pathp->node, \ 566 rbtn_red_get(a_type, a_field, node)); \ 567 rbtn_left_set(a_type, a_field, pathp->node, \ 568 rbtn_left_get(a_type, a_field, node)); \ 569 /* If node's successor is its right child, the following code */\ 570 /* will do the wrong thing for the right child pointer. */\ 571 /* However, it doesn't matter, because the pointer will be */\ 572 /* properly set when the successor is pruned. */\ 573 rbtn_right_set(a_type, a_field, pathp->node, \ 574 rbtn_right_get(a_type, a_field, node)); \ 575 rbtn_color_set(a_type, a_field, node, tred); \ 576 /* The pruned leaf node's child pointers are never accessed */\ 577 /* again, so don't bother setting them to nil. */\ 578 nodep->node = pathp->node; \ 579 pathp->node = node; \ 580 if (nodep == path) { \ 581 rbtree->rbt_root = nodep->node; \ 582 } else { \ 583 if (nodep[-1].cmp < 0) { \ 584 rbtn_left_set(a_type, a_field, nodep[-1].node, \ 585 nodep->node); \ 586 } else { \ 587 rbtn_right_set(a_type, a_field, nodep[-1].node, \ 588 nodep->node); \ 589 } \ 590 } \ 591 } else { \ 592 a_type *left = rbtn_left_get(a_type, a_field, node); \ 593 if (left != &rbtree->rbt_nil) { \ 594 /* node has no successor, but it has a left child. */\ 595 /* Splice node out, without losing the left child. */\ 596 assert(!rbtn_red_get(a_type, a_field, node)); \ 597 assert(rbtn_red_get(a_type, a_field, left)); \ 598 rbtn_black_set(a_type, a_field, left); \ 599 if (pathp == path) { \ 600 rbtree->rbt_root = left; \ 601 } else { \ 602 if (pathp[-1].cmp < 0) { \ 603 rbtn_left_set(a_type, a_field, pathp[-1].node, \ 604 left); \ 605 } else { \ 606 rbtn_right_set(a_type, a_field, pathp[-1].node, \ 607 left); \ 608 } \ 609 } \ 610 return; \ 611 } else if (pathp == path) { \ 612 /* The tree only contained one node. */ \ 613 rbtree->rbt_root = &rbtree->rbt_nil; \ 614 return; \ 615 } \ 616 } \ 617 if (rbtn_red_get(a_type, a_field, pathp->node)) { \ 618 /* Prune red node, which requires no fixup. */ \ 619 assert(pathp[-1].cmp < 0); \ 620 rbtn_left_set(a_type, a_field, pathp[-1].node, \ 621 &rbtree->rbt_nil); \ 622 return; \ 623 } \ 624 /* The node to be pruned is black, so unwind until balance is */\ 625 /* restored. */\ 626 pathp->node = &rbtree->rbt_nil; \ 627 for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ 628 assert(pathp->cmp != 0); \ 629 if (pathp->cmp < 0) { \ 630 rbtn_left_set(a_type, a_field, pathp->node, \ 631 pathp[1].node); \ 632 assert(!rbtn_red_get(a_type, a_field, pathp[1].node)); \ 633 if (rbtn_red_get(a_type, a_field, pathp->node)) { \ 634 a_type *right = rbtn_right_get(a_type, a_field, \ 635 pathp->node); \ 636 a_type *rightleft = rbtn_left_get(a_type, a_field, \ 637 right); \ 638 a_type *tnode; \ 639 if (rbtn_red_get(a_type, a_field, rightleft)) { \ 640 /* In the following diagrams, ||, //, and \\ */\ 641 /* indicate the path to the removed node. */\ 642 /* */\ 643 /* || */\ 644 /* pathp(r) */\ 645 /* // \ */\ 646 /* (b) (b) */\ 647 /* / */\ 648 /* (r) */\ 649 /* */\ 650 rbtn_black_set(a_type, a_field, pathp->node); \ 651 rbtn_rotate_right(a_type, a_field, right, tnode); \ 652 rbtn_right_set(a_type, a_field, pathp->node, tnode);\ 653 rbtn_rotate_left(a_type, a_field, pathp->node, \ 654 tnode); \ 655 } else { \ 656 /* || */\ 657 /* pathp(r) */\ 658 /* // \ */\ 659 /* (b) (b) */\ 660 /* / */\ 661 /* (b) */\ 662 /* */\ 663 rbtn_rotate_left(a_type, a_field, pathp->node, \ 664 tnode); \ 665 } \ 666 /* Balance restored, but rotation modified subtree */\ 667 /* root. */\ 668 assert((uintptr_t)pathp > (uintptr_t)path); \ 669 if (pathp[-1].cmp < 0) { \ 670 rbtn_left_set(a_type, a_field, pathp[-1].node, \ 671 tnode); \ 672 } else { \ 673 rbtn_right_set(a_type, a_field, pathp[-1].node, \ 674 tnode); \ 675 } \ 676 return; \ 677 } else { \ 678 a_type *right = rbtn_right_get(a_type, a_field, \ 679 pathp->node); \ 680 a_type *rightleft = rbtn_left_get(a_type, a_field, \ 681 right); \ 682 if (rbtn_red_get(a_type, a_field, rightleft)) { \ 683 /* || */\ 684 /* pathp(b) */\ 685 /* // \ */\ 686 /* (b) (b) */\ 687 /* / */\ 688 /* (r) */\ 689 a_type *tnode; \ 690 rbtn_black_set(a_type, a_field, rightleft); \ 691 rbtn_rotate_right(a_type, a_field, right, tnode); \ 692 rbtn_right_set(a_type, a_field, pathp->node, tnode);\ 693 rbtn_rotate_left(a_type, a_field, pathp->node, \ 694 tnode); \ 695 /* Balance restored, but rotation modified */\ 696 /* subtree root, which may actually be the tree */\ 697 /* root. */\ 698 if (pathp == path) { \ 699 /* Set root. */ \ 700 rbtree->rbt_root = tnode; \ 701 } else { \ 702 if (pathp[-1].cmp < 0) { \ 703 rbtn_left_set(a_type, a_field, \ 704 pathp[-1].node, tnode); \ 705 } else { \ 706 rbtn_right_set(a_type, a_field, \ 707 pathp[-1].node, tnode); \ 708 } \ 709 } \ 710 return; \ 711 } else { \ 712 /* || */\ 713 /* pathp(b) */\ 714 /* // \ */\ 715 /* (b) (b) */\ 716 /* / */\ 717 /* (b) */\ 718 a_type *tnode; \ 719 rbtn_red_set(a_type, a_field, pathp->node); \ 720 rbtn_rotate_left(a_type, a_field, pathp->node, \ 721 tnode); \ 722 pathp->node = tnode; \ 723 } \ 724 } \ 725 } else { \ 726 a_type *left; \ 727 rbtn_right_set(a_type, a_field, pathp->node, \ 728 pathp[1].node); \ 729 left = rbtn_left_get(a_type, a_field, pathp->node); \ 730 if (rbtn_red_get(a_type, a_field, left)) { \ 731 a_type *tnode; \ 732 a_type *leftright = rbtn_right_get(a_type, a_field, \ 733 left); \ 734 a_type *leftrightleft = rbtn_left_get(a_type, a_field, \ 735 leftright); \ 736 if (rbtn_red_get(a_type, a_field, leftrightleft)) { \ 737 /* || */\ 738 /* pathp(b) */\ 739 /* / \\ */\ 740 /* (r) (b) */\ 741 /* \ */\ 742 /* (b) */\ 743 /* / */\ 744 /* (r) */\ 745 a_type *unode; \ 746 rbtn_black_set(a_type, a_field, leftrightleft); \ 747 rbtn_rotate_right(a_type, a_field, pathp->node, \ 748 unode); \ 749 rbtn_rotate_right(a_type, a_field, pathp->node, \ 750 tnode); \ 751 rbtn_right_set(a_type, a_field, unode, tnode); \ 752 rbtn_rotate_left(a_type, a_field, unode, tnode); \ 753 } else { \ 754 /* || */\ 755 /* pathp(b) */\ 756 /* / \\ */\ 757 /* (r) (b) */\ 758 /* \ */\ 759 /* (b) */\ 760 /* / */\ 761 /* (b) */\ 762 assert(leftright != &rbtree->rbt_nil); \ 763 rbtn_red_set(a_type, a_field, leftright); \ 764 rbtn_rotate_right(a_type, a_field, pathp->node, \ 765 tnode); \ 766 rbtn_black_set(a_type, a_field, tnode); \ 767 } \ 768 /* Balance restored, but rotation modified subtree */\ 769 /* root, which may actually be the tree root. */\ 770 if (pathp == path) { \ 771 /* Set root. */ \ 772 rbtree->rbt_root = tnode; \ 773 } else { \ 774 if (pathp[-1].cmp < 0) { \ 775 rbtn_left_set(a_type, a_field, pathp[-1].node, \ 776 tnode); \ 777 } else { \ 778 rbtn_right_set(a_type, a_field, pathp[-1].node, \ 779 tnode); \ 780 } \ 781 } \ 782 return; \ 783 } else if (rbtn_red_get(a_type, a_field, pathp->node)) { \ 784 a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ 785 if (rbtn_red_get(a_type, a_field, leftleft)) { \ 786 /* || */\ 787 /* pathp(r) */\ 788 /* / \\ */\ 789 /* (b) (b) */\ 790 /* / */\ 791 /* (r) */\ 792 a_type *tnode; \ 793 rbtn_black_set(a_type, a_field, pathp->node); \ 794 rbtn_red_set(a_type, a_field, left); \ 795 rbtn_black_set(a_type, a_field, leftleft); \ 796 rbtn_rotate_right(a_type, a_field, pathp->node, \ 797 tnode); \ 798 /* Balance restored, but rotation modified */\ 799 /* subtree root. */\ 800 assert((uintptr_t)pathp > (uintptr_t)path); \ 801 if (pathp[-1].cmp < 0) { \ 802 rbtn_left_set(a_type, a_field, pathp[-1].node, \ 803 tnode); \ 804 } else { \ 805 rbtn_right_set(a_type, a_field, pathp[-1].node, \ 806 tnode); \ 807 } \ 808 return; \ 809 } else { \ 810 /* || */\ 811 /* pathp(r) */\ 812 /* / \\ */\ 813 /* (b) (b) */\ 814 /* / */\ 815 /* (b) */\ 816 rbtn_red_set(a_type, a_field, left); \ 817 rbtn_black_set(a_type, a_field, pathp->node); \ 818 /* Balance restored. */ \ 819 return; \ 820 } \ 821 } else { \ 822 a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ 823 if (rbtn_red_get(a_type, a_field, leftleft)) { \ 824 /* || */\ 825 /* pathp(b) */\ 826 /* / \\ */\ 827 /* (b) (b) */\ 828 /* / */\ 829 /* (r) */\ 830 a_type *tnode; \ 831 rbtn_black_set(a_type, a_field, leftleft); \ 832 rbtn_rotate_right(a_type, a_field, pathp->node, \ 833 tnode); \ 834 /* Balance restored, but rotation modified */\ 835 /* subtree root, which may actually be the tree */\ 836 /* root. */\ 837 if (pathp == path) { \ 838 /* Set root. */ \ 839 rbtree->rbt_root = tnode; \ 840 } else { \ 841 if (pathp[-1].cmp < 0) { \ 842 rbtn_left_set(a_type, a_field, \ 843 pathp[-1].node, tnode); \ 844 } else { \ 845 rbtn_right_set(a_type, a_field, \ 846 pathp[-1].node, tnode); \ 847 } \ 848 } \ 849 return; \ 850 } else { \ 851 /* || */\ 852 /* pathp(b) */\ 853 /* / \\ */\ 854 /* (b) (b) */\ 855 /* / */\ 856 /* (b) */\ 857 rbtn_red_set(a_type, a_field, left); \ 858 } \ 859 } \ 860 } \ 861 } \ 862 /* Set root. */ \ 863 rbtree->rbt_root = path->node; \ 864 assert(!rbtn_red_get(a_type, a_field, rbtree->rbt_root)); \ 865 } \ 866 a_attr a_type * \ 867 a_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node, \ 868 a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 869 if (node == &rbtree->rbt_nil) { \ 870 return (&rbtree->rbt_nil); \ 871 } else { \ 872 a_type *ret; \ 873 if ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type, \ 874 a_field, node), cb, arg)) != &rbtree->rbt_nil \ 875 || (ret = cb(rbtree, node, arg)) != NULL) { \ 876 return (ret); \ 877 } \ 878 return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ 879 a_field, node), cb, arg)); \ 880 } \ 881 } \ 882 a_attr a_type * \ 883 a_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node, \ 884 a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 885 int cmp = a_cmp(start, node); \ 886 if (cmp < 0) { \ 887 a_type *ret; \ 888 if ((ret = a_prefix##iter_start(rbtree, start, \ 889 rbtn_left_get(a_type, a_field, node), cb, arg)) != \ 890 &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ 891 return (ret); \ 892 } \ 893 return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ 894 a_field, node), cb, arg)); \ 895 } else if (cmp > 0) { \ 896 return (a_prefix##iter_start(rbtree, start, \ 897 rbtn_right_get(a_type, a_field, node), cb, arg)); \ 898 } else { \ 899 a_type *ret; \ 900 if ((ret = cb(rbtree, node, arg)) != NULL) { \ 901 return (ret); \ 902 } \ 903 return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ 904 a_field, node), cb, arg)); \ 905 } \ 906 } \ 907 a_attr a_type * \ 908 a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ 909 a_rbt_type *, a_type *, void *), void *arg) { \ 910 a_type *ret; \ 911 if (start != NULL) { \ 912 ret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root, \ 913 cb, arg); \ 914 } else { \ 915 ret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\ 916 } \ 917 if (ret == &rbtree->rbt_nil) { \ 918 ret = NULL; \ 919 } \ 920 return (ret); \ 921 } \ 922 a_attr a_type * \ 923 a_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node, \ 924 a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 925 if (node == &rbtree->rbt_nil) { \ 926 return (&rbtree->rbt_nil); \ 927 } else { \ 928 a_type *ret; \ 929 if ((ret = a_prefix##reverse_iter_recurse(rbtree, \ 930 rbtn_right_get(a_type, a_field, node), cb, arg)) != \ 931 &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ 932 return (ret); \ 933 } \ 934 return (a_prefix##reverse_iter_recurse(rbtree, \ 935 rbtn_left_get(a_type, a_field, node), cb, arg)); \ 936 } \ 937 } \ 938 a_attr a_type * \ 939 a_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start, \ 940 a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *), \ 941 void *arg) { \ 942 int cmp = a_cmp(start, node); \ 943 if (cmp > 0) { \ 944 a_type *ret; \ 945 if ((ret = a_prefix##reverse_iter_start(rbtree, start, \ 946 rbtn_right_get(a_type, a_field, node), cb, arg)) != \ 947 &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ 948 return (ret); \ 949 } \ 950 return (a_prefix##reverse_iter_recurse(rbtree, \ 951 rbtn_left_get(a_type, a_field, node), cb, arg)); \ 952 } else if (cmp < 0) { \ 953 return (a_prefix##reverse_iter_start(rbtree, start, \ 954 rbtn_left_get(a_type, a_field, node), cb, arg)); \ 955 } else { \ 956 a_type *ret; \ 957 if ((ret = cb(rbtree, node, arg)) != NULL) { \ 958 return (ret); \ 959 } \ 960 return (a_prefix##reverse_iter_recurse(rbtree, \ 961 rbtn_left_get(a_type, a_field, node), cb, arg)); \ 962 } \ 963 } \ 964 a_attr a_type * \ 965 a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ 966 a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 967 a_type *ret; \ 968 if (start != NULL) { \ 969 ret = a_prefix##reverse_iter_start(rbtree, start, \ 970 rbtree->rbt_root, cb, arg); \ 971 } else { \ 972 ret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root, \ 973 cb, arg); \ 974 } \ 975 if (ret == &rbtree->rbt_nil) { \ 976 ret = NULL; \ 977 } \ 978 return (ret); \ 979 } 980 981 #endif /* RB_H_ */ 982