OLD | NEW |
(Empty) | |
| 1 /****************************************************************************** |
| 2 * |
| 3 * Copyright (C) 2008 Jason Evans <jasone@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 |
OLD | NEW |