1 /*      $OpenBSD: tree.h,v 1.6 2002/06/11 22:09:52 provos Exp $ */
   2 /*
   3  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
   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, this list of conditions and the following disclaimer.
  11  * 2. Redistributions in binary form must reproduce the above copyright
  12  *    notice, this list of conditions and the following disclaimer in the
  13  *    documentation and/or other materials provided with the distribution.
  14  *
  15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25  */
  26 
  27 #ifndef _SYS_TREE_H
  28 #define _SYS_TREE_H
  29 
  30 #ifdef __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 /*
  35  * This file defines data structures for different types of trees:
  36  * splay trees and red-black trees.
  37  *
  38  * A splay tree is a self-organizing data structure.  Every operation
  39  * on the tree causes a splay to happen.  The splay moves the requested
  40  * node to the root of the tree and partly rebalances it.
  41  *
  42  * This has the benefit that request locality causes faster lookups as
  43  * the requested nodes move to the top of the tree.  On the other hand,
  44  * every lookup causes memory writes.
  45  *
  46  * The Balance Theorem bounds the total access time for m operations
  47  * and n inserts on an initially empty tree as O((m + n)lg n).  The
  48  * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
  49  *
  50  * A red-black tree is a binary search tree with the node color as an
  51  * extra attribute.  It fulfills a set of conditions:
  52  *      - every search path from the root to a leaf consists of the
  53  *        same number of black nodes,
  54  *      - each red node (except for the root) has a black parent,
  55  *      - each leaf node is black.
  56  *
  57  * Every operation on a red-black tree is bounded as O(lg n).
  58  * The maximum height of a red-black tree is 2lg (n+1).
  59  */
  60 
  61 #define SPLAY_HEAD(name, type)                                          \
  62 struct name {                                                           \
  63         struct type *sph_root; /* root of the tree */                   \
  64 }
  65 
  66 #define SPLAY_INITIALIZER(root)                                         \
  67         { NULL }
  68 
  69 #define SPLAY_INIT(root) do {                                           \
  70         (root)->sph_root = NULL;                                     \
  71 } while (0)
  72 
  73 #define SPLAY_ENTRY(type)                                               \
  74 struct {                                                                \
  75         struct type *spe_left; /* left element */                       \
  76         struct type *spe_right; /* right element */                     \
  77 }
  78 
  79 #define SPLAY_LEFT(elm, field)          (elm)->field.spe_left
  80 #define SPLAY_RIGHT(elm, field)         (elm)->field.spe_right
  81 #define SPLAY_ROOT(head)                (head)->sph_root
  82 #define SPLAY_EMPTY(head)               (SPLAY_ROOT(head) == NULL)
  83 
  84 /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
  85 #define SPLAY_ROTATE_RIGHT(head, tmp, field) do {                       \
  86         SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);       \
  87         SPLAY_RIGHT(tmp, field) = (head)->sph_root;                  \
  88         (head)->sph_root = tmp;                                              \
  89 } while (0)
  90         
  91 #define SPLAY_ROTATE_LEFT(head, tmp, field) do {                        \
  92         SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);       \
  93         SPLAY_LEFT(tmp, field) = (head)->sph_root;                   \
  94         (head)->sph_root = tmp;                                              \
  95 } while (0)
  96 
  97 #define SPLAY_LINKLEFT(head, tmp, field) do {                           \
  98         SPLAY_LEFT(tmp, field) = (head)->sph_root;                   \
  99         tmp = (head)->sph_root;                                              \
 100         (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);           \
 101 } while (0)
 102 
 103 #define SPLAY_LINKRIGHT(head, tmp, field) do {                          \
 104         SPLAY_RIGHT(tmp, field) = (head)->sph_root;                  \
 105         tmp = (head)->sph_root;                                              \
 106         (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);  \
 107 } while (0)
 108 
 109 #define SPLAY_ASSEMBLE(head, node, left, right, field) do {             \
 110         SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);      \
 111         SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
 112         SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);      \
 113         SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);      \
 114 } while (0)
 115 
 116 /* Generates prototypes and inline functions */
 117 
 118 #define SPLAY_PROTOTYPE(name, type, field, cmp)                         \
 119 void name##_SPLAY(struct name *, struct type *);                        \
 120 void name##_SPLAY_MINMAX(struct name *, int);                           \
 121 struct type *name##_SPLAY_INSERT(struct name *, struct type *);         \
 122 struct type *name##_SPLAY_REMOVE(struct name *, struct type *);         \
 123                                                                         \
 124 /* Finds the node with the same key as elm */                           \
 125 static __inline struct type *                                           \
 126 name##_SPLAY_FIND(struct name *head, struct type *elm)                  \
 127 {                                                                       \
 128         if (SPLAY_EMPTY(head))                                          \
 129                 return(NULL);                                           \
 130         name##_SPLAY(head, elm);                                        \
 131         if ((cmp)(elm, (head)->sph_root) == 0)                               \
 132                 return (head->sph_root);                             \
 133         return (NULL);                                                  \
 134 }                                                                       \
 135                                                                         \
 136 static __inline struct type *                                           \
 137 name##_SPLAY_NEXT(struct name *head, struct type *elm)                  \
 138 {                                                                       \
 139         name##_SPLAY(head, elm);                                        \
 140         if (SPLAY_RIGHT(elm, field) != NULL) {                          \
 141                 elm = SPLAY_RIGHT(elm, field);                          \
 142                 while (SPLAY_LEFT(elm, field) != NULL) {                \
 143                         elm = SPLAY_LEFT(elm, field);                   \
 144                 }                                                       \
 145         } else                                                          \
 146                 elm = NULL;                                             \
 147         return (elm);                                                   \
 148 }                                                                       \
 149                                                                         \
 150 static __inline struct type *                                           \
 151 name##_SPLAY_MIN_MAX(struct name *head, int val)                        \
 152 {                                                                       \
 153         name##_SPLAY_MINMAX(head, val);                                 \
 154         return (SPLAY_ROOT(head));                                      \
 155 }
 156 
 157 /* Main splay operation.
 158  * Moves node close to the key of elm to top
 159  */
 160 #define SPLAY_GENERATE(name, type, field, cmp)                          \
 161 struct type *                                                           \
 162 name##_SPLAY_INSERT(struct name *head, struct type *elm)                \
 163 {                                                                       \
 164     if (SPLAY_EMPTY(head)) {                                            \
 165             SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;    \
 166     } else {                                                            \
 167             int __comp;                                                 \
 168             name##_SPLAY(head, elm);                                    \
 169             __comp = (cmp)(elm, (head)->sph_root);                   \
 170             if(__comp < 0) {                                         \
 171                     SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
 172                     SPLAY_RIGHT(elm, field) = (head)->sph_root;              \
 173                     SPLAY_LEFT((head)->sph_root, field) = NULL;              \
 174             } else if (__comp > 0) {                                 \
 175                     SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
 176                     SPLAY_LEFT(elm, field) = (head)->sph_root;               \
 177                     SPLAY_RIGHT((head)->sph_root, field) = NULL;     \
 178             } else                                                      \
 179                     return ((head)->sph_root);                               \
 180     }                                                                   \
 181     (head)->sph_root = (elm);                                                \
 182     return (NULL);                                                      \
 183 }                                                                       \
 184                                                                         \
 185 struct type *                                                           \
 186 name##_SPLAY_REMOVE(struct name *head, struct type *elm)                \
 187 {                                                                       \
 188         struct type *__tmp;                                             \
 189         if (SPLAY_EMPTY(head))                                          \
 190                 return (NULL);                                          \
 191         name##_SPLAY(head, elm);                                        \
 192         if ((cmp)(elm, (head)->sph_root) == 0) {                     \
 193                 if (SPLAY_LEFT((head)->sph_root, field) == NULL) {   \
 194                         (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
 195                 } else {                                                \
 196                         __tmp = SPLAY_RIGHT((head)->sph_root, field);        \
 197                         (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
 198                         name##_SPLAY(head, elm);                        \
 199                         SPLAY_RIGHT((head)->sph_root, field) = __tmp;        \
 200                 }                                                       \
 201                 return (elm);                                           \
 202         }                                                               \
 203         return (NULL);                                                  \
 204 }                                                                       \
 205                                                                         \
 206 void                                                                    \
 207 name##_SPLAY(struct name *head, struct type *elm)                       \
 208 {                                                                       \
 209         struct type __node, *__left, *__right, *__tmp;                  \
 210         int __comp;                                                     \
 211 \
 212         SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
 213         __left = __right = &__node;                                 \
 214 \
 215         while ((__comp = (cmp)(elm, (head)->sph_root))) {            \
 216                 if (__comp < 0) {                                    \
 217                         __tmp = SPLAY_LEFT((head)->sph_root, field); \
 218                         if (__tmp == NULL)                              \
 219                                 break;                                  \
 220                         if ((cmp)(elm, __tmp) < 0){                  \
 221                                 SPLAY_ROTATE_RIGHT(head, __tmp, field); \
 222                                 if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
 223                                         break;                          \
 224                         }                                               \
 225                         SPLAY_LINKLEFT(head, __right, field);           \
 226                 } else if (__comp > 0) {                             \
 227                         __tmp = SPLAY_RIGHT((head)->sph_root, field);        \
 228                         if (__tmp == NULL)                              \
 229                                 break;                                  \
 230                         if ((cmp)(elm, __tmp) > 0){                  \
 231                                 SPLAY_ROTATE_LEFT(head, __tmp, field);  \
 232                                 if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
 233                                         break;                          \
 234                         }                                               \
 235                         SPLAY_LINKRIGHT(head, __left, field);           \
 236                 }                                                       \
 237         }                                                               \
 238         SPLAY_ASSEMBLE(head, &__node, __left, __right, field);              \
 239 }                                                                       \
 240                                                                         \
 241 /* Splay with either the minimum or the maximum element                 \
 242  * Used to find minimum or maximum element in tree.                     \
 243  */                                                                     \
 244 void name##_SPLAY_MINMAX(struct name *head, int __comp) \
 245 {                                                                       \
 246         struct type __node, *__left, *__right, *__tmp;                  \
 247 \
 248         SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
 249         __left = __right = &__node;                                 \
 250 \
 251         while (1) {                                                     \
 252                 if (__comp < 0) {                                    \
 253                         __tmp = SPLAY_LEFT((head)->sph_root, field); \
 254                         if (__tmp == NULL)                              \
 255                                 break;                                  \
 256                         if (__comp < 0){                             \
 257                                 SPLAY_ROTATE_RIGHT(head, __tmp, field); \
 258                                 if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
 259                                         break;                          \
 260                         }                                               \
 261                         SPLAY_LINKLEFT(head, __right, field);           \
 262                 } else if (__comp > 0) {                             \
 263                         __tmp = SPLAY_RIGHT((head)->sph_root, field);        \
 264                         if (__tmp == NULL)                              \
 265                                 break;                                  \
 266                         if (__comp > 0) {                            \
 267                                 SPLAY_ROTATE_LEFT(head, __tmp, field);  \
 268                                 if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
 269                                         break;                          \
 270                         }                                               \
 271                         SPLAY_LINKRIGHT(head, __left, field);           \
 272                 }                                                       \
 273         }                                                               \
 274         SPLAY_ASSEMBLE(head, &__node, __left, __right, field);              \
 275 }
 276 
 277 #define SPLAY_NEGINF    -1
 278 #define SPLAY_INF       1
 279 
 280 #define SPLAY_INSERT(name, x, y)        name##_SPLAY_INSERT(x, y)
 281 #define SPLAY_REMOVE(name, x, y)        name##_SPLAY_REMOVE(x, y)
 282 #define SPLAY_FIND(name, x, y)          name##_SPLAY_FIND(x, y)
 283 #define SPLAY_NEXT(name, x, y)          name##_SPLAY_NEXT(x, y)
 284 #define SPLAY_MIN(name, x)              (SPLAY_EMPTY(x) ? NULL  \
 285                                         : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
 286 #define SPLAY_MAX(name, x)              (SPLAY_EMPTY(x) ? NULL  \
 287                                         : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
 288 
 289 #define SPLAY_FOREACH(x, name, head)                                    \
 290         for ((x) = SPLAY_MIN(name, head);                               \
 291              (x) != NULL;                                               \
 292              (x) = SPLAY_NEXT(name, head, x))
 293 
 294 /* Macros that define a red-back tree */
 295 #define RB_HEAD(name, type)                                             \
 296 struct name {                                                           \
 297         struct type *rbh_root; /* root of the tree */                   \
 298 }
 299 
 300 #define RB_INITIALIZER(root)                                            \
 301         { NULL }
 302 
 303 #define RB_INIT(root) do {                                              \
 304         (root)->rbh_root = NULL;                                     \
 305 } while (0)
 306 
 307 #define RB_BLACK        0
 308 #define RB_RED          1
 309 #define RB_ENTRY(type)                                                  \
 310 struct {                                                                \
 311         struct type *rbe_left;          /* left element */              \
 312         struct type *rbe_right;         /* right element */             \
 313         struct type *rbe_parent;        /* parent element */            \
 314         int rbe_color;                  /* node color */                \
 315 }
 316 
 317 #define RB_LEFT(elm, field)             (elm)->field.rbe_left
 318 #define RB_RIGHT(elm, field)            (elm)->field.rbe_right
 319 #define RB_PARENT(elm, field)           (elm)->field.rbe_parent
 320 #define RB_COLOR(elm, field)            (elm)->field.rbe_color
 321 #define RB_ROOT(head)                   (head)->rbh_root
 322 #define RB_EMPTY(head)                  (RB_ROOT(head) == NULL)
 323 
 324 #define RB_SET(elm, parent, field) do {                                 \
 325         RB_PARENT(elm, field) = parent;                                 \
 326         RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;              \
 327         RB_COLOR(elm, field) = RB_RED;                                  \
 328 } while (0)
 329 
 330 #define RB_SET_BLACKRED(black, red, field) do {                         \
 331         RB_COLOR(black, field) = RB_BLACK;                              \
 332         RB_COLOR(red, field) = RB_RED;                                  \
 333 } while (0)
 334 
 335 #ifndef RB_AUGMENT
 336 #define RB_AUGMENT(x)
 337 #endif
 338 
 339 #define RB_ROTATE_LEFT(head, elm, tmp, field) do {                      \
 340         (tmp) = RB_RIGHT(elm, field);                                   \
 341         if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {             \
 342                 RB_PARENT(RB_LEFT(tmp, field), field) = (elm);          \
 343         }                                                               \
 344         RB_AUGMENT(elm);                                                \
 345         if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {          \
 346                 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))     \
 347                         RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
 348                 else                                                    \
 349                         RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
 350                 RB_AUGMENT(RB_PARENT(elm, field));                      \
 351         } else                                                          \
 352                 (head)->rbh_root = (tmp);                            \
 353         RB_LEFT(tmp, field) = (elm);                                    \
 354         RB_PARENT(elm, field) = (tmp);                                  \
 355         RB_AUGMENT(tmp);                                                \
 356 } while (0)
 357 
 358 #define RB_ROTATE_RIGHT(head, elm, tmp, field) do {                     \
 359         (tmp) = RB_LEFT(elm, field);                                    \
 360         if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {             \
 361                 RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);         \
 362         }                                                               \
 363         RB_AUGMENT(elm);                                                \
 364         if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {          \
 365                 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))     \
 366                         RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
 367                 else                                                    \
 368                         RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
 369                 RB_AUGMENT(RB_PARENT(elm, field));                      \
 370         } else                                                          \
 371                 (head)->rbh_root = (tmp);                            \
 372         RB_RIGHT(tmp, field) = (elm);                                   \
 373         RB_PARENT(elm, field) = (tmp);                                  \
 374         RB_AUGMENT(tmp);                                                \
 375 } while (0)
 376 
 377 /* Generates prototypes and inline functions */
 378 #define RB_PROTOTYPE(name, type, field, cmp)                            \
 379 void name##_RB_INSERT_COLOR(struct name *, struct type *);      \
 380 void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
 381 struct type *name##_RB_REMOVE(struct name *, struct type *);            \
 382 struct type *name##_RB_INSERT(struct name *, struct type *);            \
 383 struct type *name##_RB_FIND(struct name *, struct type *);              \
 384 struct type *name##_RB_NEXT(struct name *, struct type *);              \
 385 struct type *name##_RB_MINMAX(struct name *, int);
 386 
 387 /* Main rb operation.
 388  * Moves node close to the key of elm to top
 389  */
 390 #define RB_GENERATE(name, type, field, cmp)                             \
 391 void                                                                    \
 392 name##_RB_INSERT_COLOR(struct name *head, struct type *elm)             \
 393 {                                                                       \
 394         struct type *parent, *gparent, *tmp;                            \
 395         while ((parent = RB_PARENT(elm, field)) &&                      \
 396             RB_COLOR(parent, field) == RB_RED) {                        \
 397                 gparent = RB_PARENT(parent, field);                     \
 398                 if (parent == RB_LEFT(gparent, field)) {                \
 399                         tmp = RB_RIGHT(gparent, field);                 \
 400                         if (tmp && RB_COLOR(tmp, field) == RB_RED) {    \
 401                                 RB_COLOR(tmp, field) = RB_BLACK;        \
 402                                 RB_SET_BLACKRED(parent, gparent, field);\
 403                                 elm = gparent;                          \
 404                                 continue;                               \
 405                         }                                               \
 406                         if (RB_RIGHT(parent, field) == elm) {           \
 407                                 RB_ROTATE_LEFT(head, parent, tmp, field);\
 408                                 tmp = parent;                           \
 409                                 parent = elm;                           \
 410                                 elm = tmp;                              \
 411                         }                                               \
 412                         RB_SET_BLACKRED(parent, gparent, field);        \
 413                         RB_ROTATE_RIGHT(head, gparent, tmp, field);     \
 414                 } else {                                                \
 415                         tmp = RB_LEFT(gparent, field);                  \
 416                         if (tmp && RB_COLOR(tmp, field) == RB_RED) {    \
 417                                 RB_COLOR(tmp, field) = RB_BLACK;        \
 418                                 RB_SET_BLACKRED(parent, gparent, field);\
 419                                 elm = gparent;                          \
 420                                 continue;                               \
 421                         }                                               \
 422                         if (RB_LEFT(parent, field) == elm) {            \
 423                                 RB_ROTATE_RIGHT(head, parent, tmp, field);\
 424                                 tmp = parent;                           \
 425                                 parent = elm;                           \
 426                                 elm = tmp;                              \
 427                         }                                               \
 428                         RB_SET_BLACKRED(parent, gparent, field);        \
 429                         RB_ROTATE_LEFT(head, gparent, tmp, field);      \
 430                 }                                                       \
 431         }                                                               \
 432         RB_COLOR(head->rbh_root, field) = RB_BLACK;                  \
 433 }                                                                       \
 434                                                                         \
 435 void                                                                    \
 436 name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
 437 {                                                                       \
 438         struct type *tmp;                                               \
 439         while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&     \
 440             elm != RB_ROOT(head)) {                                     \
 441                 if (RB_LEFT(parent, field) == elm) {                    \
 442                         tmp = RB_RIGHT(parent, field);                  \
 443                         if (RB_COLOR(tmp, field) == RB_RED) {           \
 444                                 RB_SET_BLACKRED(tmp, parent, field);    \
 445                                 RB_ROTATE_LEFT(head, parent, tmp, field);\
 446                                 tmp = RB_RIGHT(parent, field);          \
 447                         }                                               \
 448                         if ((RB_LEFT(tmp, field) == NULL ||             \
 449                             RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
 450                             (RB_RIGHT(tmp, field) == NULL ||            \
 451                             RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
 452                                 RB_COLOR(tmp, field) = RB_RED;          \
 453                                 elm = parent;                           \
 454                                 parent = RB_PARENT(elm, field);         \
 455                         } else {                                        \
 456                                 if (RB_RIGHT(tmp, field) == NULL ||     \
 457                                     RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
 458                                         struct type *oleft;             \
 459                                         if ((oleft = RB_LEFT(tmp, field)))\
 460                                                 RB_COLOR(oleft, field) = RB_BLACK;\
 461                                         RB_COLOR(tmp, field) = RB_RED;  \
 462                                         RB_ROTATE_RIGHT(head, tmp, oleft, field);\
 463                                         tmp = RB_RIGHT(parent, field);  \
 464                                 }                                       \
 465                                 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
 466                                 RB_COLOR(parent, field) = RB_BLACK;     \
 467                                 if (RB_RIGHT(tmp, field))               \
 468                                         RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
 469                                 RB_ROTATE_LEFT(head, parent, tmp, field);\
 470                                 elm = RB_ROOT(head);                    \
 471                                 break;                                  \
 472                         }                                               \
 473                 } else {                                                \
 474                         tmp = RB_LEFT(parent, field);                   \
 475                         if (RB_COLOR(tmp, field) == RB_RED) {           \
 476                                 RB_SET_BLACKRED(tmp, parent, field);    \
 477                                 RB_ROTATE_RIGHT(head, parent, tmp, field);\
 478                                 tmp = RB_LEFT(parent, field);           \
 479                         }                                               \
 480                         if ((RB_LEFT(tmp, field) == NULL ||             \
 481                             RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
 482                             (RB_RIGHT(tmp, field) == NULL ||            \
 483                             RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
 484                                 RB_COLOR(tmp, field) = RB_RED;          \
 485                                 elm = parent;                           \
 486                                 parent = RB_PARENT(elm, field);         \
 487                         } else {                                        \
 488                                 if (RB_LEFT(tmp, field) == NULL ||      \
 489                                     RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
 490                                         struct type *oright;            \
 491                                         if ((oright = RB_RIGHT(tmp, field)))\
 492                                                 RB_COLOR(oright, field) = RB_BLACK;\
 493                                         RB_COLOR(tmp, field) = RB_RED;  \
 494                                         RB_ROTATE_LEFT(head, tmp, oright, field);\
 495                                         tmp = RB_LEFT(parent, field);   \
 496                                 }                                       \
 497                                 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
 498                                 RB_COLOR(parent, field) = RB_BLACK;     \
 499                                 if (RB_LEFT(tmp, field))                \
 500                                         RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
 501                                 RB_ROTATE_RIGHT(head, parent, tmp, field);\
 502                                 elm = RB_ROOT(head);                    \
 503                                 break;                                  \
 504                         }                                               \
 505                 }                                                       \
 506         }                                                               \
 507         if (elm)                                                        \
 508                 RB_COLOR(elm, field) = RB_BLACK;                        \
 509 }                                                                       \
 510                                                                         \
 511 struct type *                                                           \
 512 name##_RB_REMOVE(struct name *head, struct type *elm)                   \
 513 {                                                                       \
 514         struct type *child, *parent, *old = elm;                        \
 515         int color;                                                      \
 516         if (RB_LEFT(elm, field) == NULL)                                \
 517                 child = RB_RIGHT(elm, field);                           \
 518         else if (RB_RIGHT(elm, field) == NULL)                          \
 519                 child = RB_LEFT(elm, field);                            \
 520         else {                                                          \
 521                 struct type *left;                                      \
 522                 elm = RB_RIGHT(elm, field);                             \
 523                 while ((left = RB_LEFT(elm, field)))                    \
 524                         elm = left;                                     \
 525                 child = RB_RIGHT(elm, field);                           \
 526                 parent = RB_PARENT(elm, field);                         \
 527                 color = RB_COLOR(elm, field);                           \
 528                 if (child)                                              \
 529                         RB_PARENT(child, field) = parent;               \
 530                 if (parent) {                                           \
 531                         if (RB_LEFT(parent, field) == elm)              \
 532                                 RB_LEFT(parent, field) = child;         \
 533                         else                                            \
 534                                 RB_RIGHT(parent, field) = child;        \
 535                         RB_AUGMENT(parent);                             \
 536                 } else                                                  \
 537                         RB_ROOT(head) = child;                          \
 538                 if (RB_PARENT(elm, field) == old)                       \
 539                         parent = elm;                                   \
 540                 (elm)->field = (old)->field;                              \
 541                 if (RB_PARENT(old, field)) {                            \
 542                         if (RB_LEFT(RB_PARENT(old, field), field) == old)\
 543                                 RB_LEFT(RB_PARENT(old, field), field) = elm;\
 544                         else                                            \
 545                                 RB_RIGHT(RB_PARENT(old, field), field) = elm;\
 546                         RB_AUGMENT(RB_PARENT(old, field));              \
 547                 } else                                                  \
 548                         RB_ROOT(head) = elm;                            \
 549                 RB_PARENT(RB_LEFT(old, field), field) = elm;            \
 550                 if (RB_RIGHT(old, field))                               \
 551                         RB_PARENT(RB_RIGHT(old, field), field) = elm;   \
 552                 if (parent) {                                           \
 553                         left = parent;                                  \
 554                         do {                                            \
 555                                 RB_AUGMENT(left);                       \
 556                         } while ((left = RB_PARENT(left, field)));      \
 557                 }                                                       \
 558                 goto color;                                             \
 559         }                                                               \
 560         parent = RB_PARENT(elm, field);                                 \
 561         color = RB_COLOR(elm, field);                                   \
 562         if (child)                                                      \
 563                 RB_PARENT(child, field) = parent;                       \
 564         if (parent) {                                                   \
 565                 if (RB_LEFT(parent, field) == elm)                      \
 566                         RB_LEFT(parent, field) = child;                 \
 567                 else                                                    \
 568                         RB_RIGHT(parent, field) = child;                \
 569                 RB_AUGMENT(parent);                                     \
 570         } else                                                          \
 571                 RB_ROOT(head) = child;                                  \
 572 color:                                                                  \
 573         if (color == RB_BLACK)                                          \
 574                 name##_RB_REMOVE_COLOR(head, parent, child);            \
 575         return (old);                                                   \
 576 }                                                                       \
 577                                                                         \
 578 /* Inserts a node into the RB tree */                                   \
 579 struct type *                                                           \
 580 name##_RB_INSERT(struct name *head, struct type *elm)                   \
 581 {                                                                       \
 582         struct type *tmp;                                               \
 583         struct type *parent = NULL;                                     \
 584         int comp = 0;                                                   \
 585         tmp = RB_ROOT(head);                                            \
 586         while (tmp) {                                                   \
 587                 parent = tmp;                                           \
 588                 comp = (cmp)(elm, parent);                              \
 589                 if (comp < 0)                                                \
 590                         tmp = RB_LEFT(tmp, field);                      \
 591                 else if (comp > 0)                                   \
 592                         tmp = RB_RIGHT(tmp, field);                     \
 593                 else                                                    \
 594                         return (tmp);                                   \
 595         }                                                               \
 596         RB_SET(elm, parent, field);                                     \
 597         if (parent != NULL) {                                           \
 598                 if (comp < 0)                                                \
 599                         RB_LEFT(parent, field) = elm;                   \
 600                 else                                                    \
 601                         RB_RIGHT(parent, field) = elm;                  \
 602                 RB_AUGMENT(parent);                                     \
 603         } else                                                          \
 604                 RB_ROOT(head) = elm;                                    \
 605         name##_RB_INSERT_COLOR(head, elm);                              \
 606         return (NULL);                                                  \
 607 }                                                                       \
 608                                                                         \
 609 /* Finds the node with the same key as elm */                           \
 610 struct type *                                                           \
 611 name##_RB_FIND(struct name *head, struct type *elm)                     \
 612 {                                                                       \
 613         struct type *tmp = RB_ROOT(head);                               \
 614         int comp;                                                       \
 615         while (tmp) {                                                   \
 616                 comp = cmp(elm, tmp);                                   \
 617                 if (comp < 0)                                                \
 618                         tmp = RB_LEFT(tmp, field);                      \
 619                 else if (comp > 0)                                   \
 620                         tmp = RB_RIGHT(tmp, field);                     \
 621                 else                                                    \
 622                         return (tmp);                                   \
 623         }                                                               \
 624         return (NULL);                                                  \
 625 }                                                                       \
 626                                                                         \
 627 struct type *                                                           \
 628 name##_RB_NEXT(struct name *head, struct type *elm)                     \
 629 {                                                                       \
 630         if (RB_RIGHT(elm, field)) {                                     \
 631                 elm = RB_RIGHT(elm, field);                             \
 632                 while (RB_LEFT(elm, field))                             \
 633                         elm = RB_LEFT(elm, field);                      \
 634         } else {                                                        \
 635                 if (RB_PARENT(elm, field) &&                            \
 636                     (elm == RB_LEFT(RB_PARENT(elm, field), field)))     \
 637                         elm = RB_PARENT(elm, field);                    \
 638                 else {                                                  \
 639                         while (RB_PARENT(elm, field) &&                 \
 640                             (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
 641                                 elm = RB_PARENT(elm, field);            \
 642                         elm = RB_PARENT(elm, field);                    \
 643                 }                                                       \
 644         }                                                               \
 645         return (elm);                                                   \
 646 }                                                                       \
 647                                                                         \
 648 struct type *                                                           \
 649 name##_RB_MINMAX(struct name *head, int val)                            \
 650 {                                                                       \
 651         struct type *tmp = RB_ROOT(head);                               \
 652         struct type *parent = NULL;                                     \
 653         while (tmp) {                                                   \
 654                 parent = tmp;                                           \
 655                 if (val < 0)                                         \
 656                         tmp = RB_LEFT(tmp, field);                      \
 657                 else                                                    \
 658                         tmp = RB_RIGHT(tmp, field);                     \
 659         }                                                               \
 660         return (parent);                                                \
 661 }
 662 
 663 #define RB_NEGINF       -1
 664 #define RB_INF  1
 665 
 666 #define RB_INSERT(name, x, y)   name##_RB_INSERT(x, y)
 667 #define RB_REMOVE(name, x, y)   name##_RB_REMOVE(x, y)
 668 #define RB_FIND(name, x, y)     name##_RB_FIND(x, y)
 669 #define RB_NEXT(name, x, y)     name##_RB_NEXT(x, y)
 670 #define RB_MIN(name, x)         name##_RB_MINMAX(x, RB_NEGINF)
 671 #define RB_MAX(name, x)         name##_RB_MINMAX(x, RB_INF)
 672 
 673 #define RB_FOREACH(x, name, head)                                       \
 674         for ((x) = RB_MIN(name, head);                                  \
 675              (x) != NULL;                                               \
 676              (x) = name##_RB_NEXT(head, x))
 677 
 678 #ifdef __cplusplus
 679 }
 680 #endif
 681 
 682 #endif /* _SYS_TREE_H */