Go to the documentation of this file. 36 #define RB_HEAD(name, type) \ 38 struct type *rbh_root; \ 41 #define RB_INITIALIZER(root) \ 44 #define RB_INIT(root) do { \ 45 (root)->rbh_root = NULL; \ 50 #define RB_ENTRY(type) \ 52 struct type *rbe_left; \ 53 struct type *rbe_right; \ 54 struct type *rbe_parent; \ 58 #define RB_LEFT(elm, field) (elm)->field.rbe_left 59 #define RB_RIGHT(elm, field) (elm)->field.rbe_right 60 #define RB_PARENT(elm, field) (elm)->field.rbe_parent 61 #define RB_COLOR(elm, field) (elm)->field.rbe_color 62 #define RB_ROOT(head) (head)->rbh_root 63 #define RB_EMPTY(head) (RB_ROOT(head) == NULL) 65 #define RB_SET(elm, parent, field) do { \ 66 RB_PARENT(elm, field) = parent; \ 67 RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ 68 RB_COLOR(elm, field) = RB_RED; \ 71 #define RB_SET_BLACKRED(black, red, field) do { \ 72 RB_COLOR(black, field) = RB_BLACK; \ 73 RB_COLOR(red, field) = RB_RED; \ 77 #define RB_AUGMENT(x) do {} while (0) 80 #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ 81 (tmp) = RB_RIGHT(elm, field); \ 82 if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ 83 RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ 86 if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ 87 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ 88 RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ 90 RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ 92 (head)->rbh_root = (tmp); \ 93 RB_LEFT(tmp, field) = (elm); \ 94 RB_PARENT(elm, field) = (tmp); \ 96 if ((RB_PARENT(tmp, field))) \ 97 RB_AUGMENT(RB_PARENT(tmp, field)); \ 100 #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ 101 (tmp) = RB_LEFT(elm, field); \ 102 if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ 103 RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ 106 if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ 107 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ 108 RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ 110 RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ 112 (head)->rbh_root = (tmp); \ 113 RB_RIGHT(tmp, field) = (elm); \ 114 RB_PARENT(elm, field) = (tmp); \ 116 if ((RB_PARENT(tmp, field))) \ 117 RB_AUGMENT(RB_PARENT(tmp, field)); \ 121 #define RB_PROTOTYPE(name, type, field, cmp) \ 122 RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) 123 #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ 124 RB_PROTOTYPE_INTERNAL(name, type, field, cmp, static) 125 #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ 126 attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ 127 attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ 128 attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ 129 attr struct type *name##_RB_INSERT(struct name *, struct type *); \ 130 attr struct type *name##_RB_FIND(struct name *, struct type *); \ 131 attr struct type *name##_RB_NFIND(struct name *, struct type *); \ 132 attr struct type *name##_RB_NEXT(struct type *); \ 133 attr struct type *name##_RB_PREV(struct type *); \ 134 attr struct type *name##_RB_MINMAX(struct name *, int); \ 140 #define RB_GENERATE(name, type, field, cmp) \ 141 RB_GENERATE_INTERNAL(name, type, field, cmp,) 142 #define RB_GENERATE_STATIC(name, type, field, cmp) \ 143 RB_GENERATE_INTERNAL(name, type, field, cmp, static) 144 #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ 146 name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ 148 struct type *parent, *gparent, *tmp; \ 149 while ((parent = RB_PARENT(elm, field)) != NULL && \ 150 RB_COLOR(parent, field) == RB_RED) { \ 151 gparent = RB_PARENT(parent, field); \ 152 if (parent == RB_LEFT(gparent, field)) { \ 153 tmp = RB_RIGHT(gparent, field); \ 154 if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ 155 RB_COLOR(tmp, field) = RB_BLACK; \ 156 RB_SET_BLACKRED(parent, gparent, field);\ 160 if (RB_RIGHT(parent, field) == elm) { \ 161 RB_ROTATE_LEFT(head, parent, tmp, field);\ 166 RB_SET_BLACKRED(parent, gparent, field); \ 167 RB_ROTATE_RIGHT(head, gparent, tmp, field); \ 169 tmp = RB_LEFT(gparent, field); \ 170 if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ 171 RB_COLOR(tmp, field) = RB_BLACK; \ 172 RB_SET_BLACKRED(parent, gparent, field);\ 176 if (RB_LEFT(parent, field) == elm) { \ 177 RB_ROTATE_RIGHT(head, parent, tmp, field);\ 182 RB_SET_BLACKRED(parent, gparent, field); \ 183 RB_ROTATE_LEFT(head, gparent, tmp, field); \ 186 RB_COLOR(head->rbh_root, field) = RB_BLACK; \ 190 name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ 193 while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ 194 elm != RB_ROOT(head)) { \ 195 if (RB_LEFT(parent, field) == elm) { \ 196 tmp = RB_RIGHT(parent, field); \ 197 if (RB_COLOR(tmp, field) == RB_RED) { \ 198 RB_SET_BLACKRED(tmp, parent, field); \ 199 RB_ROTATE_LEFT(head, parent, tmp, field);\ 200 tmp = RB_RIGHT(parent, field); \ 202 if ((RB_LEFT(tmp, field) == NULL || \ 203 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ 204 (RB_RIGHT(tmp, field) == NULL || \ 205 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ 206 RB_COLOR(tmp, field) = RB_RED; \ 208 parent = RB_PARENT(elm, field); \ 210 if (RB_RIGHT(tmp, field) == NULL || \ 211 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ 212 struct type *oleft; \ 213 if ((oleft = RB_LEFT(tmp, field)) \ 215 RB_COLOR(oleft, field) = RB_BLACK;\ 216 RB_COLOR(tmp, field) = RB_RED; \ 217 RB_ROTATE_RIGHT(head, tmp, oleft, field);\ 218 tmp = RB_RIGHT(parent, field); \ 220 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ 221 RB_COLOR(parent, field) = RB_BLACK; \ 222 if (RB_RIGHT(tmp, field)) \ 223 RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ 224 RB_ROTATE_LEFT(head, parent, tmp, field);\ 225 elm = RB_ROOT(head); \ 229 tmp = RB_LEFT(parent, field); \ 230 if (RB_COLOR(tmp, field) == RB_RED) { \ 231 RB_SET_BLACKRED(tmp, parent, field); \ 232 RB_ROTATE_RIGHT(head, parent, tmp, field);\ 233 tmp = RB_LEFT(parent, field); \ 235 if ((RB_LEFT(tmp, field) == NULL || \ 236 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ 237 (RB_RIGHT(tmp, field) == NULL || \ 238 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ 239 RB_COLOR(tmp, field) = RB_RED; \ 241 parent = RB_PARENT(elm, field); \ 243 if (RB_LEFT(tmp, field) == NULL || \ 244 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ 245 struct type *oright; \ 246 if ((oright = RB_RIGHT(tmp, field)) \ 248 RB_COLOR(oright, field) = RB_BLACK;\ 249 RB_COLOR(tmp, field) = RB_RED; \ 250 RB_ROTATE_LEFT(head, tmp, oright, field);\ 251 tmp = RB_LEFT(parent, field); \ 253 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ 254 RB_COLOR(parent, field) = RB_BLACK; \ 255 if (RB_LEFT(tmp, field)) \ 256 RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ 257 RB_ROTATE_RIGHT(head, parent, tmp, field);\ 258 elm = RB_ROOT(head); \ 264 RB_COLOR(elm, field) = RB_BLACK; \ 268 name##_RB_REMOVE(struct name *head, struct type *elm) \ 270 struct type *child, *parent, *old = elm; \ 272 if (RB_LEFT(elm, field) == NULL) \ 273 child = RB_RIGHT(elm, field); \ 274 else if (RB_RIGHT(elm, field) == NULL) \ 275 child = RB_LEFT(elm, field); \ 278 elm = RB_RIGHT(elm, field); \ 279 while ((left = RB_LEFT(elm, field)) != NULL) \ 281 child = RB_RIGHT(elm, field); \ 282 parent = RB_PARENT(elm, field); \ 283 color = RB_COLOR(elm, field); \ 285 RB_PARENT(child, field) = parent; \ 287 if (RB_LEFT(parent, field) == elm) \ 288 RB_LEFT(parent, field) = child; \ 290 RB_RIGHT(parent, field) = child; \ 291 RB_AUGMENT(parent); \ 293 RB_ROOT(head) = child; \ 294 if (RB_PARENT(elm, field) == old) \ 296 (elm)->field = (old)->field; \ 297 if (RB_PARENT(old, field)) { \ 298 if (RB_LEFT(RB_PARENT(old, field), field) == old)\ 299 RB_LEFT(RB_PARENT(old, field), field) = elm;\ 301 RB_RIGHT(RB_PARENT(old, field), field) = elm;\ 302 RB_AUGMENT(RB_PARENT(old, field)); \ 304 RB_ROOT(head) = elm; \ 305 RB_PARENT(RB_LEFT(old, field), field) = elm; \ 306 if (RB_RIGHT(old, field)) \ 307 RB_PARENT(RB_RIGHT(old, field), field) = elm; \ 312 } while ((left = RB_PARENT(left, field)) != NULL); \ 316 parent = RB_PARENT(elm, field); \ 317 color = RB_COLOR(elm, field); \ 319 RB_PARENT(child, field) = parent; \ 321 if (RB_LEFT(parent, field) == elm) \ 322 RB_LEFT(parent, field) = child; \ 324 RB_RIGHT(parent, field) = child; \ 325 RB_AUGMENT(parent); \ 327 RB_ROOT(head) = child; \ 329 if (color == RB_BLACK) \ 330 name##_RB_REMOVE_COLOR(head, parent, child); \ 336 name##_RB_INSERT(struct name *head, struct type *elm) \ 339 struct type *parent = NULL; \ 341 tmp = RB_ROOT(head); \ 344 comp = (cmp)(elm, parent); \ 346 tmp = RB_LEFT(tmp, field); \ 348 tmp = RB_RIGHT(tmp, field); \ 352 RB_SET(elm, parent, field); \ 353 if (parent != NULL) { \ 355 RB_LEFT(parent, field) = elm; \ 357 RB_RIGHT(parent, field) = elm; \ 358 RB_AUGMENT(parent); \ 360 RB_ROOT(head) = elm; \ 361 name##_RB_INSERT_COLOR(head, elm); \ 367 name##_RB_FIND(struct name *head, struct type *elm) \ 369 struct type *tmp = RB_ROOT(head); \ 372 comp = cmp(elm, tmp); \ 374 tmp = RB_LEFT(tmp, field); \ 376 tmp = RB_RIGHT(tmp, field); \ 385 name##_RB_NFIND(struct name *head, struct type *elm) \ 387 struct type *tmp = RB_ROOT(head); \ 388 struct type *res = NULL; \ 391 comp = cmp(elm, tmp); \ 394 tmp = RB_LEFT(tmp, field); \ 397 tmp = RB_RIGHT(tmp, field); \ 406 name##_RB_NEXT(struct type *elm) \ 408 if (RB_RIGHT(elm, field)) { \ 409 elm = RB_RIGHT(elm, field); \ 410 while (RB_LEFT(elm, field)) \ 411 elm = RB_LEFT(elm, field); \ 413 if (RB_PARENT(elm, field) && \ 414 (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ 415 elm = RB_PARENT(elm, field); \ 417 while (RB_PARENT(elm, field) && \ 418 (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ 419 elm = RB_PARENT(elm, field); \ 420 elm = RB_PARENT(elm, field); \ 428 name##_RB_PREV(struct type *elm) \ 430 if (RB_LEFT(elm, field)) { \ 431 elm = RB_LEFT(elm, field); \ 432 while (RB_RIGHT(elm, field)) \ 433 elm = RB_RIGHT(elm, field); \ 435 if (RB_PARENT(elm, field) && \ 436 (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ 437 elm = RB_PARENT(elm, field); \ 439 while (RB_PARENT(elm, field) && \ 440 (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ 441 elm = RB_PARENT(elm, field); \ 442 elm = RB_PARENT(elm, field); \ 449 name##_RB_MINMAX(struct name *head, int val) \ 451 struct type *tmp = RB_ROOT(head); \ 452 struct type *parent = NULL; \ 456 tmp = RB_LEFT(tmp, field); \ 458 tmp = RB_RIGHT(tmp, field); \ 466 #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) 467 #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) 468 #define RB_FIND(name, x, y) name##_RB_FIND(x, y) 469 #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) 470 #define RB_NEXT(name, x, y) name##_RB_NEXT(y) 471 #define RB_PREV(name, x, y) name##_RB_PREV(y) 472 #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) 473 #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) 475 #define RB_FOREACH(x, name, head) \ 476 for ((x) = RB_MIN(name, head); \ 478 (x) = name##_RB_NEXT(x)) 480 #define RB_FOREACH_FROM(x, name, y) \ 482 ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ 485 #define RB_FOREACH_SAFE(x, name, head, y) \ 486 for ((x) = RB_MIN(name, head); \ 487 ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ 490 #define RB_FOREACH_REVERSE(x, name, head) \ 491 for ((x) = RB_MAX(name, head); \ 493 (x) = name##_RB_PREV(x)) 495 #define RB_FOREACH_REVERSE_FROM(x, name, y) \ 497 ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ 500 #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ 501 for ((x) = RB_MAX(name, head); \ 502 ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \