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