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