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