Blame


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