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