1 /****************************************************************************** 2 * 3 * Copyright (C) 2008 Jason Evans <jasone (at) FreeBSD.org>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice(s), this list of conditions and the following disclaimer 11 * unmodified other than the allowable addition of one or more 12 * copyright notices. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice(s), this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 ****************************************************************************** 31 * 32 * cpp macro implementation of left-leaning red-black trees. 33 * 34 * Usage: 35 * 36 * (Optional.) 37 * #define SIZEOF_PTR ... 38 * #define SIZEOF_PTR_2POW ... 39 * #define RB_NO_C99_VARARRAYS 40 * 41 * (Optional, see assert(3).) 42 * #define NDEBUG 43 * 44 * (Required.) 45 * #include <assert.h> 46 * #include <rb.h> 47 * ... 48 * 49 * All operations are done non-recursively. Parent pointers are not used, and 50 * color bits are stored in the least significant bit of right-child pointers, 51 * thus making node linkage as compact as is possible for red-black trees. 52 * 53 * Some macros use a comparison function pointer, which is expected to have the 54 * following prototype: 55 * 56 * int (a_cmp *)(a_type *a_node, a_type *a_other); 57 * ^^^^^^ 58 * or a_key 59 * 60 * Interpretation of comparision function return values: 61 * 62 * -1 : a_node < a_other 63 * 0 : a_node == a_other 64 * 1 : a_node > a_other 65 * 66 * In all cases, the a_node or a_key macro argument is the first argument to the 67 * comparison function, which makes it possible to write comparison functions 68 * that treat the first argument specially. 69 * 70 ******************************************************************************/ 71 72 #ifndef RB_H_ 73 #define RB_H_ 74 75 #if 0 76 #include <sys/cdefs.h> 77 __FBSDID("$FreeBSD: head/lib/libc/stdlib/rb.h 178995 2008-05-14 18:33:13Z jasone $"); 78 #endif 79 80 /* Node structure. */ 81 #define rb_node(a_type) \ 82 struct { \ 83 a_type *rbn_left; \ 84 a_type *rbn_right_red; \ 85 } 86 87 /* Root structure. */ 88 #define rb_tree(a_type) \ 89 struct { \ 90 a_type *rbt_root; \ 91 a_type rbt_nil; \ 92 } 93 94 /* Left accessors. */ 95 #define rbp_left_get(a_type, a_field, a_node) \ 96 ((a_node)->a_field.rbn_left) 97 #define rbp_left_set(a_type, a_field, a_node, a_left) do { \ 98 (a_node)->a_field.rbn_left = a_left; \ 99 } while (0) 100 101 /* Right accessors. */ 102 #define rbp_right_get(a_type, a_field, a_node) \ 103 ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red) \ 104 & ((ssize_t)-2))) 105 #define rbp_right_set(a_type, a_field, a_node, a_right) do { \ 106 (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \ 107 | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \ 108 } while (0) 109 110 /* Color accessors. */ 111 #define rbp_red_get(a_type, a_field, a_node) \ 112 ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red) \ 113 & ((size_t)1))) 114 #define rbp_color_set(a_type, a_field, a_node, a_red) do { \ 115 (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t) \ 116 (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)) \ 117 | ((ssize_t)a_red)); \ 118 } while (0) 119 #define rbp_red_set(a_type, a_field, a_node) do { \ 120 (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) \ 121 (a_node)->a_field.rbn_right_red) | ((size_t)1)); \ 122 } while (0) 123 #define rbp_black_set(a_type, a_field, a_node) do { \ 124 (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t) \ 125 (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)); \ 126 } while (0) 127 128 /* Node initializer. */ 129 #define rbp_node_new(a_type, a_field, a_tree, a_node) do { \ 130 rbp_left_set(a_type, a_field, (a_node), &(a_tree)->rbt_nil); \ 131 rbp_right_set(a_type, a_field, (a_node), &(a_tree)->rbt_nil); \ 132 rbp_red_set(a_type, a_field, (a_node)); \ 133 } while (0) 134 135 /* Tree initializer. */ 136 #define rb_new(a_type, a_field, a_tree) do { \ 137 (a_tree)->rbt_root = &(a_tree)->rbt_nil; \ 138 rbp_node_new(a_type, a_field, a_tree, &(a_tree)->rbt_nil); \ 139 rbp_black_set(a_type, a_field, &(a_tree)->rbt_nil); \ 140 } while (0) 141 142 /* Tree operations. */ 143 #define rbp_black_height(a_type, a_field, a_tree, r_height) do { \ 144 a_type *rbp_bh_t; \ 145 for (rbp_bh_t = (a_tree)->rbt_root, (r_height) = 0; \ 146 rbp_bh_t != &(a_tree)->rbt_nil; \ 147 rbp_bh_t = rbp_left_get(a_type, a_field, rbp_bh_t)) { \ 148 if (rbp_red_get(a_type, a_field, rbp_bh_t) == false) { \ 149 (r_height)++; \ 150 } \ 151 } \ 152 } while (0) 153 154 #define rbp_first(a_type, a_field, a_tree, a_root, r_node) do { \ 155 for ((r_node) = (a_root); \ 156 rbp_left_get(a_type, a_field, (r_node)) != &(a_tree)->rbt_nil; \ 157 (r_node) = rbp_left_get(a_type, a_field, (r_node))) { \ 158 } \ 159 } while (0) 160 161 #define rbp_last(a_type, a_field, a_tree, a_root, r_node) do { \ 162 for ((r_node) = (a_root); \ 163 rbp_right_get(a_type, a_field, (r_node)) != &(a_tree)->rbt_nil; \ 164 (r_node) = rbp_right_get(a_type, a_field, (r_node))) { \ 165 } \ 166 } while (0) 167 168 #define rbp_next(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \ 169 if (rbp_right_get(a_type, a_field, (a_node)) \ 170 != &(a_tree)->rbt_nil) { \ 171 rbp_first(a_type, a_field, a_tree, rbp_right_get(a_type, \ 172 a_field, (a_node)), (r_node)); \ 173 } else { \ 174 a_type *rbp_n_t = (a_tree)->rbt_root; \ 175 assert(rbp_n_t != &(a_tree)->rbt_nil); \ 176 (r_node) = &(a_tree)->rbt_nil; \ 177 while (true) { \ 178 int rbp_n_cmp = (a_cmp)((a_node), rbp_n_t); \ 179 if (rbp_n_cmp < 0) { \ 180 (r_node) = rbp_n_t; \ 181 rbp_n_t = rbp_left_get(a_type, a_field, rbp_n_t); \ 182 } else if (rbp_n_cmp > 0) { \ 183 rbp_n_t = rbp_right_get(a_type, a_field, rbp_n_t); \ 184 } else { \ 185 break; \ 186 } \ 187 assert(rbp_n_t != &(a_tree)->rbt_nil); \ 188 } \ 189 } \ 190 } while (0) 191 192 #define rbp_prev(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \ 193 if (rbp_left_get(a_type, a_field, (a_node)) != &(a_tree)->rbt_nil) {\ 194 rbp_last(a_type, a_field, a_tree, rbp_left_get(a_type, \ 195 a_field, (a_node)), (r_node)); \ 196 } else { \ 197 a_type *rbp_p_t = (a_tree)->rbt_root; \ 198 assert(rbp_p_t != &(a_tree)->rbt_nil); \ 199 (r_node) = &(a_tree)->rbt_nil; \ 200 while (true) { \ 201 int rbp_p_cmp = (a_cmp)((a_node), rbp_p_t); \ 202 if (rbp_p_cmp < 0) { \ 203 rbp_p_t = rbp_left_get(a_type, a_field, rbp_p_t); \ 204 } else if (rbp_p_cmp > 0) { \ 205 (r_node) = rbp_p_t; \ 206 rbp_p_t = rbp_right_get(a_type, a_field, rbp_p_t); \ 207 } else { \ 208 break; \ 209 } \ 210 assert(rbp_p_t != &(a_tree)->rbt_nil); \ 211 } \ 212 } \ 213 } while (0) 214 215 #define rb_first(a_type, a_field, a_tree, r_node) do { \ 216 rbp_first(a_type, a_field, a_tree, (a_tree)->rbt_root, (r_node)); \ 217 if ((r_node) == &(a_tree)->rbt_nil) { \ 218 (r_node) = NULL; \ 219 } \ 220 } while (0) 221 222 #define rb_last(a_type, a_field, a_tree, r_node) do { \ 223 rbp_last(a_type, a_field, a_tree, (a_tree)->rbt_root, r_node); \ 224 if ((r_node) == &(a_tree)->rbt_nil) { \ 225 (r_node) = NULL; \ 226 } \ 227 } while (0) 228 229 #define rb_next(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \ 230 rbp_next(a_type, a_field, a_cmp, a_tree, (a_node), (r_node)); \ 231 if ((r_node) == &(a_tree)->rbt_nil) { \ 232 (r_node) = NULL; \ 233 } \ 234 } while (0) 235 236 #define rb_prev(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \ 237 rbp_prev(a_type, a_field, a_cmp, a_tree, (a_node), (r_node)); \ 238 if ((r_node) == &(a_tree)->rbt_nil) { \ 239 (r_node) = NULL; \ 240 } \ 241 } while (0) 242 243 #define rb_search(a_type, a_field, a_cmp, a_tree, a_key, r_node) do { \ 244 int rbp_se_cmp; \ 245 (r_node) = (a_tree)->rbt_root; \ 246 while ((r_node) != &(a_tree)->rbt_nil \ 247 && (rbp_se_cmp = (a_cmp)((a_key), (r_node))) != 0) { \ 248 if (rbp_se_cmp < 0) { \ 249 (r_node) = rbp_left_get(a_type, a_field, (r_node)); \ 250 } else { \ 251 (r_node) = rbp_right_get(a_type, a_field, (r_node)); \ 252 } \ 253 } \ 254 if ((r_node) == &(a_tree)->rbt_nil) { \ 255 (r_node) = NULL; \ 256 } \ 257 } while (0) 258 259 /* 260 * Find a match if it exists. Otherwise, find the next greater node, if one 261 * exists. 262 */ 263 #define rb_nsearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) do { \ 264 a_type *rbp_ns_t = (a_tree)->rbt_root; \ 265 (r_node) = NULL; \ 266 while (rbp_ns_t != &(a_tree)->rbt_nil) { \ 267 int rbp_ns_cmp = (a_cmp)((a_key), rbp_ns_t); \ 268 if (rbp_ns_cmp < 0) { \ 269 (r_node) = rbp_ns_t; \ 270 rbp_ns_t = rbp_left_get(a_type, a_field, rbp_ns_t); \ 271 } else if (rbp_ns_cmp > 0) { \ 272 rbp_ns_t = rbp_right_get(a_type, a_field, rbp_ns_t); \ 273 } else { \ 274 (r_node) = rbp_ns_t; \ 275 break; \ 276 } \ 277 } \ 278 } while (0) 279 280 /* 281 * Find a match if it exists. Otherwise, find the previous lesser node, if one 282 * exists. 283 */ 284 #define rb_psearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) do { \ 285 a_type *rbp_ps_t = (a_tree)->rbt_root; \ 286 (r_node) = NULL; \ 287 while (rbp_ps_t != &(a_tree)->rbt_nil) { \ 288 int rbp_ps_cmp = (a_cmp)((a_key), rbp_ps_t); \ 289 if (rbp_ps_cmp < 0) { \ 290 rbp_ps_t = rbp_left_get(a_type, a_field, rbp_ps_t); \ 291 } else if (rbp_ps_cmp > 0) { \ 292 (r_node) = rbp_ps_t; \ 293 rbp_ps_t = rbp_right_get(a_type, a_field, rbp_ps_t); \ 294 } else { \ 295 (r_node) = rbp_ps_t; \ 296 break; \ 297 } \ 298 } \ 299 } while (0) 300 301 #define rbp_rotate_left(a_type, a_field, a_node, r_node) do { \ 302 (r_node) = rbp_right_get(a_type, a_field, (a_node)); \ 303 rbp_right_set(a_type, a_field, (a_node), \ 304 rbp_left_get(a_type, a_field, (r_node))); \ 305 rbp_left_set(a_type, a_field, (r_node), (a_node)); \ 306 } while (0) 307 308 #define rbp_rotate_right(a_type, a_field, a_node, r_node) do { \ 309 (r_node) = rbp_left_get(a_type, a_field, (a_node)); \ 310 rbp_left_set(a_type, a_field, (a_node), \ 311 rbp_right_get(a_type, a_field, (r_node))); \ 312 rbp_right_set(a_type, a_field, (r_node), (a_node)); \ 313 } while (0) 314 315 #define rbp_lean_left(a_type, a_field, a_node, r_node) do { \ 316 bool rbp_ll_red; \ 317 rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \ 318 rbp_ll_red = rbp_red_get(a_type, a_field, (a_node)); \ 319 rbp_color_set(a_type, a_field, (r_node), rbp_ll_red); \ 320 rbp_red_set(a_type, a_field, (a_node)); \ 321 } while (0) 322 323 #define rbp_lean_right(a_type, a_field, a_node, r_node) do { \ 324 bool rbp_lr_red; \ 325 rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \ 326 rbp_lr_red = rbp_red_get(a_type, a_field, (a_node)); \ 327 rbp_color_set(a_type, a_field, (r_node), rbp_lr_red); \ 328 rbp_red_set(a_type, a_field, (a_node)); \ 329 } while (0) 330 331 #define rbp_move_red_left(a_type, a_field, a_node, r_node) do { \ 332 a_type *rbp_mrl_t, *rbp_mrl_u; \ 333 rbp_mrl_t = rbp_left_get(a_type, a_field, (a_node)); \ 334 rbp_red_set(a_type, a_field, rbp_mrl_t); \ 335 rbp_mrl_t = rbp_right_get(a_type, a_field, (a_node)); \ 336 rbp_mrl_u = rbp_left_get(a_type, a_field, rbp_mrl_t); \ 337 if (rbp_red_get(a_type, a_field, rbp_mrl_u)) { \ 338 rbp_rotate_right(a_type, a_field, rbp_mrl_t, rbp_mrl_u); \ 339 rbp_right_set(a_type, a_field, (a_node), rbp_mrl_u); \ 340 rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \ 341 rbp_mrl_t = rbp_right_get(a_type, a_field, (a_node)); \ 342 if (rbp_red_get(a_type, a_field, rbp_mrl_t)) { \ 343 rbp_black_set(a_type, a_field, rbp_mrl_t); \ 344 rbp_red_set(a_type, a_field, (a_node)); \ 345 rbp_rotate_left(a_type, a_field, (a_node), rbp_mrl_t); \ 346 rbp_left_set(a_type, a_field, (r_node), rbp_mrl_t); \ 347 } else { \ 348 rbp_black_set(a_type, a_field, (a_node)); \ 349 } \ 350 } else { \ 351 rbp_red_set(a_type, a_field, (a_node)); \ 352 rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \ 353 } \ 354 } while (0) 355 356 #define rbp_move_red_right(a_type, a_field, a_node, r_node) do { \ 357 a_type *rbp_mrr_t; \ 358 rbp_mrr_t = rbp_left_get(a_type, a_field, (a_node)); \ 359 if (rbp_red_get(a_type, a_field, rbp_mrr_t)) { \ 360 a_type *rbp_mrr_u, *rbp_mrr_v; \ 361 rbp_mrr_u = rbp_right_get(a_type, a_field, rbp_mrr_t); \ 362 rbp_mrr_v = rbp_left_get(a_type, a_field, rbp_mrr_u); \ 363 if (rbp_red_get(a_type, a_field, rbp_mrr_v)) { \ 364 rbp_color_set(a_type, a_field, rbp_mrr_u, \ 365 rbp_red_get(a_type, a_field, (a_node))); \ 366 rbp_black_set(a_type, a_field, rbp_mrr_v); \ 367 rbp_rotate_left(a_type, a_field, rbp_mrr_t, rbp_mrr_u); \ 368 rbp_left_set(a_type, a_field, (a_node), rbp_mrr_u); \ 369 rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \ 370 rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t); \ 371 rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t); \ 372 } else { \ 373 rbp_color_set(a_type, a_field, rbp_mrr_t, \ 374 rbp_red_get(a_type, a_field, (a_node))); \ 375 rbp_red_set(a_type, a_field, rbp_mrr_u); \ 376 rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \ 377 rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t); \ 378 rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t); \ 379 } \ 380 rbp_red_set(a_type, a_field, (a_node)); \ 381 } else { \ 382 rbp_red_set(a_type, a_field, rbp_mrr_t); \ 383 rbp_mrr_t = rbp_left_get(a_type, a_field, rbp_mrr_t); \ 384 if (rbp_red_get(a_type, a_field, rbp_mrr_t)) { \ 385 rbp_black_set(a_type, a_field, rbp_mrr_t); \ 386 rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \ 387 rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t); \ 388 rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t); \ 389 } else { \ 390 rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \ 391 } \ 392 } \ 393 } while (0) 394 395 #define rb_insert(a_type, a_field, a_cmp, a_tree, a_node) do { \ 396 a_type rbp_i_s; \ 397 a_type *rbp_i_g, *rbp_i_p, *rbp_i_c, *rbp_i_t, *rbp_i_u; \ 398 int rbp_i_cmp = 0; \ 399 rbp_i_g = &(a_tree)->rbt_nil; \ 400 rbp_left_set(a_type, a_field, &rbp_i_s, (a_tree)->rbt_root); \ 401 rbp_right_set(a_type, a_field, &rbp_i_s, &(a_tree)->rbt_nil); \ 402 rbp_black_set(a_type, a_field, &rbp_i_s); \ 403 rbp_i_p = &rbp_i_s; \ 404 rbp_i_c = (a_tree)->rbt_root; \ 405 /* Iteratively search down the tree for the insertion point, */\ 406 /* splitting 4-nodes as they are encountered. At the end of each */\ 407 /* iteration, rbp_i_g->rbp_i_p->rbp_i_c is a 3-level path down */\ 408 /* the tree, assuming a sufficiently deep tree. */\ 409 while (rbp_i_c != &(a_tree)->rbt_nil) { \ 410 rbp_i_t = rbp_left_get(a_type, a_field, rbp_i_c); \ 411 rbp_i_u = rbp_left_get(a_type, a_field, rbp_i_t); \ 412 if (rbp_red_get(a_type, a_field, rbp_i_t) \ 413 && rbp_red_get(a_type, a_field, rbp_i_u)) { \ 414 /* rbp_i_c is the top of a logical 4-node, so split it. */\ 415 /* This iteration does not move down the tree, due to the */\ 416 /* disruptiveness of node splitting. */\ 417 /* */\ 418 /* Rotate right. */\ 419 rbp_rotate_right(a_type, a_field, rbp_i_c, rbp_i_t); \ 420 /* Pass red links up one level. */\ 421 rbp_i_u = rbp_left_get(a_type, a_field, rbp_i_t); \ 422 rbp_black_set(a_type, a_field, rbp_i_u); \ 423 if (rbp_left_get(a_type, a_field, rbp_i_p) == rbp_i_c) { \ 424 rbp_left_set(a_type, a_field, rbp_i_p, rbp_i_t); \ 425 rbp_i_c = rbp_i_t; \ 426 } else { \ 427 /* rbp_i_c was the right child of rbp_i_p, so rotate */\ 428 /* left in order to maintain the left-leaning */\ 429 /* invariant. */\ 430 assert(rbp_right_get(a_type, a_field, rbp_i_p) \ 431 == rbp_i_c); \ 432 rbp_right_set(a_type, a_field, rbp_i_p, rbp_i_t); \ 433 rbp_lean_left(a_type, a_field, rbp_i_p, rbp_i_u); \ 434 if (rbp_left_get(a_type, a_field, rbp_i_g) == rbp_i_p) {\ 435 rbp_left_set(a_type, a_field, rbp_i_g, rbp_i_u); \ 436 } else { \ 437 assert(rbp_right_get(a_type, a_field, rbp_i_g) \ 438 == rbp_i_p); \ 439 rbp_right_set(a_type, a_field, rbp_i_g, rbp_i_u); \ 440 } \ 441 rbp_i_p = rbp_i_u; \ 442 rbp_i_cmp = (a_cmp)((a_node), rbp_i_p); \ 443 if (rbp_i_cmp < 0) { \ 444 rbp_i_c = rbp_left_get(a_type, a_field, rbp_i_p); \ 445 } else { \ 446 assert(rbp_i_cmp > 0); \ 447 rbp_i_c = rbp_right_get(a_type, a_field, rbp_i_p); \ 448 } \ 449 continue; \ 450 } \ 451 } \ 452 rbp_i_g = rbp_i_p; \ 453 rbp_i_p = rbp_i_c; \ 454 rbp_i_cmp = (a_cmp)((a_node), rbp_i_c); \ 455 if (rbp_i_cmp < 0) { \ 456 rbp_i_c = rbp_left_get(a_type, a_field, rbp_i_c); \ 457 } else { \ 458 assert(rbp_i_cmp > 0); \ 459 rbp_i_c = rbp_right_get(a_type, a_field, rbp_i_c); \ 460 } \ 461 } \ 462 /* rbp_i_p now refers to the node under which to insert. */\ 463 rbp_node_new(a_type, a_field, a_tree, (a_node)); \ 464 if (rbp_i_cmp > 0) { \ 465 rbp_right_set(a_type, a_field, rbp_i_p, (a_node)); \ 466 rbp_lean_left(a_type, a_field, rbp_i_p, rbp_i_t); \ 467 if (rbp_left_get(a_type, a_field, rbp_i_g) == rbp_i_p) { \ 468 rbp_left_set(a_type, a_field, rbp_i_g, rbp_i_t); \ 469 } else if (rbp_right_get(a_type, a_field, rbp_i_g) == rbp_i_p) {\ 470 rbp_right_set(a_type, a_field, rbp_i_g, rbp_i_t); \ 471 } \ 472 } else { \ 473 rbp_left_set(a_type, a_field, rbp_i_p, (a_node)); \ 474 } \ 475 /* Update the root and make sure that it is black. */\ 476 (a_tree)->rbt_root = rbp_left_get(a_type, a_field, &rbp_i_s); \ 477 rbp_black_set(a_type, a_field, (a_tree)->rbt_root); \ 478 } while (0) 479 480 #define rb_remove(a_type, a_field, a_cmp, a_tree, a_node) do { \ 481 a_type rbp_r_s; \ 482 a_type *rbp_r_p, *rbp_r_c, *rbp_r_xp, *rbp_r_t, *rbp_r_u; \ 483 int rbp_r_cmp; \ 484 rbp_left_set(a_type, a_field, &rbp_r_s, (a_tree)->rbt_root); \ 485 rbp_right_set(a_type, a_field, &rbp_r_s, &(a_tree)->rbt_nil); \ 486 rbp_black_set(a_type, a_field, &rbp_r_s); \ 487 rbp_r_p = &rbp_r_s; \ 488 rbp_r_c = (a_tree)->rbt_root; \ 489 rbp_r_xp = &(a_tree)->rbt_nil; \ 490 /* Iterate down the tree, but always transform 2-nodes to 3- or */\ 491 /* 4-nodes in order to maintain the invariant that the current */\ 492 /* node is not a 2-node. This allows simple deletion once a leaf */\ 493 /* is reached. Handle the root specially though, since there may */\ 494 /* be no way to convert it from a 2-node to a 3-node. */\ 495 rbp_r_cmp = (a_cmp)((a_node), rbp_r_c); \ 496 if (rbp_r_cmp < 0) { \ 497 rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c); \ 498 rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \ 499 if (rbp_red_get(a_type, a_field, rbp_r_t) == false \ 500 && rbp_red_get(a_type, a_field, rbp_r_u) == false) { \ 501 /* Apply standard transform to prepare for left move. */\ 502 rbp_move_red_left(a_type, a_field, rbp_r_c, rbp_r_t); \ 503 rbp_black_set(a_type, a_field, rbp_r_t); \ 504 rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t); \ 505 rbp_r_c = rbp_r_t; \ 506 } else { \ 507 /* Move left. */\ 508 rbp_r_p = rbp_r_c; \ 509 rbp_r_c = rbp_left_get(a_type, a_field, rbp_r_c); \ 510 } \ 511 } else { \ 512 if (rbp_r_cmp == 0) { \ 513 assert((a_node) == rbp_r_c); \ 514 if (rbp_right_get(a_type, a_field, rbp_r_c) \ 515 == &(a_tree)->rbt_nil) { \ 516 /* Delete root node (which is also a leaf node). */\ 517 if (rbp_left_get(a_type, a_field, rbp_r_c) \ 518 != &(a_tree)->rbt_nil) { \ 519 rbp_lean_right(a_type, a_field, rbp_r_c, rbp_r_t); \ 520 rbp_right_set(a_type, a_field, rbp_r_t, \ 521 &(a_tree)->rbt_nil); \ 522 } else { \ 523 rbp_r_t = &(a_tree)->rbt_nil; \ 524 } \ 525 rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t); \ 526 } else { \ 527 /* This is the node we want to delete, but we will */\ 528 /* instead swap it with its successor and delete the */\ 529 /* successor. Record enough information to do the */\ 530 /* swap later. rbp_r_xp is the a_node's parent. */\ 531 rbp_r_xp = rbp_r_p; \ 532 rbp_r_cmp = 1; /* Note that deletion is incomplete. */\ 533 } \ 534 } \ 535 if (rbp_r_cmp == 1) { \ 536 if (rbp_red_get(a_type, a_field, rbp_left_get(a_type, \ 537 a_field, rbp_right_get(a_type, a_field, rbp_r_c))) \ 538 == false) { \ 539 rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c); \ 540 if (rbp_red_get(a_type, a_field, rbp_r_t)) { \ 541 /* Standard transform. */\ 542 rbp_move_red_right(a_type, a_field, rbp_r_c, \ 543 rbp_r_t); \ 544 } else { \ 545 /* Root-specific transform. */\ 546 rbp_red_set(a_type, a_field, rbp_r_c); \ 547 rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \ 548 if (rbp_red_get(a_type, a_field, rbp_r_u)) { \ 549 rbp_black_set(a_type, a_field, rbp_r_u); \ 550 rbp_rotate_right(a_type, a_field, rbp_r_c, \ 551 rbp_r_t); \ 552 rbp_rotate_left(a_type, a_field, rbp_r_c, \ 553 rbp_r_u); \ 554 rbp_right_set(a_type, a_field, rbp_r_t, \ 555 rbp_r_u); \ 556 } else { \ 557 rbp_red_set(a_type, a_field, rbp_r_t); \ 558 rbp_rotate_left(a_type, a_field, rbp_r_c, \ 559 rbp_r_t); \ 560 } \ 561 } \ 562 rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t); \ 563 rbp_r_c = rbp_r_t; \ 564 } else { \ 565 /* Move right. */\ 566 rbp_r_p = rbp_r_c; \ 567 rbp_r_c = rbp_right_get(a_type, a_field, rbp_r_c); \ 568 } \ 569 } \ 570 } \ 571 if (rbp_r_cmp != 0) { \ 572 while (true) { \ 573 assert(rbp_r_p != &(a_tree)->rbt_nil); \ 574 rbp_r_cmp = (a_cmp)((a_node), rbp_r_c); \ 575 if (rbp_r_cmp < 0) { \ 576 rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c); \ 577 if (rbp_r_t == &(a_tree)->rbt_nil) { \ 578 /* rbp_r_c now refers to the successor node to */\ 579 /* relocate, and rbp_r_xp/a_node refer to the */\ 580 /* context for the relocation. */\ 581 if (rbp_left_get(a_type, a_field, rbp_r_xp) \ 582 == (a_node)) { \ 583 rbp_left_set(a_type, a_field, rbp_r_xp, \ 584 rbp_r_c); \ 585 } else { \ 586 assert(rbp_right_get(a_type, a_field, \ 587 rbp_r_xp) == (a_node)); \ 588 rbp_right_set(a_type, a_field, rbp_r_xp, \ 589 rbp_r_c); \ 590 } \ 591 rbp_left_set(a_type, a_field, rbp_r_c, \ 592 rbp_left_get(a_type, a_field, (a_node))); \ 593 rbp_right_set(a_type, a_field, rbp_r_c, \ 594 rbp_right_get(a_type, a_field, (a_node))); \ 595 rbp_color_set(a_type, a_field, rbp_r_c, \ 596 rbp_red_get(a_type, a_field, (a_node))); \ 597 if (rbp_left_get(a_type, a_field, rbp_r_p) \ 598 == rbp_r_c) { \ 599 rbp_left_set(a_type, a_field, rbp_r_p, \ 600 &(a_tree)->rbt_nil); \ 601 } else { \ 602 assert(rbp_right_get(a_type, a_field, rbp_r_p) \ 603 == rbp_r_c); \ 604 rbp_right_set(a_type, a_field, rbp_r_p, \ 605 &(a_tree)->rbt_nil); \ 606 } \ 607 break; \ 608 } \ 609 rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \ 610 if (rbp_red_get(a_type, a_field, rbp_r_t) == false \ 611 && rbp_red_get(a_type, a_field, rbp_r_u) == false) { \ 612 rbp_move_red_left(a_type, a_field, rbp_r_c, \ 613 rbp_r_t); \ 614 if (rbp_left_get(a_type, a_field, rbp_r_p) \ 615 == rbp_r_c) { \ 616 rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);\ 617 } else { \ 618 rbp_right_set(a_type, a_field, rbp_r_p, \ 619 rbp_r_t); \ 620 } \ 621 rbp_r_c = rbp_r_t; \ 622 } else { \ 623 rbp_r_p = rbp_r_c; \ 624 rbp_r_c = rbp_left_get(a_type, a_field, rbp_r_c); \ 625 } \ 626 } else { \ 627 /* Check whether to delete this node (it has to be */\ 628 /* the correct node and a leaf node). */\ 629 if (rbp_r_cmp == 0) { \ 630 assert((a_node) == rbp_r_c); \ 631 if (rbp_right_get(a_type, a_field, rbp_r_c) \ 632 == &(a_tree)->rbt_nil) { \ 633 /* Delete leaf node. */\ 634 if (rbp_left_get(a_type, a_field, rbp_r_c) \ 635 != &(a_tree)->rbt_nil) { \ 636 rbp_lean_right(a_type, a_field, rbp_r_c, \ 637 rbp_r_t); \ 638 rbp_right_set(a_type, a_field, rbp_r_t, \ 639 &(a_tree)->rbt_nil); \ 640 } else { \ 641 rbp_r_t = &(a_tree)->rbt_nil; \ 642 } \ 643 if (rbp_left_get(a_type, a_field, rbp_r_p) \ 644 == rbp_r_c) { \ 645 rbp_left_set(a_type, a_field, rbp_r_p, \ 646 rbp_r_t); \ 647 } else { \ 648 rbp_right_set(a_type, a_field, rbp_r_p, \ 649 rbp_r_t); \ 650 } \ 651 break; \ 652 } else { \ 653 /* This is the node we want to delete, but we */\ 654 /* will instead swap it with its successor */\ 655 /* and delete the successor. Record enough */\ 656 /* information to do the swap later. */\ 657 /* rbp_r_xp is a_node's parent. */\ 658 rbp_r_xp = rbp_r_p; \ 659 } \ 660 } \ 661 rbp_r_t = rbp_right_get(a_type, a_field, rbp_r_c); \ 662 rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \ 663 if (rbp_red_get(a_type, a_field, rbp_r_u) == false) { \ 664 rbp_move_red_right(a_type, a_field, rbp_r_c, \ 665 rbp_r_t); \ 666 if (rbp_left_get(a_type, a_field, rbp_r_p) \ 667 == rbp_r_c) { \ 668 rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);\ 669 } else { \ 670 rbp_right_set(a_type, a_field, rbp_r_p, \ 671 rbp_r_t); \ 672 } \ 673 rbp_r_c = rbp_r_t; \ 674 } else { \ 675 rbp_r_p = rbp_r_c; \ 676 rbp_r_c = rbp_right_get(a_type, a_field, rbp_r_c); \ 677 } \ 678 } \ 679 } \ 680 } \ 681 /* Update root. */\ 682 (a_tree)->rbt_root = rbp_left_get(a_type, a_field, &rbp_r_s); \ 683 } while (0) 684 685 /* 686 * The rb_wrap() macro provides a convenient way to wrap functions around the 687 * cpp macros. The main benefits of wrapping are that 1) repeated macro 688 * expansion can cause code bloat, especially for rb_{insert,remove)(), and 689 * 2) type, linkage, comparison functions, etc. need not be specified at every 690 * call point. 691 */ 692 693 #define rb_wrap(a_attr, a_prefix, a_tree_type, a_type, a_field, a_cmp) \ 694 a_attr void \ 695 a_prefix##new(a_tree_type *tree) { \ 696 rb_new(a_type, a_field, tree); \ 697 } \ 698 a_attr a_type * \ 699 a_prefix##first(a_tree_type *tree) { \ 700 a_type *ret; \ 701 rb_first(a_type, a_field, tree, ret); \ 702 return (ret); \ 703 } \ 704 a_attr a_type * \ 705 a_prefix##last(a_tree_type *tree) { \ 706 a_type *ret; \ 707 rb_last(a_type, a_field, tree, ret); \ 708 return (ret); \ 709 } \ 710 a_attr a_type * \ 711 a_prefix##next(a_tree_type *tree, a_type *node) { \ 712 a_type *ret; \ 713 rb_next(a_type, a_field, a_cmp, tree, node, ret); \ 714 return (ret); \ 715 } \ 716 a_attr a_type * \ 717 a_prefix##prev(a_tree_type *tree, a_type *node) { \ 718 a_type *ret; \ 719 rb_prev(a_type, a_field, a_cmp, tree, node, ret); \ 720 return (ret); \ 721 } \ 722 a_attr a_type * \ 723 a_prefix##search(a_tree_type *tree, a_type *key) { \ 724 a_type *ret; \ 725 rb_search(a_type, a_field, a_cmp, tree, key, ret); \ 726 return (ret); \ 727 } \ 728 a_attr a_type * \ 729 a_prefix##nsearch(a_tree_type *tree, a_type *key) { \ 730 a_type *ret; \ 731 rb_nsearch(a_type, a_field, a_cmp, tree, key, ret); \ 732 return (ret); \ 733 } \ 734 a_attr a_type * \ 735 a_prefix##psearch(a_tree_type *tree, a_type *key) { \ 736 a_type *ret; \ 737 rb_psearch(a_type, a_field, a_cmp, tree, key, ret); \ 738 return (ret); \ 739 } \ 740 a_attr void \ 741 a_prefix##insert(a_tree_type *tree, a_type *node) { \ 742 rb_insert(a_type, a_field, a_cmp, tree, node); \ 743 } \ 744 a_attr void \ 745 a_prefix##remove(a_tree_type *tree, a_type *node) { \ 746 rb_remove(a_type, a_field, a_cmp, tree, node); \ 747 } 748 749 /* 750 * The iterators simulate recursion via an array of pointers that store the 751 * current path. This is critical to performance, since a series of calls to 752 * rb_{next,prev}() would require time proportional to (n lg n), whereas this 753 * implementation only requires time proportional to (n). 754 * 755 * Since the iterators cache a path down the tree, any tree modification may 756 * cause the cached path to become invalid. In order to continue iteration, 757 * use something like the following sequence: 758 * 759 * { 760 * a_type *node, *tnode; 761 * 762 * rb_foreach_begin(a_type, a_field, a_tree, node) { 763 * ... 764 * rb_next(a_type, a_field, a_cmp, a_tree, node, tnode); 765 * rb_remove(a_type, a_field, a_cmp, a_tree, node); 766 * rb_foreach_next(a_type, a_field, a_cmp, a_tree, tnode); 767 * ... 768 * } rb_foreach_end(a_type, a_field, a_tree, node) 769 * } 770 * 771 * Note that this idiom is not advised if every iteration modifies the tree, 772 * since in that case there is no algorithmic complexity improvement over a 773 * series of rb_{next,prev}() calls, thus making the setup overhead wasted 774 * effort. 775 */ 776 777 #ifdef RB_NO_C99_VARARRAYS 778 /* 779 * Avoid using variable-length arrays, at the cost of using more stack space. 780 * Size the path arrays such that they are always large enough, even if a 781 * tree consumes all of memory. Since each node must contain a minimum of 782 * two pointers, there can never be more nodes than: 783 * 784 * 1 << ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)) 785 * 786 * Since the depth of a tree is limited to 3*lg(#nodes), the maximum depth 787 * is: 788 * 789 * (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1))) 790 * 791 * This works out to a maximum depth of 87 and 180 for 32- and 64-bit 792 * systems, respectively (approximatly 348 and 1440 bytes, respectively). 793 */ 794 # define rbp_compute_f_height(a_type, a_field, a_tree) 795 # define rbp_f_height (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1))) 796 # define rbp_compute_fr_height(a_type, a_field, a_tree) 797 # define rbp_fr_height (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1))) 798 #else 799 # define rbp_compute_f_height(a_type, a_field, a_tree) \ 800 /* Compute the maximum possible tree depth (3X the black height). */\ 801 unsigned rbp_f_height; \ 802 rbp_black_height(a_type, a_field, a_tree, rbp_f_height); \ 803 rbp_f_height *= 3; 804 # define rbp_compute_fr_height(a_type, a_field, a_tree) \ 805 /* Compute the maximum possible tree depth (3X the black height). */\ 806 unsigned rbp_fr_height; \ 807 rbp_black_height(a_type, a_field, a_tree, rbp_fr_height); \ 808 rbp_fr_height *= 3; 809 #endif 810 811 #define rb_foreach_begin(a_type, a_field, a_tree, a_var) { \ 812 rbp_compute_f_height(a_type, a_field, a_tree) \ 813 { \ 814 /* Initialize the path to contain the left spine. */\ 815 a_type *rbp_f_path[rbp_f_height]; \ 816 a_type *rbp_f_node; \ 817 bool rbp_f_synced = false; \ 818 unsigned rbp_f_depth = 0; \ 819 if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \ 820 rbp_f_path[rbp_f_depth] = (a_tree)->rbt_root; \ 821 rbp_f_depth++; \ 822 while ((rbp_f_node = rbp_left_get(a_type, a_field, \ 823 rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) { \ 824 rbp_f_path[rbp_f_depth] = rbp_f_node; \ 825 rbp_f_depth++; \ 826 } \ 827 } \ 828 /* While the path is non-empty, iterate. */\ 829 while (rbp_f_depth > 0) { \ 830 (a_var) = rbp_f_path[rbp_f_depth-1]; 831 832 /* Only use if modifying the tree during iteration. */ 833 #define rb_foreach_next(a_type, a_field, a_cmp, a_tree, a_node) \ 834 /* Re-initialize the path to contain the path to a_node. */\ 835 rbp_f_depth = 0; \ 836 if (a_node != NULL) { \ 837 if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \ 838 rbp_f_path[rbp_f_depth] = (a_tree)->rbt_root; \ 839 rbp_f_depth++; \ 840 rbp_f_node = rbp_f_path[0]; \ 841 while (true) { \ 842 int rbp_f_cmp = (a_cmp)((a_node), \ 843 rbp_f_path[rbp_f_depth-1]); \ 844 if (rbp_f_cmp < 0) { \ 845 rbp_f_node = rbp_left_get(a_type, a_field, \ 846 rbp_f_path[rbp_f_depth-1]); \ 847 } else if (rbp_f_cmp > 0) { \ 848 rbp_f_node = rbp_right_get(a_type, a_field, \ 849 rbp_f_path[rbp_f_depth-1]); \ 850 } else { \ 851 break; \ 852 } \ 853 assert(rbp_f_node != &(a_tree)->rbt_nil); \ 854 rbp_f_path[rbp_f_depth] = rbp_f_node; \ 855 rbp_f_depth++; \ 856 } \ 857 } \ 858 } \ 859 rbp_f_synced = true; 860 861 #define rb_foreach_end(a_type, a_field, a_tree, a_var) \ 862 if (rbp_f_synced) { \ 863 rbp_f_synced = false; \ 864 continue; \ 865 } \ 866 /* Find the successor. */\ 867 if ((rbp_f_node = rbp_right_get(a_type, a_field, \ 868 rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) { \ 869 /* The successor is the left-most node in the right */\ 870 /* subtree. */\ 871 rbp_f_path[rbp_f_depth] = rbp_f_node; \ 872 rbp_f_depth++; \ 873 while ((rbp_f_node = rbp_left_get(a_type, a_field, \ 874 rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) { \ 875 rbp_f_path[rbp_f_depth] = rbp_f_node; \ 876 rbp_f_depth++; \ 877 } \ 878 } else { \ 879 /* The successor is above the current node. Unwind */\ 880 /* until a left-leaning edge is removed from the */\ 881 /* path, or the path is empty. */\ 882 for (rbp_f_depth--; rbp_f_depth > 0; rbp_f_depth--) { \ 883 if (rbp_left_get(a_type, a_field, \ 884 rbp_f_path[rbp_f_depth-1]) \ 885 == rbp_f_path[rbp_f_depth]) { \ 886 break; \ 887 } \ 888 } \ 889 } \ 890 } \ 891 } \ 892 } 893 894 #define rb_foreach_reverse_begin(a_type, a_field, a_tree, a_var) { \ 895 rbp_compute_fr_height(a_type, a_field, a_tree) \ 896 { \ 897 /* Initialize the path to contain the right spine. */\ 898 a_type *rbp_fr_path[rbp_fr_height]; \ 899 a_type *rbp_fr_node; \ 900 bool rbp_fr_synced = false; \ 901 unsigned rbp_fr_depth = 0; \ 902 if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \ 903 rbp_fr_path[rbp_fr_depth] = (a_tree)->rbt_root; \ 904 rbp_fr_depth++; \ 905 while ((rbp_fr_node = rbp_right_get(a_type, a_field, \ 906 rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) { \ 907 rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \ 908 rbp_fr_depth++; \ 909 } \ 910 } \ 911 /* While the path is non-empty, iterate. */\ 912 while (rbp_fr_depth > 0) { \ 913 (a_var) = rbp_fr_path[rbp_fr_depth-1]; 914 915 /* Only use if modifying the tree during iteration. */ 916 #define rb_foreach_reverse_prev(a_type, a_field, a_cmp, a_tree, a_node) \ 917 /* Re-initialize the path to contain the path to a_node. */\ 918 rbp_fr_depth = 0; \ 919 if (a_node != NULL) { \ 920 if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \ 921 rbp_fr_path[rbp_fr_depth] = (a_tree)->rbt_root; \ 922 rbp_fr_depth++; \ 923 rbp_fr_node = rbp_fr_path[0]; \ 924 while (true) { \ 925 int rbp_fr_cmp = (a_cmp)((a_node), \ 926 rbp_fr_path[rbp_fr_depth-1]); \ 927 if (rbp_fr_cmp < 0) { \ 928 rbp_fr_node = rbp_left_get(a_type, a_field, \ 929 rbp_fr_path[rbp_fr_depth-1]); \ 930 } else if (rbp_fr_cmp > 0) { \ 931 rbp_fr_node = rbp_right_get(a_type, a_field,\ 932 rbp_fr_path[rbp_fr_depth-1]); \ 933 } else { \ 934 break; \ 935 } \ 936 assert(rbp_fr_node != &(a_tree)->rbt_nil); \ 937 rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \ 938 rbp_fr_depth++; \ 939 } \ 940 } \ 941 } \ 942 rbp_fr_synced = true; 943 944 #define rb_foreach_reverse_end(a_type, a_field, a_tree, a_var) \ 945 if (rbp_fr_synced) { \ 946 rbp_fr_synced = false; \ 947 continue; \ 948 } \ 949 if (rbp_fr_depth == 0) { \ 950 /* rb_foreach_reverse_sync() was called with a NULL */\ 951 /* a_node. */\ 952 break; \ 953 } \ 954 /* Find the predecessor. */\ 955 if ((rbp_fr_node = rbp_left_get(a_type, a_field, \ 956 rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) { \ 957 /* The predecessor is the right-most node in the left */\ 958 /* subtree. */\ 959 rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \ 960 rbp_fr_depth++; \ 961 while ((rbp_fr_node = rbp_right_get(a_type, a_field, \ 962 rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) {\ 963 rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \ 964 rbp_fr_depth++; \ 965 } \ 966 } else { \ 967 /* The predecessor is above the current node. Unwind */\ 968 /* until a right-leaning edge is removed from the */\ 969 /* path, or the path is empty. */\ 970 for (rbp_fr_depth--; rbp_fr_depth > 0; rbp_fr_depth--) {\ 971 if (rbp_right_get(a_type, a_field, \ 972 rbp_fr_path[rbp_fr_depth-1]) \ 973 == rbp_fr_path[rbp_fr_depth]) { \ 974 break; \ 975 } \ 976 } \ 977 } \ 978 } \ 979 } \ 980 } 981 982 #endif /* RB_H_ */ 983 984