1 1.1 christos /*- 2 1.1 christos * Copyright 2002 Niels Provos <provos (at) citi.umich.edu> 3 1.1 christos * All rights reserved. 4 1.1 christos * 5 1.1 christos * Redistribution and use in source and binary forms, with or without 6 1.1 christos * modification, are permitted provided that the following conditions 7 1.1 christos * are met: 8 1.1 christos * 1. Redistributions of source code must retain the above copyright 9 1.1 christos * notice, this list of conditions and the following disclaimer. 10 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 11 1.1 christos * notice, this list of conditions and the following disclaimer in the 12 1.1 christos * documentation and/or other materials provided with the distribution. 13 1.1 christos * 14 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 1.1 christos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 1.1 christos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 1.1 christos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 1.1 christos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 1.1 christos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 1.1 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 1.1 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 1.1 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 1.1 christos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 1.1 christos */ 25 1.1 christos 26 1.1 christos #ifndef UV_TREE_H_ 27 1.1 christos #define UV_TREE_H_ 28 1.1 christos 29 1.1 christos #ifndef UV__UNUSED 30 1.1 christos # if __GNUC__ 31 1.1 christos # define UV__UNUSED __attribute__((unused)) 32 1.1 christos # else 33 1.1 christos # define UV__UNUSED 34 1.1 christos # endif 35 1.1 christos #endif 36 1.1 christos 37 1.1 christos /* 38 1.1.1.3 christos * This file defines data structures for red-black trees. 39 1.1 christos * A red-black tree is a binary search tree with the node color as an 40 1.1 christos * extra attribute. It fulfills a set of conditions: 41 1.1 christos * - every search path from the root to a leaf consists of the 42 1.1 christos * same number of black nodes, 43 1.1 christos * - each red node (except for the root) has a black parent, 44 1.1 christos * - each leaf node is black. 45 1.1 christos * 46 1.1 christos * Every operation on a red-black tree is bounded as O(lg n). 47 1.1 christos * The maximum height of a red-black tree is 2lg (n+1). 48 1.1 christos */ 49 1.1 christos 50 1.1 christos /* Macros that define a red-black tree */ 51 1.1 christos #define RB_HEAD(name, type) \ 52 1.1 christos struct name { \ 53 1.1 christos struct type *rbh_root; /* root of the tree */ \ 54 1.1 christos } 55 1.1 christos 56 1.1 christos #define RB_INITIALIZER(root) \ 57 1.1 christos { NULL } 58 1.1 christos 59 1.1 christos #define RB_INIT(root) do { \ 60 1.1 christos (root)->rbh_root = NULL; \ 61 1.1 christos } while (/*CONSTCOND*/ 0) 62 1.1 christos 63 1.1 christos #define RB_BLACK 0 64 1.1 christos #define RB_RED 1 65 1.1 christos #define RB_ENTRY(type) \ 66 1.1 christos struct { \ 67 1.1 christos struct type *rbe_left; /* left element */ \ 68 1.1 christos struct type *rbe_right; /* right element */ \ 69 1.1 christos struct type *rbe_parent; /* parent element */ \ 70 1.1 christos int rbe_color; /* node color */ \ 71 1.1 christos } 72 1.1 christos 73 1.1 christos #define RB_LEFT(elm, field) (elm)->field.rbe_left 74 1.1 christos #define RB_RIGHT(elm, field) (elm)->field.rbe_right 75 1.1 christos #define RB_PARENT(elm, field) (elm)->field.rbe_parent 76 1.1 christos #define RB_COLOR(elm, field) (elm)->field.rbe_color 77 1.1 christos #define RB_ROOT(head) (head)->rbh_root 78 1.1 christos #define RB_EMPTY(head) (RB_ROOT(head) == NULL) 79 1.1 christos 80 1.1 christos #define RB_SET(elm, parent, field) do { \ 81 1.1 christos RB_PARENT(elm, field) = parent; \ 82 1.1 christos RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ 83 1.1 christos RB_COLOR(elm, field) = RB_RED; \ 84 1.1 christos } while (/*CONSTCOND*/ 0) 85 1.1 christos 86 1.1 christos #define RB_SET_BLACKRED(black, red, field) do { \ 87 1.1 christos RB_COLOR(black, field) = RB_BLACK; \ 88 1.1 christos RB_COLOR(red, field) = RB_RED; \ 89 1.1 christos } while (/*CONSTCOND*/ 0) 90 1.1 christos 91 1.1 christos #ifndef RB_AUGMENT 92 1.1 christos #define RB_AUGMENT(x) do {} while (0) 93 1.1 christos #endif 94 1.1 christos 95 1.1 christos #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ 96 1.1 christos (tmp) = RB_RIGHT(elm, field); \ 97 1.1 christos if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ 98 1.1 christos RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ 99 1.1 christos } \ 100 1.1 christos RB_AUGMENT(elm); \ 101 1.1 christos if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ 102 1.1 christos if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ 103 1.1 christos RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ 104 1.1 christos else \ 105 1.1 christos RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ 106 1.1 christos } else \ 107 1.1 christos (head)->rbh_root = (tmp); \ 108 1.1 christos RB_LEFT(tmp, field) = (elm); \ 109 1.1 christos RB_PARENT(elm, field) = (tmp); \ 110 1.1 christos RB_AUGMENT(tmp); \ 111 1.1 christos if ((RB_PARENT(tmp, field))) \ 112 1.1 christos RB_AUGMENT(RB_PARENT(tmp, field)); \ 113 1.1 christos } while (/*CONSTCOND*/ 0) 114 1.1 christos 115 1.1 christos #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ 116 1.1 christos (tmp) = RB_LEFT(elm, field); \ 117 1.1 christos if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ 118 1.1 christos RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ 119 1.1 christos } \ 120 1.1 christos RB_AUGMENT(elm); \ 121 1.1 christos if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ 122 1.1 christos if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ 123 1.1 christos RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ 124 1.1 christos else \ 125 1.1 christos RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ 126 1.1 christos } else \ 127 1.1 christos (head)->rbh_root = (tmp); \ 128 1.1 christos RB_RIGHT(tmp, field) = (elm); \ 129 1.1 christos RB_PARENT(elm, field) = (tmp); \ 130 1.1 christos RB_AUGMENT(tmp); \ 131 1.1 christos if ((RB_PARENT(tmp, field))) \ 132 1.1 christos RB_AUGMENT(RB_PARENT(tmp, field)); \ 133 1.1 christos } while (/*CONSTCOND*/ 0) 134 1.1 christos 135 1.1 christos /* Generates prototypes and inline functions */ 136 1.1 christos #define RB_PROTOTYPE(name, type, field, cmp) \ 137 1.1 christos RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) 138 1.1 christos #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ 139 1.1 christos RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static) 140 1.1 christos #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ 141 1.1 christos attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ 142 1.1 christos attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ 143 1.1 christos attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ 144 1.1 christos attr struct type *name##_RB_INSERT(struct name *, struct type *); \ 145 1.1 christos attr struct type *name##_RB_FIND(struct name *, struct type *); \ 146 1.1 christos attr struct type *name##_RB_NFIND(struct name *, struct type *); \ 147 1.1 christos attr struct type *name##_RB_NEXT(struct type *); \ 148 1.1 christos attr struct type *name##_RB_PREV(struct type *); \ 149 1.1 christos attr struct type *name##_RB_MINMAX(struct name *, int); \ 150 1.1 christos \ 151 1.1 christos 152 1.1 christos /* Main rb operation. 153 1.1 christos * Moves node close to the key of elm to top 154 1.1 christos */ 155 1.1 christos #define RB_GENERATE(name, type, field, cmp) \ 156 1.1 christos RB_GENERATE_INTERNAL(name, type, field, cmp,) 157 1.1 christos #define RB_GENERATE_STATIC(name, type, field, cmp) \ 158 1.1 christos RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static) 159 1.1 christos #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ 160 1.1 christos attr void \ 161 1.1 christos name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ 162 1.1 christos { \ 163 1.1 christos struct type *parent, *gparent, *tmp; \ 164 1.1 christos while ((parent = RB_PARENT(elm, field)) != NULL && \ 165 1.1 christos RB_COLOR(parent, field) == RB_RED) { \ 166 1.1 christos gparent = RB_PARENT(parent, field); \ 167 1.1 christos if (parent == RB_LEFT(gparent, field)) { \ 168 1.1 christos tmp = RB_RIGHT(gparent, field); \ 169 1.1 christos if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ 170 1.1 christos RB_COLOR(tmp, field) = RB_BLACK; \ 171 1.1 christos RB_SET_BLACKRED(parent, gparent, field); \ 172 1.1 christos elm = gparent; \ 173 1.1 christos continue; \ 174 1.1 christos } \ 175 1.1 christos if (RB_RIGHT(parent, field) == elm) { \ 176 1.1 christos RB_ROTATE_LEFT(head, parent, tmp, field); \ 177 1.1 christos tmp = parent; \ 178 1.1 christos parent = elm; \ 179 1.1 christos elm = tmp; \ 180 1.1 christos } \ 181 1.1 christos RB_SET_BLACKRED(parent, gparent, field); \ 182 1.1 christos RB_ROTATE_RIGHT(head, gparent, tmp, field); \ 183 1.1 christos } else { \ 184 1.1 christos tmp = RB_LEFT(gparent, field); \ 185 1.1 christos if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ 186 1.1 christos RB_COLOR(tmp, field) = RB_BLACK; \ 187 1.1 christos RB_SET_BLACKRED(parent, gparent, field); \ 188 1.1 christos elm = gparent; \ 189 1.1 christos continue; \ 190 1.1 christos } \ 191 1.1 christos if (RB_LEFT(parent, field) == elm) { \ 192 1.1 christos RB_ROTATE_RIGHT(head, parent, tmp, field); \ 193 1.1 christos tmp = parent; \ 194 1.1 christos parent = elm; \ 195 1.1 christos elm = tmp; \ 196 1.1 christos } \ 197 1.1 christos RB_SET_BLACKRED(parent, gparent, field); \ 198 1.1 christos RB_ROTATE_LEFT(head, gparent, tmp, field); \ 199 1.1 christos } \ 200 1.1 christos } \ 201 1.1 christos RB_COLOR(head->rbh_root, field) = RB_BLACK; \ 202 1.1 christos } \ 203 1.1 christos \ 204 1.1 christos attr void \ 205 1.1 christos name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \ 206 1.1 christos struct type *elm) \ 207 1.1 christos { \ 208 1.1 christos struct type *tmp; \ 209 1.1 christos while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ 210 1.1 christos elm != RB_ROOT(head)) { \ 211 1.1 christos if (RB_LEFT(parent, field) == elm) { \ 212 1.1 christos tmp = RB_RIGHT(parent, field); \ 213 1.1 christos if (RB_COLOR(tmp, field) == RB_RED) { \ 214 1.1 christos RB_SET_BLACKRED(tmp, parent, field); \ 215 1.1 christos RB_ROTATE_LEFT(head, parent, tmp, field); \ 216 1.1 christos tmp = RB_RIGHT(parent, field); \ 217 1.1 christos } \ 218 1.1 christos if ((RB_LEFT(tmp, field) == NULL || \ 219 1.1 christos RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ 220 1.1 christos (RB_RIGHT(tmp, field) == NULL || \ 221 1.1 christos RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ 222 1.1 christos RB_COLOR(tmp, field) = RB_RED; \ 223 1.1 christos elm = parent; \ 224 1.1 christos parent = RB_PARENT(elm, field); \ 225 1.1 christos } else { \ 226 1.1 christos if (RB_RIGHT(tmp, field) == NULL || \ 227 1.1 christos RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \ 228 1.1 christos struct type *oleft; \ 229 1.1 christos if ((oleft = RB_LEFT(tmp, field)) \ 230 1.1 christos != NULL) \ 231 1.1 christos RB_COLOR(oleft, field) = RB_BLACK; \ 232 1.1 christos RB_COLOR(tmp, field) = RB_RED; \ 233 1.1 christos RB_ROTATE_RIGHT(head, tmp, oleft, field); \ 234 1.1 christos tmp = RB_RIGHT(parent, field); \ 235 1.1 christos } \ 236 1.1 christos RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ 237 1.1 christos RB_COLOR(parent, field) = RB_BLACK; \ 238 1.1 christos if (RB_RIGHT(tmp, field)) \ 239 1.1 christos RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \ 240 1.1 christos RB_ROTATE_LEFT(head, parent, tmp, field); \ 241 1.1 christos elm = RB_ROOT(head); \ 242 1.1 christos break; \ 243 1.1 christos } \ 244 1.1 christos } else { \ 245 1.1 christos tmp = RB_LEFT(parent, field); \ 246 1.1 christos if (RB_COLOR(tmp, field) == RB_RED) { \ 247 1.1 christos RB_SET_BLACKRED(tmp, parent, field); \ 248 1.1 christos RB_ROTATE_RIGHT(head, parent, tmp, field); \ 249 1.1 christos tmp = RB_LEFT(parent, field); \ 250 1.1 christos } \ 251 1.1 christos if ((RB_LEFT(tmp, field) == NULL || \ 252 1.1 christos RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ 253 1.1 christos (RB_RIGHT(tmp, field) == NULL || \ 254 1.1 christos RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ 255 1.1 christos RB_COLOR(tmp, field) = RB_RED; \ 256 1.1 christos elm = parent; \ 257 1.1 christos parent = RB_PARENT(elm, field); \ 258 1.1 christos } else { \ 259 1.1 christos if (RB_LEFT(tmp, field) == NULL || \ 260 1.1 christos RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \ 261 1.1 christos struct type *oright; \ 262 1.1 christos if ((oright = RB_RIGHT(tmp, field)) \ 263 1.1 christos != NULL) \ 264 1.1 christos RB_COLOR(oright, field) = RB_BLACK; \ 265 1.1 christos RB_COLOR(tmp, field) = RB_RED; \ 266 1.1 christos RB_ROTATE_LEFT(head, tmp, oright, field); \ 267 1.1 christos tmp = RB_LEFT(parent, field); \ 268 1.1 christos } \ 269 1.1 christos RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ 270 1.1 christos RB_COLOR(parent, field) = RB_BLACK; \ 271 1.1 christos if (RB_LEFT(tmp, field)) \ 272 1.1 christos RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \ 273 1.1 christos RB_ROTATE_RIGHT(head, parent, tmp, field); \ 274 1.1 christos elm = RB_ROOT(head); \ 275 1.1 christos break; \ 276 1.1 christos } \ 277 1.1 christos } \ 278 1.1 christos } \ 279 1.1 christos if (elm) \ 280 1.1 christos RB_COLOR(elm, field) = RB_BLACK; \ 281 1.1 christos } \ 282 1.1 christos \ 283 1.1 christos attr struct type * \ 284 1.1 christos name##_RB_REMOVE(struct name *head, struct type *elm) \ 285 1.1 christos { \ 286 1.1 christos struct type *child, *parent, *old = elm; \ 287 1.1 christos int color; \ 288 1.1 christos if (RB_LEFT(elm, field) == NULL) \ 289 1.1 christos child = RB_RIGHT(elm, field); \ 290 1.1 christos else if (RB_RIGHT(elm, field) == NULL) \ 291 1.1 christos child = RB_LEFT(elm, field); \ 292 1.1 christos else { \ 293 1.1 christos struct type *left; \ 294 1.1 christos elm = RB_RIGHT(elm, field); \ 295 1.1 christos while ((left = RB_LEFT(elm, field)) != NULL) \ 296 1.1 christos elm = left; \ 297 1.1 christos child = RB_RIGHT(elm, field); \ 298 1.1 christos parent = RB_PARENT(elm, field); \ 299 1.1 christos color = RB_COLOR(elm, field); \ 300 1.1 christos if (child) \ 301 1.1 christos RB_PARENT(child, field) = parent; \ 302 1.1 christos if (parent) { \ 303 1.1 christos if (RB_LEFT(parent, field) == elm) \ 304 1.1 christos RB_LEFT(parent, field) = child; \ 305 1.1 christos else \ 306 1.1 christos RB_RIGHT(parent, field) = child; \ 307 1.1 christos RB_AUGMENT(parent); \ 308 1.1 christos } else \ 309 1.1 christos RB_ROOT(head) = child; \ 310 1.1 christos if (RB_PARENT(elm, field) == old) \ 311 1.1 christos parent = elm; \ 312 1.1 christos (elm)->field = (old)->field; \ 313 1.1 christos if (RB_PARENT(old, field)) { \ 314 1.1 christos if (RB_LEFT(RB_PARENT(old, field), field) == old) \ 315 1.1 christos RB_LEFT(RB_PARENT(old, field), field) = elm; \ 316 1.1 christos else \ 317 1.1 christos RB_RIGHT(RB_PARENT(old, field), field) = elm; \ 318 1.1 christos RB_AUGMENT(RB_PARENT(old, field)); \ 319 1.1 christos } else \ 320 1.1 christos RB_ROOT(head) = elm; \ 321 1.1 christos RB_PARENT(RB_LEFT(old, field), field) = elm; \ 322 1.1 christos if (RB_RIGHT(old, field)) \ 323 1.1 christos RB_PARENT(RB_RIGHT(old, field), field) = elm; \ 324 1.1 christos if (parent) { \ 325 1.1 christos left = parent; \ 326 1.1 christos do { \ 327 1.1 christos RB_AUGMENT(left); \ 328 1.1 christos } while ((left = RB_PARENT(left, field)) != NULL); \ 329 1.1 christos } \ 330 1.1 christos goto color; \ 331 1.1 christos } \ 332 1.1 christos parent = RB_PARENT(elm, field); \ 333 1.1 christos color = RB_COLOR(elm, field); \ 334 1.1 christos if (child) \ 335 1.1 christos RB_PARENT(child, field) = parent; \ 336 1.1 christos if (parent) { \ 337 1.1 christos if (RB_LEFT(parent, field) == elm) \ 338 1.1 christos RB_LEFT(parent, field) = child; \ 339 1.1 christos else \ 340 1.1 christos RB_RIGHT(parent, field) = child; \ 341 1.1 christos RB_AUGMENT(parent); \ 342 1.1 christos } else \ 343 1.1 christos RB_ROOT(head) = child; \ 344 1.1 christos color: \ 345 1.1 christos if (color == RB_BLACK) \ 346 1.1 christos name##_RB_REMOVE_COLOR(head, parent, child); \ 347 1.1 christos return (old); \ 348 1.1 christos } \ 349 1.1 christos \ 350 1.1 christos /* Inserts a node into the RB tree */ \ 351 1.1 christos attr struct type * \ 352 1.1 christos name##_RB_INSERT(struct name *head, struct type *elm) \ 353 1.1 christos { \ 354 1.1 christos struct type *tmp; \ 355 1.1 christos struct type *parent = NULL; \ 356 1.1 christos int comp = 0; \ 357 1.1 christos tmp = RB_ROOT(head); \ 358 1.1 christos while (tmp) { \ 359 1.1 christos parent = tmp; \ 360 1.1 christos comp = (cmp)(elm, parent); \ 361 1.1 christos if (comp < 0) \ 362 1.1 christos tmp = RB_LEFT(tmp, field); \ 363 1.1 christos else if (comp > 0) \ 364 1.1 christos tmp = RB_RIGHT(tmp, field); \ 365 1.1 christos else \ 366 1.1 christos return (tmp); \ 367 1.1 christos } \ 368 1.1 christos RB_SET(elm, parent, field); \ 369 1.1 christos if (parent != NULL) { \ 370 1.1 christos if (comp < 0) \ 371 1.1 christos RB_LEFT(parent, field) = elm; \ 372 1.1 christos else \ 373 1.1 christos RB_RIGHT(parent, field) = elm; \ 374 1.1 christos RB_AUGMENT(parent); \ 375 1.1 christos } else \ 376 1.1 christos RB_ROOT(head) = elm; \ 377 1.1 christos name##_RB_INSERT_COLOR(head, elm); \ 378 1.1 christos return (NULL); \ 379 1.1 christos } \ 380 1.1 christos \ 381 1.1 christos /* Finds the node with the same key as elm */ \ 382 1.1 christos attr struct type * \ 383 1.1 christos name##_RB_FIND(struct name *head, struct type *elm) \ 384 1.1 christos { \ 385 1.1 christos struct type *tmp = RB_ROOT(head); \ 386 1.1 christos int comp; \ 387 1.1 christos while (tmp) { \ 388 1.1 christos comp = cmp(elm, tmp); \ 389 1.1 christos if (comp < 0) \ 390 1.1 christos tmp = RB_LEFT(tmp, field); \ 391 1.1 christos else if (comp > 0) \ 392 1.1 christos tmp = RB_RIGHT(tmp, field); \ 393 1.1 christos else \ 394 1.1 christos return (tmp); \ 395 1.1 christos } \ 396 1.1 christos return (NULL); \ 397 1.1 christos } \ 398 1.1 christos \ 399 1.1 christos /* Finds the first node greater than or equal to the search key */ \ 400 1.1 christos attr struct type * \ 401 1.1 christos name##_RB_NFIND(struct name *head, struct type *elm) \ 402 1.1 christos { \ 403 1.1 christos struct type *tmp = RB_ROOT(head); \ 404 1.1 christos struct type *res = NULL; \ 405 1.1 christos int comp; \ 406 1.1 christos while (tmp) { \ 407 1.1 christos comp = cmp(elm, tmp); \ 408 1.1 christos if (comp < 0) { \ 409 1.1 christos res = tmp; \ 410 1.1 christos tmp = RB_LEFT(tmp, field); \ 411 1.1 christos } \ 412 1.1 christos else if (comp > 0) \ 413 1.1 christos tmp = RB_RIGHT(tmp, field); \ 414 1.1 christos else \ 415 1.1 christos return (tmp); \ 416 1.1 christos } \ 417 1.1 christos return (res); \ 418 1.1 christos } \ 419 1.1 christos \ 420 1.1 christos /* ARGSUSED */ \ 421 1.1 christos attr struct type * \ 422 1.1 christos name##_RB_NEXT(struct type *elm) \ 423 1.1 christos { \ 424 1.1 christos if (RB_RIGHT(elm, field)) { \ 425 1.1 christos elm = RB_RIGHT(elm, field); \ 426 1.1 christos while (RB_LEFT(elm, field)) \ 427 1.1 christos elm = RB_LEFT(elm, field); \ 428 1.1 christos } else { \ 429 1.1 christos if (RB_PARENT(elm, field) && \ 430 1.1 christos (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ 431 1.1 christos elm = RB_PARENT(elm, field); \ 432 1.1 christos else { \ 433 1.1 christos while (RB_PARENT(elm, field) && \ 434 1.1 christos (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ 435 1.1 christos elm = RB_PARENT(elm, field); \ 436 1.1 christos elm = RB_PARENT(elm, field); \ 437 1.1 christos } \ 438 1.1 christos } \ 439 1.1 christos return (elm); \ 440 1.1 christos } \ 441 1.1 christos \ 442 1.1 christos /* ARGSUSED */ \ 443 1.1 christos attr struct type * \ 444 1.1 christos name##_RB_PREV(struct type *elm) \ 445 1.1 christos { \ 446 1.1 christos if (RB_LEFT(elm, field)) { \ 447 1.1 christos elm = RB_LEFT(elm, field); \ 448 1.1 christos while (RB_RIGHT(elm, field)) \ 449 1.1 christos elm = RB_RIGHT(elm, field); \ 450 1.1 christos } else { \ 451 1.1 christos if (RB_PARENT(elm, field) && \ 452 1.1 christos (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ 453 1.1 christos elm = RB_PARENT(elm, field); \ 454 1.1 christos else { \ 455 1.1 christos while (RB_PARENT(elm, field) && \ 456 1.1 christos (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ 457 1.1 christos elm = RB_PARENT(elm, field); \ 458 1.1 christos elm = RB_PARENT(elm, field); \ 459 1.1 christos } \ 460 1.1 christos } \ 461 1.1 christos return (elm); \ 462 1.1 christos } \ 463 1.1 christos \ 464 1.1 christos attr struct type * \ 465 1.1 christos name##_RB_MINMAX(struct name *head, int val) \ 466 1.1 christos { \ 467 1.1 christos struct type *tmp = RB_ROOT(head); \ 468 1.1 christos struct type *parent = NULL; \ 469 1.1 christos while (tmp) { \ 470 1.1 christos parent = tmp; \ 471 1.1 christos if (val < 0) \ 472 1.1 christos tmp = RB_LEFT(tmp, field); \ 473 1.1 christos else \ 474 1.1 christos tmp = RB_RIGHT(tmp, field); \ 475 1.1 christos } \ 476 1.1 christos return (parent); \ 477 1.1 christos } 478 1.1 christos 479 1.1 christos #define RB_NEGINF -1 480 1.1 christos #define RB_INF 1 481 1.1 christos 482 1.1 christos #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) 483 1.1 christos #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) 484 1.1 christos #define RB_FIND(name, x, y) name##_RB_FIND(x, y) 485 1.1 christos #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) 486 1.1.1.3 christos #define RB_NEXT(name, x) name##_RB_NEXT(x) 487 1.1.1.3 christos #define RB_PREV(name, x) name##_RB_PREV(x) 488 1.1 christos #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) 489 1.1 christos #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) 490 1.1 christos 491 1.1 christos #define RB_FOREACH(x, name, head) \ 492 1.1 christos for ((x) = RB_MIN(name, head); \ 493 1.1 christos (x) != NULL; \ 494 1.1 christos (x) = name##_RB_NEXT(x)) 495 1.1 christos 496 1.1 christos #define RB_FOREACH_FROM(x, name, y) \ 497 1.1 christos for ((x) = (y); \ 498 1.1 christos ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ 499 1.1 christos (x) = (y)) 500 1.1 christos 501 1.1 christos #define RB_FOREACH_SAFE(x, name, head, y) \ 502 1.1 christos for ((x) = RB_MIN(name, head); \ 503 1.1 christos ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ 504 1.1 christos (x) = (y)) 505 1.1 christos 506 1.1 christos #define RB_FOREACH_REVERSE(x, name, head) \ 507 1.1 christos for ((x) = RB_MAX(name, head); \ 508 1.1 christos (x) != NULL; \ 509 1.1 christos (x) = name##_RB_PREV(x)) 510 1.1 christos 511 1.1 christos #define RB_FOREACH_REVERSE_FROM(x, name, y) \ 512 1.1 christos for ((x) = (y); \ 513 1.1 christos ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ 514 1.1 christos (x) = (y)) 515 1.1 christos 516 1.1 christos #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ 517 1.1 christos for ((x) = RB_MAX(name, head); \ 518 1.1 christos ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ 519 1.1 christos (x) = (y)) 520 1.1 christos 521 1.1 christos #endif /* UV_TREE_H_ */ 522