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