]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sys/tree.h
rb_tree: silence coverity
[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         if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) {     \
384                 RB_SET_PARENT(RB_RIGHT(elm, field), elm, field);        \
385         }                                                               \
386         RB_SET_PARENT(tmp, RB_PARENT(elm, field), field);               \
387         RB_SWAP_CHILD(head, elm, tmp, field);                           \
388         RB_LEFT(tmp, field) = (elm);                                    \
389         RB_SET_PARENT(elm, tmp, field);                                 \
390         RB_AUGMENT(elm);                                                \
391 } while (/*CONSTCOND*/ 0)
392
393 #define RB_ROTATE_RIGHT(head, elm, tmp, field) do {                     \
394         if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {     \
395                 RB_SET_PARENT(RB_LEFT(elm, field), elm, field);         \
396         }                                                               \
397         RB_SET_PARENT(tmp, RB_PARENT(elm, field), field);               \
398         RB_SWAP_CHILD(head, elm, tmp, field);                           \
399         RB_RIGHT(tmp, field) = (elm);                                   \
400         RB_SET_PARENT(elm, tmp, field);                                 \
401         RB_AUGMENT(elm);                                                \
402 } while (/*CONSTCOND*/ 0)
403
404 /* Generates prototypes and inline functions */
405 #define RB_PROTOTYPE(name, type, field, cmp)                            \
406         RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
407 #define RB_PROTOTYPE_STATIC(name, type, field, cmp)                     \
408         RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
409 #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)             \
410         RB_PROTOTYPE_INSERT_COLOR(name, type, attr);                    \
411         RB_PROTOTYPE_REMOVE_COLOR(name, type, attr);                    \
412         RB_PROTOTYPE_INSERT(name, type, attr);                          \
413         RB_PROTOTYPE_REMOVE(name, type, attr);                          \
414         RB_PROTOTYPE_FIND(name, type, attr);                            \
415         RB_PROTOTYPE_NFIND(name, type, attr);                           \
416         RB_PROTOTYPE_NEXT(name, type, attr);                            \
417         RB_PROTOTYPE_PREV(name, type, attr);                            \
418         RB_PROTOTYPE_MINMAX(name, type, attr);                          \
419         RB_PROTOTYPE_REINSERT(name, type, attr);
420 #define RB_PROTOTYPE_INSERT_COLOR(name, type, attr)                     \
421         attr void name##_RB_INSERT_COLOR(struct name *, struct type *)
422 #define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr)                     \
423         attr void name##_RB_REMOVE_COLOR(struct name *,                 \
424             struct type *, struct type *)
425 #define RB_PROTOTYPE_REMOVE(name, type, attr)                           \
426         attr struct type *name##_RB_REMOVE(struct name *, struct type *)
427 #define RB_PROTOTYPE_INSERT(name, type, attr)                           \
428         attr struct type *name##_RB_INSERT(struct name *, struct type *)
429 #define RB_PROTOTYPE_FIND(name, type, attr)                             \
430         attr struct type *name##_RB_FIND(struct name *, struct type *)
431 #define RB_PROTOTYPE_NFIND(name, type, attr)                            \
432         attr struct type *name##_RB_NFIND(struct name *, struct type *)
433 #define RB_PROTOTYPE_NEXT(name, type, attr)                             \
434         attr struct type *name##_RB_NEXT(struct type *)
435 #define RB_PROTOTYPE_PREV(name, type, attr)                             \
436         attr struct type *name##_RB_PREV(struct type *)
437 #define RB_PROTOTYPE_MINMAX(name, type, attr)                           \
438         attr struct type *name##_RB_MINMAX(struct name *, int)
439 #define RB_PROTOTYPE_REINSERT(name, type, attr)                 \
440         attr struct type *name##_RB_REINSERT(struct name *, struct type *)
441
442 /* Main rb operation.
443  * Moves node close to the key of elm to top
444  */
445 #define RB_GENERATE(name, type, field, cmp)                             \
446         RB_GENERATE_INTERNAL(name, type, field, cmp,)
447 #define RB_GENERATE_STATIC(name, type, field, cmp)                      \
448         RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
449 #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)              \
450         RB_GENERATE_INSERT_COLOR(name, type, field, attr)               \
451         RB_GENERATE_REMOVE_COLOR(name, type, field, attr)               \
452         RB_GENERATE_INSERT(name, type, field, cmp, attr)                \
453         RB_GENERATE_REMOVE(name, type, field, attr)                     \
454         RB_GENERATE_FIND(name, type, field, cmp, attr)                  \
455         RB_GENERATE_NFIND(name, type, field, cmp, attr)                 \
456         RB_GENERATE_NEXT(name, type, field, attr)                       \
457         RB_GENERATE_PREV(name, type, field, attr)                       \
458         RB_GENERATE_MINMAX(name, type, field, attr)                     \
459         RB_GENERATE_REINSERT(name, type, field, cmp, attr)
460
461 #define RB_GENERATE_INSERT_COLOR(name, type, field, attr)               \
462 attr void                                                               \
463 name##_RB_INSERT_COLOR(struct name *head, struct type *elm)             \
464 {                                                                       \
465         /*                                                              \
466          * Initially, elm is a leaf.  Either its parent was previously  \
467          * a leaf, with two black null children, or an interior node    \
468          * with a black non-null child and a red null child. The        \
469          * balance criterion "the rank of any leaf is 1" precludes the  \
470          * possibility of two red null children for the initial parent. \
471          * So the first loop iteration cannot lead to accessing an      \
472          * uninitialized 'child', and a later iteration can only happen \
473          * when a value has been assigned to 'child' in the previous    \
474          * one.                                                         \
475          */                                                             \
476         struct type *child, *parent;                                    \
477         while ((parent = RB_PARENT(elm, field)) != NULL) {              \
478                 if (RB_LEFT(parent, field) == elm) {                    \
479                         if (RB_RED_LEFT(parent, field)) {               \
480                                 RB_FLIP_LEFT(parent, field);            \
481                                 return;                                 \
482                         }                                               \
483                         RB_FLIP_RIGHT(parent, field);                   \
484                         if (RB_RED_RIGHT(parent, field)) {              \
485                                 child = elm;                            \
486                                 elm = parent;                           \
487                                 continue;                               \
488                         }                                               \
489                         if (!RB_RED_RIGHT(elm, field)) {                \
490                                 RB_FLIP_LEFT(elm, field);               \
491                                 /* coverity[uninit_use] */              \
492                                 RB_ROTATE_LEFT(head, elm, child, field);\
493                                 if (RB_RED_LEFT(child, field))          \
494                                         RB_FLIP_RIGHT(elm, field);      \
495                                 else if (RB_RED_RIGHT(child, field))    \
496                                         RB_FLIP_LEFT(parent, field);    \
497                                 elm = child;                            \
498                         }                                               \
499                         RB_ROTATE_RIGHT(head, parent, elm, field);      \
500                 } else {                                                \
501                         if (RB_RED_RIGHT(parent, field)) {              \
502                                 RB_FLIP_RIGHT(parent, field);           \
503                                 return;                                 \
504                         }                                               \
505                         RB_FLIP_LEFT(parent, field);                    \
506                         if (RB_RED_LEFT(parent, field)) {               \
507                                 child = elm;                            \
508                                 elm = parent;                           \
509                                 continue;                               \
510                         }                                               \
511                         if (!RB_RED_LEFT(elm, field)) {                 \
512                                 RB_FLIP_RIGHT(elm, field);              \
513                                 /* coverity[uninit_use] */              \
514                                 RB_ROTATE_RIGHT(head, elm, child, field);\
515                                 if (RB_RED_RIGHT(child, field))         \
516                                         RB_FLIP_LEFT(elm, field);       \
517                                 else if (RB_RED_LEFT(child, field))     \
518                                         RB_FLIP_RIGHT(parent, field);   \
519                                 elm = child;                            \
520                         }                                               \
521                         RB_ROTATE_LEFT(head, parent, elm, field);       \
522                 }                                                       \
523                 RB_BITS(elm, field) &= ~RB_RED_MASK;                    \
524                 break;                                                  \
525         }                                                               \
526 }
527
528 #define RB_GENERATE_REMOVE_COLOR(name, type, field, attr)               \
529 attr void                                                               \
530 name##_RB_REMOVE_COLOR(struct name *head,                               \
531     struct type *parent, struct type *elm)                              \
532 {                                                                       \
533         struct type *sib;                                               \
534         if (RB_LEFT(parent, field) == elm &&                            \
535             RB_RIGHT(parent, field) == elm) {                           \
536                 RB_BITS(parent, field) &= ~RB_RED_MASK;                 \
537                 elm = parent;                                           \
538                 parent = RB_PARENT(elm, field);                         \
539                 if (parent == NULL)                                     \
540                         return;                                         \
541         }                                                               \
542         do  {                                                           \
543                 if (RB_LEFT(parent, field) == elm) {                    \
544                         if (!RB_RED_LEFT(parent, field)) {              \
545                                 RB_FLIP_LEFT(parent, field);            \
546                                 return;                                 \
547                         }                                               \
548                         if (RB_RED_RIGHT(parent, field)) {              \
549                                 RB_FLIP_RIGHT(parent, field);           \
550                                 elm = parent;                           \
551                                 continue;                               \
552                         }                                               \
553                         sib = RB_RIGHT(parent, field);                  \
554                         if ((~RB_BITS(sib, field) & RB_RED_MASK) == 0) {\
555                                 RB_BITS(sib, field) &= ~RB_RED_MASK;    \
556                                 elm = parent;                           \
557                                 continue;                               \
558                         }                                               \
559                         RB_FLIP_RIGHT(sib, field);                      \
560                         if (RB_RED_LEFT(sib, field))                    \
561                                 RB_FLIP_LEFT(parent, field);            \
562                         else if (!RB_RED_RIGHT(sib, field)) {           \
563                                 RB_FLIP_LEFT(parent, field);            \
564                                 elm = RB_LEFT(sib, field);              \
565                                 RB_ROTATE_RIGHT(head, sib, elm, field); \
566                                 if (RB_RED_RIGHT(elm, field))           \
567                                         RB_FLIP_LEFT(sib, field);       \
568                                 if (RB_RED_LEFT(elm, field))            \
569                                         RB_FLIP_RIGHT(parent, field);   \
570                                 RB_BITS(elm, field) |= RB_RED_MASK;     \
571                                 sib = elm;                              \
572                         }                                               \
573                         RB_ROTATE_LEFT(head, parent, sib, field);       \
574                 } else {                                                \
575                         if (!RB_RED_RIGHT(parent, field)) {             \
576                                 RB_FLIP_RIGHT(parent, field);           \
577                                 return;                                 \
578                         }                                               \
579                         if (RB_RED_LEFT(parent, field)) {               \
580                                 RB_FLIP_LEFT(parent, field);            \
581                                 elm = parent;                           \
582                                 continue;                               \
583                         }                                               \
584                         sib = RB_LEFT(parent, field);                   \
585                         if ((~RB_BITS(sib, field) & RB_RED_MASK) == 0) {\
586                                 RB_BITS(sib, field) &= ~RB_RED_MASK;    \
587                                 elm = parent;                           \
588                                 continue;                               \
589                         }                                               \
590                         RB_FLIP_LEFT(sib, field);                       \
591                         if (RB_RED_RIGHT(sib, field))                   \
592                                 RB_FLIP_RIGHT(parent, field);           \
593                         else if (!RB_RED_LEFT(sib, field)) {            \
594                                 RB_FLIP_RIGHT(parent, field);           \
595                                 elm = RB_RIGHT(sib, field);             \
596                                 RB_ROTATE_LEFT(head, sib, elm, field);  \
597                                 if (RB_RED_LEFT(elm, field))            \
598                                         RB_FLIP_RIGHT(sib, field);      \
599                                 if (RB_RED_RIGHT(elm, field))           \
600                                         RB_FLIP_LEFT(parent, field);    \
601                                 RB_BITS(elm, field) |= RB_RED_MASK;     \
602                                 sib = elm;                              \
603                         }                                               \
604                         RB_ROTATE_RIGHT(head, parent, sib, field);      \
605                 }                                                       \
606                 break;                                                  \
607         } while ((parent = RB_PARENT(elm, field)) != NULL);             \
608 }
609
610 #define RB_GENERATE_REMOVE(name, type, field, attr)                     \
611 attr struct type *                                                      \
612 name##_RB_REMOVE(struct name *head, struct type *elm)                   \
613 {                                                                       \
614         struct type *child, *old, *parent, *right;                      \
615                                                                         \
616         old = elm;                                                      \
617         parent = RB_PARENT(elm, field);                                 \
618         right = RB_RIGHT(elm, field);                                   \
619         if (RB_LEFT(elm, field) == NULL)                                \
620                 elm = child = right;                                    \
621         else if (right == NULL)                                         \
622                 elm = child = RB_LEFT(elm, field);                      \
623         else {                                                          \
624                 if ((child = RB_LEFT(right, field)) == NULL) {          \
625                         child = RB_RIGHT(right, field);                 \
626                         RB_RIGHT(old, field) = child;                   \
627                         parent = elm = right;                           \
628                 } else {                                                \
629                         do                                              \
630                                 elm = child;                            \
631                         while ((child = RB_LEFT(elm, field)) != NULL);  \
632                         child = RB_RIGHT(elm, field);                   \
633                         parent = RB_PARENT(elm, field);                 \
634                         RB_LEFT(parent, field) = child;                 \
635                         RB_SET_PARENT(RB_RIGHT(old, field), elm, field);\
636                 }                                                       \
637                 RB_SET_PARENT(RB_LEFT(old, field), elm, field);         \
638                 elm->field = old->field;                                \
639         }                                                               \
640         RB_SWAP_CHILD(head, old, elm, field);                           \
641         if (child != NULL)                                              \
642                 RB_SET_PARENT(child, parent, field);                    \
643         if (parent != NULL)                                             \
644                 name##_RB_REMOVE_COLOR(head, parent, child);            \
645         while (parent != NULL) {                                        \
646                 RB_AUGMENT(parent);                                     \
647                 parent = RB_PARENT(parent, field);                      \
648         }                                                               \
649         return (old);                                                   \
650 }
651
652 #define RB_GENERATE_INSERT(name, type, field, cmp, attr)                \
653 /* Inserts a node into the RB tree */                                   \
654 attr struct type *                                                      \
655 name##_RB_INSERT(struct name *head, struct type *elm)                   \
656 {                                                                       \
657         struct type *tmp;                                               \
658         struct type *parent = NULL;                                     \
659         int comp = 0;                                                   \
660         tmp = RB_ROOT(head);                                            \
661         while (tmp) {                                                   \
662                 parent = tmp;                                           \
663                 comp = (cmp)(elm, parent);                              \
664                 if (comp < 0)                                           \
665                         tmp = RB_LEFT(tmp, field);                      \
666                 else if (comp > 0)                                      \
667                         tmp = RB_RIGHT(tmp, field);                     \
668                 else                                                    \
669                         return (tmp);                                   \
670         }                                                               \
671         RB_SET(elm, parent, field);                                     \
672         if (parent == NULL)                                             \
673                 RB_ROOT(head) = elm;                                    \
674         else if (comp < 0)                                              \
675                 RB_LEFT(parent, field) = elm;                           \
676         else                                                            \
677                 RB_RIGHT(parent, field) = elm;                          \
678         name##_RB_INSERT_COLOR(head, elm);                              \
679         while (elm != NULL) {                                           \
680                 RB_AUGMENT(elm);                                        \
681                 elm = RB_PARENT(elm, field);                            \
682         }                                                               \
683         return (NULL);                                                  \
684 }
685
686 #define RB_GENERATE_FIND(name, type, field, cmp, attr)                  \
687 /* Finds the node with the same key as elm */                           \
688 attr struct type *                                                      \
689 name##_RB_FIND(struct name *head, struct type *elm)                     \
690 {                                                                       \
691         struct type *tmp = RB_ROOT(head);                               \
692         int comp;                                                       \
693         while (tmp) {                                                   \
694                 comp = cmp(elm, tmp);                                   \
695                 if (comp < 0)                                           \
696                         tmp = RB_LEFT(tmp, field);                      \
697                 else if (comp > 0)                                      \
698                         tmp = RB_RIGHT(tmp, field);                     \
699                 else                                                    \
700                         return (tmp);                                   \
701         }                                                               \
702         return (NULL);                                                  \
703 }
704
705 #define RB_GENERATE_NFIND(name, type, field, cmp, attr)                 \
706 /* Finds the first node greater than or equal to the search key */      \
707 attr struct type *                                                      \
708 name##_RB_NFIND(struct name *head, struct type *elm)                    \
709 {                                                                       \
710         struct type *tmp = RB_ROOT(head);                               \
711         struct type *res = NULL;                                        \
712         int comp;                                                       \
713         while (tmp) {                                                   \
714                 comp = cmp(elm, tmp);                                   \
715                 if (comp < 0) {                                         \
716                         res = tmp;                                      \
717                         tmp = RB_LEFT(tmp, field);                      \
718                 }                                                       \
719                 else if (comp > 0)                                      \
720                         tmp = RB_RIGHT(tmp, field);                     \
721                 else                                                    \
722                         return (tmp);                                   \
723         }                                                               \
724         return (res);                                                   \
725 }
726
727 #define RB_GENERATE_NEXT(name, type, field, attr)                       \
728 /* ARGSUSED */                                                          \
729 attr struct type *                                                      \
730 name##_RB_NEXT(struct type *elm)                                        \
731 {                                                                       \
732         if (RB_RIGHT(elm, field)) {                                     \
733                 elm = RB_RIGHT(elm, field);                             \
734                 while (RB_LEFT(elm, field))                             \
735                         elm = RB_LEFT(elm, field);                      \
736         } else {                                                        \
737                 while (RB_PARENT(elm, field) &&                         \
738                     (elm == RB_RIGHT(RB_PARENT(elm, field), field)))    \
739                         elm = RB_PARENT(elm, field);                    \
740                 elm = RB_PARENT(elm, field);                            \
741         }                                                               \
742         return (elm);                                                   \
743 }
744
745 #define RB_GENERATE_PREV(name, type, field, attr)                       \
746 /* ARGSUSED */                                                          \
747 attr struct type *                                                      \
748 name##_RB_PREV(struct type *elm)                                        \
749 {                                                                       \
750         if (RB_LEFT(elm, field)) {                                      \
751                 elm = RB_LEFT(elm, field);                              \
752                 while (RB_RIGHT(elm, field))                            \
753                         elm = RB_RIGHT(elm, field);                     \
754         } else {                                                        \
755                 while (RB_PARENT(elm, field) &&                         \
756                     (elm == RB_LEFT(RB_PARENT(elm, field), field)))     \
757                         elm = RB_PARENT(elm, field);                    \
758                 elm = RB_PARENT(elm, field);                            \
759         }                                                               \
760         return (elm);                                                   \
761 }
762
763 #define RB_GENERATE_MINMAX(name, type, field, attr)                     \
764 attr struct type *                                                      \
765 name##_RB_MINMAX(struct name *head, int val)                            \
766 {                                                                       \
767         struct type *tmp = RB_ROOT(head);                               \
768         struct type *parent = NULL;                                     \
769         while (tmp) {                                                   \
770                 parent = tmp;                                           \
771                 if (val < 0)                                            \
772                         tmp = RB_LEFT(tmp, field);                      \
773                 else                                                    \
774                         tmp = RB_RIGHT(tmp, field);                     \
775         }                                                               \
776         return (parent);                                                \
777 }
778
779 #define RB_GENERATE_REINSERT(name, type, field, cmp, attr)              \
780 attr struct type *                                                      \
781 name##_RB_REINSERT(struct name *head, struct type *elm)                 \
782 {                                                                       \
783         struct type *cmpelm;                                            \
784         if (((cmpelm = RB_PREV(name, head, elm)) != NULL &&             \
785             cmp(cmpelm, elm) >= 0) ||                                   \
786             ((cmpelm = RB_NEXT(name, head, elm)) != NULL &&             \
787             cmp(elm, cmpelm) >= 0)) {                                   \
788                 /* XXXLAS: Remove/insert is heavy handed. */            \
789                 RB_REMOVE(name, head, elm);                             \
790                 return (RB_INSERT(name, head, elm));                    \
791         }                                                               \
792         return (NULL);                                                  \
793 }                                                                       \
794
795 #define RB_NEGINF       -1
796 #define RB_INF  1
797
798 #define RB_INSERT(name, x, y)   name##_RB_INSERT(x, y)
799 #define RB_REMOVE(name, x, y)   name##_RB_REMOVE(x, y)
800 #define RB_FIND(name, x, y)     name##_RB_FIND(x, y)
801 #define RB_NFIND(name, x, y)    name##_RB_NFIND(x, y)
802 #define RB_NEXT(name, x, y)     name##_RB_NEXT(y)
803 #define RB_PREV(name, x, y)     name##_RB_PREV(y)
804 #define RB_MIN(name, x)         name##_RB_MINMAX(x, RB_NEGINF)
805 #define RB_MAX(name, x)         name##_RB_MINMAX(x, RB_INF)
806 #define RB_REINSERT(name, x, y) name##_RB_REINSERT(x, y)
807
808 #define RB_FOREACH(x, name, head)                                       \
809         for ((x) = RB_MIN(name, head);                                  \
810              (x) != NULL;                                               \
811              (x) = name##_RB_NEXT(x))
812
813 #define RB_FOREACH_FROM(x, name, y)                                     \
814         for ((x) = (y);                                                 \
815             ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);    \
816              (x) = (y))
817
818 #define RB_FOREACH_SAFE(x, name, head, y)                               \
819         for ((x) = RB_MIN(name, head);                                  \
820             ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);    \
821              (x) = (y))
822
823 #define RB_FOREACH_REVERSE(x, name, head)                               \
824         for ((x) = RB_MAX(name, head);                                  \
825              (x) != NULL;                                               \
826              (x) = name##_RB_PREV(x))
827
828 #define RB_FOREACH_REVERSE_FROM(x, name, y)                             \
829         for ((x) = (y);                                                 \
830             ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);    \
831              (x) = (y))
832
833 #define RB_FOREACH_REVERSE_SAFE(x, name, head, y)                       \
834         for ((x) = RB_MAX(name, head);                                  \
835             ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);    \
836              (x) = (y))
837
838 #endif  /* _SYS_TREE_H_ */