tree.h - randomcrap - random crap programs of varying quality
 (HTM) git clone git://git.codemadness.org/randomcrap
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tree.h (25520B)
       ---
            1 /*        $OpenBSD: tree.h,v 1.29 2017/07/30 19:27:20 deraadt 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 /*
           31  * This file defines data structures for red-black trees.
           32  *
           33  * A red-black tree is a binary search tree with the node color as an
           34  * extra attribute.  It fulfills a set of conditions:
           35  *        - every search path from the root to a leaf consists of the
           36  *          same number of black nodes,
           37  *        - each red node (except for the root) has a black parent,
           38  *        - each leaf node is black.
           39  *
           40  * Every operation on a red-black tree is bounded as O(lg n).
           41  * The maximum height of a red-black tree is 2lg (n+1).
           42  */
           43 
           44 /* Macros that define a red-black tree */
           45 #define RB_HEAD(name, type)                                                \
           46 struct name {                                                                \
           47         struct type *rbh_root; /* root of the tree */                        \
           48 }
           49 
           50 #define RB_INITIALIZER(root)                                                \
           51         { NULL }
           52 
           53 #define RB_INIT(root) do {                                                \
           54         (root)->rbh_root = NULL;                                        \
           55 } while (0)
           56 
           57 #define RB_BLACK        0
           58 #define RB_RED                1
           59 #define RB_ENTRY(type)                                                        \
           60 struct {                                                                \
           61         struct type *rbe_left;                /* left element */                \
           62         struct type *rbe_right;                /* right element */                \
           63         struct type *rbe_parent;        /* parent element */                \
           64         int rbe_color;                        /* node color */                \
           65 }
           66 
           67 #define RB_LEFT(elm, field)                (elm)->field.rbe_left
           68 #define RB_RIGHT(elm, field)                (elm)->field.rbe_right
           69 #define RB_PARENT(elm, field)                (elm)->field.rbe_parent
           70 #define RB_COLOR(elm, field)                (elm)->field.rbe_color
           71 #define RB_ROOT(head)                        (head)->rbh_root
           72 #define RB_EMPTY(head)                        (RB_ROOT(head) == NULL)
           73 
           74 #define RB_SET(elm, parent, field) do {                                        \
           75         RB_PARENT(elm, field) = parent;                                        \
           76         RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;                \
           77         RB_COLOR(elm, field) = RB_RED;                                        \
           78 } while (0)
           79 
           80 #define RB_SET_BLACKRED(black, red, field) do {                                \
           81         RB_COLOR(black, field) = RB_BLACK;                                \
           82         RB_COLOR(red, field) = RB_RED;                                        \
           83 } while (0)
           84 
           85 #ifndef RB_AUGMENT
           86 #define RB_AUGMENT(x)        do {} while (0)
           87 #endif
           88 
           89 #define RB_ROTATE_LEFT(head, elm, tmp, field) do {                        \
           90         (tmp) = RB_RIGHT(elm, field);                                        \
           91         if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {                \
           92                 RB_PARENT(RB_LEFT(tmp, field), field) = (elm);                \
           93         }                                                                \
           94         RB_AUGMENT(elm);                                                \
           95         if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {                \
           96                 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))        \
           97                         RB_LEFT(RB_PARENT(elm, field), field) = (tmp);        \
           98                 else                                                        \
           99                         RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);        \
          100         } else                                                                \
          101                 (head)->rbh_root = (tmp);                                \
          102         RB_LEFT(tmp, field) = (elm);                                        \
          103         RB_PARENT(elm, field) = (tmp);                                        \
          104         RB_AUGMENT(tmp);                                                \
          105         if ((RB_PARENT(tmp, field)))                                        \
          106                 RB_AUGMENT(RB_PARENT(tmp, field));                        \
          107 } while (0)
          108 
          109 #define RB_ROTATE_RIGHT(head, elm, tmp, field) do {                        \
          110         (tmp) = RB_LEFT(elm, field);                                        \
          111         if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {                \
          112                 RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);                \
          113         }                                                                \
          114         RB_AUGMENT(elm);                                                \
          115         if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {                \
          116                 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))        \
          117                         RB_LEFT(RB_PARENT(elm, field), field) = (tmp);        \
          118                 else                                                        \
          119                         RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);        \
          120         } else                                                                \
          121                 (head)->rbh_root = (tmp);                                \
          122         RB_RIGHT(tmp, field) = (elm);                                        \
          123         RB_PARENT(elm, field) = (tmp);                                        \
          124         RB_AUGMENT(tmp);                                                \
          125         if ((RB_PARENT(tmp, field)))                                        \
          126                 RB_AUGMENT(RB_PARENT(tmp, field));                        \
          127 } while (0)
          128 
          129 /* Generates prototypes and inline functions */
          130 #define        RB_PROTOTYPE(name, type, field, cmp)                                \
          131         RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
          132 #define        RB_PROTOTYPE_STATIC(name, type, field, cmp)                        \
          133         RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
          134 #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)                \
          135 attr void name##_RB_INSERT_COLOR(struct name *, struct type *);                \
          136 attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
          137 attr struct type *name##_RB_REMOVE(struct name *, struct type *);        \
          138 attr struct type *name##_RB_INSERT(struct name *, struct type *);        \
          139 attr struct type *name##_RB_FIND(struct name *, struct type *);                \
          140 attr struct type *name##_RB_NFIND(struct name *, struct type *);        \
          141 attr struct type *name##_RB_NEXT(struct type *);                        \
          142 attr struct type *name##_RB_PREV(struct type *);                        \
          143 attr struct type *name##_RB_MINMAX(struct name *, int);                        \
          144                                                                         \
          145 
          146 /* Main rb operation.
          147  * Moves node close to the key of elm to top
          148  */
          149 #define        RB_GENERATE(name, type, field, cmp)                                \
          150         RB_GENERATE_INTERNAL(name, type, field, cmp,)
          151 #define        RB_GENERATE_STATIC(name, type, field, cmp)                        \
          152         RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
          153 #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)                \
          154 attr void                                                                \
          155 name##_RB_INSERT_COLOR(struct name *head, struct type *elm)                \
          156 {                                                                        \
          157         struct type *parent, *gparent, *tmp;                                \
          158         while ((parent = RB_PARENT(elm, field)) &&                        \
          159             RB_COLOR(parent, field) == RB_RED) {                        \
          160                 gparent = RB_PARENT(parent, field);                        \
          161                 if (parent == RB_LEFT(gparent, field)) {                \
          162                         tmp = RB_RIGHT(gparent, field);                        \
          163                         if (tmp && RB_COLOR(tmp, field) == RB_RED) {        \
          164                                 RB_COLOR(tmp, field) = RB_BLACK;        \
          165                                 RB_SET_BLACKRED(parent, gparent, field);\
          166                                 elm = gparent;                                \
          167                                 continue;                                \
          168                         }                                                \
          169                         if (RB_RIGHT(parent, field) == elm) {                \
          170                                 RB_ROTATE_LEFT(head, parent, tmp, field);\
          171                                 tmp = parent;                                \
          172                                 parent = elm;                                \
          173                                 elm = tmp;                                \
          174                         }                                                \
          175                         RB_SET_BLACKRED(parent, gparent, field);        \
          176                         RB_ROTATE_RIGHT(head, gparent, tmp, field);        \
          177                 } else {                                                \
          178                         tmp = RB_LEFT(gparent, field);                        \
          179                         if (tmp && RB_COLOR(tmp, field) == RB_RED) {        \
          180                                 RB_COLOR(tmp, field) = RB_BLACK;        \
          181                                 RB_SET_BLACKRED(parent, gparent, field);\
          182                                 elm = gparent;                                \
          183                                 continue;                                \
          184                         }                                                \
          185                         if (RB_LEFT(parent, field) == elm) {                \
          186                                 RB_ROTATE_RIGHT(head, parent, tmp, field);\
          187                                 tmp = parent;                                \
          188                                 parent = elm;                                \
          189                                 elm = tmp;                                \
          190                         }                                                \
          191                         RB_SET_BLACKRED(parent, gparent, field);        \
          192                         RB_ROTATE_LEFT(head, gparent, tmp, field);        \
          193                 }                                                        \
          194         }                                                                \
          195         RB_COLOR(head->rbh_root, field) = RB_BLACK;                        \
          196 }                                                                        \
          197                                                                         \
          198 attr void                                                                \
          199 name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
          200 {                                                                        \
          201         struct type *tmp;                                                \
          202         while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&        \
          203             elm != RB_ROOT(head)) {                                        \
          204                 if (RB_LEFT(parent, field) == elm) {                        \
          205                         tmp = RB_RIGHT(parent, field);                        \
          206                         if (RB_COLOR(tmp, field) == RB_RED) {                \
          207                                 RB_SET_BLACKRED(tmp, parent, field);        \
          208                                 RB_ROTATE_LEFT(head, parent, tmp, field);\
          209                                 tmp = RB_RIGHT(parent, field);                \
          210                         }                                                \
          211                         if ((RB_LEFT(tmp, field) == NULL ||                \
          212                             RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
          213                             (RB_RIGHT(tmp, field) == NULL ||                \
          214                             RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
          215                                 RB_COLOR(tmp, field) = RB_RED;                \
          216                                 elm = parent;                                \
          217                                 parent = RB_PARENT(elm, field);                \
          218                         } else {                                        \
          219                                 if (RB_RIGHT(tmp, field) == NULL ||        \
          220                                     RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
          221                                         struct type *oleft;                \
          222                                         if ((oleft = RB_LEFT(tmp, field)))\
          223                                                 RB_COLOR(oleft, field) = RB_BLACK;\
          224                                         RB_COLOR(tmp, field) = RB_RED;        \
          225                                         RB_ROTATE_RIGHT(head, tmp, oleft, field);\
          226                                         tmp = RB_RIGHT(parent, field);        \
          227                                 }                                        \
          228                                 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
          229                                 RB_COLOR(parent, field) = RB_BLACK;        \
          230                                 if (RB_RIGHT(tmp, field))                \
          231                                         RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
          232                                 RB_ROTATE_LEFT(head, parent, tmp, field);\
          233                                 elm = RB_ROOT(head);                        \
          234                                 break;                                        \
          235                         }                                                \
          236                 } else {                                                \
          237                         tmp = RB_LEFT(parent, field);                        \
          238                         if (RB_COLOR(tmp, field) == RB_RED) {                \
          239                                 RB_SET_BLACKRED(tmp, parent, field);        \
          240                                 RB_ROTATE_RIGHT(head, parent, tmp, field);\
          241                                 tmp = RB_LEFT(parent, field);                \
          242                         }                                                \
          243                         if ((RB_LEFT(tmp, field) == NULL ||                \
          244                             RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
          245                             (RB_RIGHT(tmp, field) == NULL ||                \
          246                             RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
          247                                 RB_COLOR(tmp, field) = RB_RED;                \
          248                                 elm = parent;                                \
          249                                 parent = RB_PARENT(elm, field);                \
          250                         } else {                                        \
          251                                 if (RB_LEFT(tmp, field) == NULL ||        \
          252                                     RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
          253                                         struct type *oright;                \
          254                                         if ((oright = RB_RIGHT(tmp, field)))\
          255                                                 RB_COLOR(oright, field) = RB_BLACK;\
          256                                         RB_COLOR(tmp, field) = RB_RED;        \
          257                                         RB_ROTATE_LEFT(head, tmp, oright, field);\
          258                                         tmp = RB_LEFT(parent, field);        \
          259                                 }                                        \
          260                                 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
          261                                 RB_COLOR(parent, field) = RB_BLACK;        \
          262                                 if (RB_LEFT(tmp, field))                \
          263                                         RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
          264                                 RB_ROTATE_RIGHT(head, parent, tmp, field);\
          265                                 elm = RB_ROOT(head);                        \
          266                                 break;                                        \
          267                         }                                                \
          268                 }                                                        \
          269         }                                                                \
          270         if (elm)                                                        \
          271                 RB_COLOR(elm, field) = RB_BLACK;                        \
          272 }                                                                        \
          273                                                                         \
          274 attr struct type *                                                        \
          275 name##_RB_REMOVE(struct name *head, struct type *elm)                        \
          276 {                                                                        \
          277         struct type *child, *parent, *old = elm;                        \
          278         int color;                                                        \
          279         if (RB_LEFT(elm, field) == NULL)                                \
          280                 child = RB_RIGHT(elm, field);                                \
          281         else if (RB_RIGHT(elm, field) == NULL)                                \
          282                 child = RB_LEFT(elm, field);                                \
          283         else {                                                                \
          284                 struct type *left;                                        \
          285                 elm = RB_RIGHT(elm, field);                                \
          286                 while ((left = RB_LEFT(elm, field)))                        \
          287                         elm = left;                                        \
          288                 child = RB_RIGHT(elm, field);                                \
          289                 parent = RB_PARENT(elm, field);                                \
          290                 color = RB_COLOR(elm, field);                                \
          291                 if (child)                                                \
          292                         RB_PARENT(child, field) = parent;                \
          293                 if (parent) {                                                \
          294                         if (RB_LEFT(parent, field) == elm)                \
          295                                 RB_LEFT(parent, field) = child;                \
          296                         else                                                \
          297                                 RB_RIGHT(parent, field) = child;        \
          298                         RB_AUGMENT(parent);                                \
          299                 } else                                                        \
          300                         RB_ROOT(head) = child;                                \
          301                 if (RB_PARENT(elm, field) == old)                        \
          302                         parent = elm;                                        \
          303                 (elm)->field = (old)->field;                                \
          304                 if (RB_PARENT(old, field)) {                                \
          305                         if (RB_LEFT(RB_PARENT(old, field), field) == old)\
          306                                 RB_LEFT(RB_PARENT(old, field), field) = elm;\
          307                         else                                                \
          308                                 RB_RIGHT(RB_PARENT(old, field), field) = elm;\
          309                         RB_AUGMENT(RB_PARENT(old, field));                \
          310                 } else                                                        \
          311                         RB_ROOT(head) = elm;                                \
          312                 RB_PARENT(RB_LEFT(old, field), field) = elm;                \
          313                 if (RB_RIGHT(old, field))                                \
          314                         RB_PARENT(RB_RIGHT(old, field), field) = elm;        \
          315                 if (parent) {                                                \
          316                         left = parent;                                        \
          317                         do {                                                \
          318                                 RB_AUGMENT(left);                        \
          319                         } while ((left = RB_PARENT(left, field)));        \
          320                 }                                                        \
          321                 goto color;                                                \
          322         }                                                                \
          323         parent = RB_PARENT(elm, field);                                        \
          324         color = RB_COLOR(elm, field);                                        \
          325         if (child)                                                        \
          326                 RB_PARENT(child, field) = parent;                        \
          327         if (parent) {                                                        \
          328                 if (RB_LEFT(parent, field) == elm)                        \
          329                         RB_LEFT(parent, field) = child;                        \
          330                 else                                                        \
          331                         RB_RIGHT(parent, field) = child;                \
          332                 RB_AUGMENT(parent);                                        \
          333         } else                                                                \
          334                 RB_ROOT(head) = child;                                        \
          335 color:                                                                        \
          336         if (color == RB_BLACK)                                                \
          337                 name##_RB_REMOVE_COLOR(head, parent, child);                \
          338         return (old);                                                        \
          339 }                                                                        \
          340                                                                         \
          341 /* Inserts a node into the RB tree */                                        \
          342 attr struct type *                                                        \
          343 name##_RB_INSERT(struct name *head, struct type *elm)                        \
          344 {                                                                        \
          345         struct type *tmp;                                                \
          346         struct type *parent = NULL;                                        \
          347         int comp = 0;                                                        \
          348         tmp = RB_ROOT(head);                                                \
          349         while (tmp) {                                                        \
          350                 parent = tmp;                                                \
          351                 comp = (cmp)(elm, parent);                                \
          352                 if (comp < 0)                                                \
          353                         tmp = RB_LEFT(tmp, field);                        \
          354                 else if (comp > 0)                                        \
          355                         tmp = RB_RIGHT(tmp, field);                        \
          356                 else                                                        \
          357                         return (tmp);                                        \
          358         }                                                                \
          359         RB_SET(elm, parent, field);                                        \
          360         if (parent != NULL) {                                                \
          361                 if (comp < 0)                                                \
          362                         RB_LEFT(parent, field) = elm;                        \
          363                 else                                                        \
          364                         RB_RIGHT(parent, field) = elm;                        \
          365                 RB_AUGMENT(parent);                                        \
          366         } else                                                                \
          367                 RB_ROOT(head) = elm;                                        \
          368         name##_RB_INSERT_COLOR(head, elm);                                \
          369         return (NULL);                                                        \
          370 }                                                                        \
          371                                                                         \
          372 /* Finds the node with the same key as elm */                                \
          373 attr struct type *                                                        \
          374 name##_RB_FIND(struct name *head, struct type *elm)                        \
          375 {                                                                        \
          376         struct type *tmp = RB_ROOT(head);                                \
          377         int comp;                                                        \
          378         while (tmp) {                                                        \
          379                 comp = cmp(elm, tmp);                                        \
          380                 if (comp < 0)                                                \
          381                         tmp = RB_LEFT(tmp, field);                        \
          382                 else if (comp > 0)                                        \
          383                         tmp = RB_RIGHT(tmp, field);                        \
          384                 else                                                        \
          385                         return (tmp);                                        \
          386         }                                                                \
          387         return (NULL);                                                        \
          388 }                                                                        \
          389                                                                         \
          390 /* Finds the first node greater than or equal to the search key */        \
          391 attr struct type *                                                        \
          392 name##_RB_NFIND(struct name *head, struct type *elm)                        \
          393 {                                                                        \
          394         struct type *tmp = RB_ROOT(head);                                \
          395         struct type *res = NULL;                                        \
          396         int comp;                                                        \
          397         while (tmp) {                                                        \
          398                 comp = cmp(elm, tmp);                                        \
          399                 if (comp < 0) {                                                \
          400                         res = tmp;                                        \
          401                         tmp = RB_LEFT(tmp, field);                        \
          402                 }                                                        \
          403                 else if (comp > 0)                                        \
          404                         tmp = RB_RIGHT(tmp, field);                        \
          405                 else                                                        \
          406                         return (tmp);                                        \
          407         }                                                                \
          408         return (res);                                                        \
          409 }                                                                        \
          410                                                                         \
          411 /* ARGSUSED */                                                                \
          412 attr struct type *                                                        \
          413 name##_RB_NEXT(struct type *elm)                                        \
          414 {                                                                        \
          415         if (RB_RIGHT(elm, field)) {                                        \
          416                 elm = RB_RIGHT(elm, field);                                \
          417                 while (RB_LEFT(elm, field))                                \
          418                         elm = RB_LEFT(elm, field);                        \
          419         } else {                                                        \
          420                 if (RB_PARENT(elm, field) &&                                \
          421                     (elm == RB_LEFT(RB_PARENT(elm, field), field)))        \
          422                         elm = RB_PARENT(elm, field);                        \
          423                 else {                                                        \
          424                         while (RB_PARENT(elm, field) &&                        \
          425                             (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
          426                                 elm = RB_PARENT(elm, field);                \
          427                         elm = RB_PARENT(elm, field);                        \
          428                 }                                                        \
          429         }                                                                \
          430         return (elm);                                                        \
          431 }                                                                        \
          432                                                                         \
          433 /* ARGSUSED */                                                                \
          434 attr struct type *                                                        \
          435 name##_RB_PREV(struct type *elm)                                        \
          436 {                                                                        \
          437         if (RB_LEFT(elm, field)) {                                        \
          438                 elm = RB_LEFT(elm, field);                                \
          439                 while (RB_RIGHT(elm, field))                                \
          440                         elm = RB_RIGHT(elm, field);                        \
          441         } else {                                                        \
          442                 if (RB_PARENT(elm, field) &&                                \
          443                     (elm == RB_RIGHT(RB_PARENT(elm, field), field)))        \
          444                         elm = RB_PARENT(elm, field);                        \
          445                 else {                                                        \
          446                         while (RB_PARENT(elm, field) &&                        \
          447                             (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
          448                                 elm = RB_PARENT(elm, field);                \
          449                         elm = RB_PARENT(elm, field);                        \
          450                 }                                                        \
          451         }                                                                \
          452         return (elm);                                                        \
          453 }                                                                        \
          454                                                                         \
          455 attr struct type *                                                        \
          456 name##_RB_MINMAX(struct name *head, int val)                                \
          457 {                                                                        \
          458         struct type *tmp = RB_ROOT(head);                                \
          459         struct type *parent = NULL;                                        \
          460         while (tmp) {                                                        \
          461                 parent = tmp;                                                \
          462                 if (val < 0)                                                \
          463                         tmp = RB_LEFT(tmp, field);                        \
          464                 else                                                        \
          465                         tmp = RB_RIGHT(tmp, field);                        \
          466         }                                                                \
          467         return (parent);                                                \
          468 }
          469 
          470 #define RB_NEGINF        -1
          471 #define RB_INF        1
          472 
          473 #define RB_INSERT(name, x, y)        name##_RB_INSERT(x, y)
          474 #define RB_REMOVE(name, x, y)        name##_RB_REMOVE(x, y)
          475 #define RB_FIND(name, x, y)        name##_RB_FIND(x, y)
          476 #define RB_NFIND(name, x, y)        name##_RB_NFIND(x, y)
          477 #define RB_NEXT(name, x, y)        name##_RB_NEXT(y)
          478 #define RB_PREV(name, x, y)        name##_RB_PREV(y)
          479 #define RB_MIN(name, x)                name##_RB_MINMAX(x, RB_NEGINF)
          480 #define RB_MAX(name, x)                name##_RB_MINMAX(x, RB_INF)
          481 
          482 #define RB_FOREACH(x, name, head)                                        \
          483         for ((x) = RB_MIN(name, head);                                        \
          484              (x) != NULL;                                                \
          485              (x) = name##_RB_NEXT(x))
          486 
          487 #define RB_FOREACH_SAFE(x, name, head, y)                                \
          488         for ((x) = RB_MIN(name, head);                                        \
          489             ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1);                \
          490              (x) = (y))
          491 
          492 #define RB_FOREACH_REVERSE(x, name, head)                                \
          493         for ((x) = RB_MAX(name, head);                                        \
          494              (x) != NULL;                                                \
          495              (x) = name##_RB_PREV(x))
          496 
          497 #define RB_FOREACH_REVERSE_SAFE(x, name, head, y)                        \
          498         for ((x) = RB_MAX(name, head);                                        \
          499             ((x) != NULL) && ((y) = name##_RB_PREV(x), 1);                \
          500              (x) = (y))
          501 
          502 
          503 /*
          504  * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
          505  *
          506  * Permission to use, copy, modify, and distribute this software for any
          507  * purpose with or without fee is hereby granted, provided that the above
          508  * copyright notice and this permission notice appear in all copies.
          509  *
          510  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
          511  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
          512  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
          513  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
          514  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
          515  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
          516  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
          517  */
          518 
          519 struct rb_type {
          520         int                (*t_compare)(const void *, const void *);
          521         void                (*t_augment)(void *);
          522         unsigned int          t_offset;        /* offset of rb_entry in type */
          523 };
          524 
          525 struct rb_tree {
          526         struct rb_entry        *rbt_root;
          527 };
          528 
          529 struct rb_entry {
          530         struct rb_entry         *rbt_parent;
          531         struct rb_entry         *rbt_left;
          532         struct rb_entry         *rbt_right;
          533         unsigned int          rbt_color;
          534 };
          535 
          536 #define RBT_HEAD(_name, _type)                                                \
          537 struct _name {                                                                \
          538         struct rb_tree rbh_root;                                        \
          539 }
          540 
          541 #define RBT_ENTRY(_type)        struct rb_entry
          542 
          543 static inline void
          544 _rb_init(struct rb_tree *rbt)
          545 {
          546         rbt->rbt_root = NULL;
          547 }
          548 
          549 static inline int
          550 _rb_empty(struct rb_tree *rbt)
          551 {
          552         return (rbt->rbt_root == NULL);
          553 }
          554 
          555 void        *_rb_insert(const struct rb_type *, struct rb_tree *, void *);
          556 void        *_rb_remove(const struct rb_type *, struct rb_tree *, void *);
          557 void        *_rb_find(const struct rb_type *, struct rb_tree *, const void *);
          558 void        *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *);
          559 void        *_rb_root(const struct rb_type *, struct rb_tree *);
          560 void        *_rb_min(const struct rb_type *, struct rb_tree *);
          561 void        *_rb_max(const struct rb_type *, struct rb_tree *);
          562 void        *_rb_next(const struct rb_type *, void *);
          563 void        *_rb_prev(const struct rb_type *, void *);
          564 void        *_rb_left(const struct rb_type *, void *);
          565 void        *_rb_right(const struct rb_type *, void *);
          566 void        *_rb_parent(const struct rb_type *, void *);
          567 void         _rb_set_left(const struct rb_type *, void *, void *);
          568 void         _rb_set_right(const struct rb_type *, void *, void *);
          569 void         _rb_set_parent(const struct rb_type *, void *, void *);
          570 void         _rb_poison(const struct rb_type *, void *, unsigned long);
          571 int         _rb_check(const struct rb_type *, void *, unsigned long);
          572 
          573 #define RBT_INITIALIZER(_head)        { { NULL } }
          574 
          575 #define RBT_PROTOTYPE(_name, _type, _field, _cmp)                        \
          576 extern const struct rb_type *const _name##_RBT_TYPE;                        \
          577                                                                         \
          578 __unused static inline void                                                \
          579 _name##_RBT_INIT(struct _name *head)                                        \
          580 {                                                                        \
          581         _rb_init(&head->rbh_root);                                        \
          582 }                                                                        \
          583                                                                         \
          584 __unused static inline struct _type *                                        \
          585 _name##_RBT_INSERT(struct _name *head, struct _type *elm)                \
          586 {                                                                        \
          587         return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm);        \
          588 }                                                                        \
          589                                                                         \
          590 __unused static inline struct _type *                                        \
          591 _name##_RBT_REMOVE(struct _name *head, struct _type *elm)                \
          592 {                                                                        \
          593         return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm);        \
          594 }                                                                        \
          595                                                                         \
          596 __unused static inline struct _type *                                        \
          597 _name##_RBT_FIND(struct _name *head, const struct _type *key)                \
          598 {                                                                        \
          599         return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key);        \
          600 }                                                                        \
          601                                                                         \
          602 __unused static inline struct _type *                                        \
          603 _name##_RBT_NFIND(struct _name *head, const struct _type *key)                \
          604 {                                                                        \
          605         return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key);        \
          606 }                                                                        \
          607                                                                         \
          608 __unused static inline struct _type *                                        \
          609 _name##_RBT_ROOT(struct _name *head)                                        \
          610 {                                                                        \
          611         return _rb_root(_name##_RBT_TYPE, &head->rbh_root);                \
          612 }                                                                        \
          613                                                                         \
          614 __unused static inline int                                                \
          615 _name##_RBT_EMPTY(struct _name *head)                                        \
          616 {                                                                        \
          617         return _rb_empty(&head->rbh_root);                                \
          618 }                                                                        \
          619                                                                         \
          620 __unused static inline struct _type *                                        \
          621 _name##_RBT_MIN(struct _name *head)                                        \
          622 {                                                                        \
          623         return _rb_min(_name##_RBT_TYPE, &head->rbh_root);                \
          624 }                                                                        \
          625                                                                         \
          626 __unused static inline struct _type *                                        \
          627 _name##_RBT_MAX(struct _name *head)                                        \
          628 {                                                                        \
          629         return _rb_max(_name##_RBT_TYPE, &head->rbh_root);                \
          630 }                                                                        \
          631                                                                         \
          632 __unused static inline struct _type *                                        \
          633 _name##_RBT_NEXT(struct _type *elm)                                        \
          634 {                                                                        \
          635         return _rb_next(_name##_RBT_TYPE, elm);                                \
          636 }                                                                        \
          637                                                                         \
          638 __unused static inline struct _type *                                        \
          639 _name##_RBT_PREV(struct _type *elm)                                        \
          640 {                                                                        \
          641         return _rb_prev(_name##_RBT_TYPE, elm);                                \
          642 }                                                                        \
          643                                                                         \
          644 __unused static inline struct _type *                                        \
          645 _name##_RBT_LEFT(struct _type *elm)                                        \
          646 {                                                                        \
          647         return _rb_left(_name##_RBT_TYPE, elm);                                \
          648 }                                                                        \
          649                                                                         \
          650 __unused static inline struct _type *                                        \
          651 _name##_RBT_RIGHT(struct _type *elm)                                        \
          652 {                                                                        \
          653         return _rb_right(_name##_RBT_TYPE, elm);                        \
          654 }                                                                        \
          655                                                                         \
          656 __unused static inline struct _type *                                        \
          657 _name##_RBT_PARENT(struct _type *elm)                                        \
          658 {                                                                        \
          659         return _rb_parent(_name##_RBT_TYPE, elm);                        \
          660 }                                                                        \
          661                                                                         \
          662 __unused static inline void                                                \
          663 _name##_RBT_SET_LEFT(struct _type *elm, struct _type *left)                \
          664 {                                                                        \
          665         return _rb_set_left(_name##_RBT_TYPE, elm, left);                \
          666 }                                                                        \
          667                                                                         \
          668 __unused static inline void                                                \
          669 _name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right)                \
          670 {                                                                        \
          671         return _rb_set_right(_name##_RBT_TYPE, elm, right);                \
          672 }                                                                        \
          673                                                                         \
          674 __unused static inline void                                                \
          675 _name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent)                \
          676 {                                                                        \
          677         return _rb_set_parent(_name##_RBT_TYPE, elm, parent);                \
          678 }                                                                        \
          679                                                                         \
          680 __unused static inline void                                                \
          681 _name##_RBT_POISON(struct _type *elm, unsigned long poison)                \
          682 {                                                                        \
          683         return _rb_poison(_name##_RBT_TYPE, elm, poison);                \
          684 }                                                                        \
          685                                                                         \
          686 __unused static inline int                                                \
          687 _name##_RBT_CHECK(struct _type *elm, unsigned long poison)                \
          688 {                                                                        \
          689         return _rb_check(_name##_RBT_TYPE, elm, poison);                \
          690 }
          691 
          692 #define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug)                \
          693 static int                                                                \
          694 _name##_RBT_COMPARE(const void *lptr, const void *rptr)                        \
          695 {                                                                        \
          696         const struct _type *l = lptr, *r = rptr;                        \
          697         return _cmp(l, r);                                                \
          698 }                                                                        \
          699 static const struct rb_type _name##_RBT_INFO = {                        \
          700         _name##_RBT_COMPARE,                                                \
          701         _aug,                                                                \
          702         offsetof(struct _type, _field),                                        \
          703 };                                                                        \
          704 const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO
          705 
          706 #define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug)                \
          707 static void                                                                \
          708 _name##_RBT_AUGMENT(void *ptr)                                                \
          709 {                                                                        \
          710         struct _type *p = ptr;                                                \
          711         return _aug(p);                                                        \
          712 }                                                                        \
          713 RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)
          714 
          715 #define RBT_GENERATE(_name, _type, _field, _cmp)                        \
          716     RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
          717 
          718 #define RBT_INIT(_name, _head)                _name##_RBT_INIT(_head)
          719 #define RBT_INSERT(_name, _head, _elm)        _name##_RBT_INSERT(_head, _elm)
          720 #define RBT_REMOVE(_name, _head, _elm)        _name##_RBT_REMOVE(_head, _elm)
          721 #define RBT_FIND(_name, _head, _key)        _name##_RBT_FIND(_head, _key)
          722 #define RBT_NFIND(_name, _head, _key)        _name##_RBT_NFIND(_head, _key)
          723 #define RBT_ROOT(_name, _head)                _name##_RBT_ROOT(_head)
          724 #define RBT_EMPTY(_name, _head)                _name##_RBT_EMPTY(_head)
          725 #define RBT_MIN(_name, _head)                _name##_RBT_MIN(_head)
          726 #define RBT_MAX(_name, _head)                _name##_RBT_MAX(_head)
          727 #define RBT_NEXT(_name, _elm)                _name##_RBT_NEXT(_elm)
          728 #define RBT_PREV(_name, _elm)                _name##_RBT_PREV(_elm)
          729 #define RBT_LEFT(_name, _elm)                _name##_RBT_LEFT(_elm)
          730 #define RBT_RIGHT(_name, _elm)                _name##_RBT_RIGHT(_elm)
          731 #define RBT_PARENT(_name, _elm)                _name##_RBT_PARENT(_elm)
          732 #define RBT_SET_LEFT(_name, _elm, _l)        _name##_RBT_SET_LEFT(_elm, _l)
          733 #define RBT_SET_RIGHT(_name, _elm, _r)        _name##_RBT_SET_RIGHT(_elm, _r)
          734 #define RBT_SET_PARENT(_name, _elm, _p)        _name##_RBT_SET_PARENT(_elm, _p)
          735 #define RBT_POISON(_name, _elm, _p)        _name##_RBT_POISON(_elm, _p)
          736 #define RBT_CHECK(_name, _elm, _p)        _name##_RBT_CHECK(_elm, _p)
          737 
          738 #define RBT_FOREACH(_e, _name, _head)                                        \
          739         for ((_e) = RBT_MIN(_name, (_head));                                \
          740              (_e) != NULL;                                                \
          741              (_e) = RBT_NEXT(_name, (_e)))
          742 
          743 #define RBT_FOREACH_SAFE(_e, _name, _head, _n)                                \
          744         for ((_e) = RBT_MIN(_name, (_head));                                \
          745              (_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1);        \
          746              (_e) = (_n))
          747 
          748 #define RBT_FOREACH_REVERSE(_e, _name, _head)                                \
          749         for ((_e) = RBT_MAX(_name, (_head));                                \
          750              (_e) != NULL;                                                \
          751              (_e) = RBT_PREV(_name, (_e)))
          752 
          753 #define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n)                        \
          754         for ((_e) = RBT_MAX(_name, (_head));                                \
          755              (_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1);        \
          756              (_e) = (_n))
          757 
          758 #endif        /* _SYS_TREE_H_ */