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