f5335477e410ddd494d30576eeb9e284ec2f689c
1 /* This is a cut down version of FreeBSD's
2 * src/sys/sys/tree.h,v 1.5
5 * $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $
6 * $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $
8 * The original file's license:
10 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
11 * All rights reserved.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #define RB_HEAD(name, type) \
36 struct type *rbh_root; /* root of the tree */ \
39 #define RB_INITIALIZER(root) { NULL }
43 #define RB_ENTRY(type) \
45 struct type *rbe_left; /* left element */ \
46 struct type *rbe_right; /* right element */ \
47 struct type *rbe_parent; /* parent element */ \
48 int rbe_color; /* node color */ \
51 #define RB_LEFT(elm, field) (elm)->field.rbe_left
52 #define RB_RIGHT(elm, field) (elm)->field.rbe_right
53 #define RB_PARENT(elm, field) (elm)->field.rbe_parent
54 #define RB_COLOR(elm, field) (elm)->field.rbe_color
55 #define RB_ROOT(head) (head)->rbh_root
57 #define RB_SET(elm, parent, field) do { \
58 RB_PARENT(elm, field) = parent; \
59 RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
60 RB_COLOR(elm, field) = RB_RED; \
61 } while (/*CONSTCOND*/ 0)
63 #define RB_SET_BLACKRED(black, red, field) do { \
64 RB_COLOR(black, field) = RB_BLACK; \
65 RB_COLOR(red, field) = RB_RED; \
66 } while (/*CONSTCOND*/ 0)
68 #define RB_AUGMENT(x) do {} while (0)
70 #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
71 (tmp) = RB_RIGHT(elm, field); \
72 if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
73 RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
76 if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
77 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
78 RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
80 RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
82 (head)->rbh_root = (tmp); \
83 RB_LEFT(tmp, field) = (elm); \
84 RB_PARENT(elm, field) = (tmp); \
86 if ((RB_PARENT(tmp, field))) \
87 RB_AUGMENT(RB_PARENT(tmp, field)); \
88 } while (/*CONSTCOND*/ 0)
90 #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
91 (tmp) = RB_LEFT(elm, field); \
92 if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
93 RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
96 if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
97 if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
98 RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
100 RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
102 (head)->rbh_root = (tmp); \
103 RB_RIGHT(tmp, field) = (elm); \
104 RB_PARENT(elm, field) = (tmp); \
106 if ((RB_PARENT(tmp, field))) \
107 RB_AUGMENT(RB_PARENT(tmp, field)); \
108 } while (/*CONSTCOND*/ 0)
110 #define RB_GENERATE(name, type, field, cmp) \
111 RB_GENERATE_INTERNAL(name, type, field, cmp, static)
112 #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
114 name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
116 struct type *parent, *gparent, *tmp; \
117 while ((parent = RB_PARENT(elm, field)) != NULL && \
118 RB_COLOR(parent, field) == RB_RED) { \
119 gparent = RB_PARENT(parent, field); \
120 if (parent == RB_LEFT(gparent, field)) { \
121 tmp = RB_RIGHT(gparent, field); \
122 if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
123 RB_COLOR(tmp, field) = RB_BLACK; \
124 RB_SET_BLACKRED(parent, gparent, field);\
128 if (RB_RIGHT(parent, field) == elm) { \
129 RB_ROTATE_LEFT(head, parent, tmp, field);\
134 RB_SET_BLACKRED(parent, gparent, field); \
135 RB_ROTATE_RIGHT(head, gparent, tmp, field); \
137 tmp = RB_LEFT(gparent, field); \
138 if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
139 RB_COLOR(tmp, field) = RB_BLACK; \
140 RB_SET_BLACKRED(parent, gparent, field);\
144 if (RB_LEFT(parent, field) == elm) { \
145 RB_ROTATE_RIGHT(head, parent, tmp, field);\
150 RB_SET_BLACKRED(parent, gparent, field); \
151 RB_ROTATE_LEFT(head, gparent, tmp, field); \
154 RB_COLOR(head->rbh_root, field) = RB_BLACK; \
158 name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
161 while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
162 elm != RB_ROOT(head)) { \
163 if (RB_LEFT(parent, field) == elm) { \
164 tmp = RB_RIGHT(parent, field); \
165 if (RB_COLOR(tmp, field) == RB_RED) { \
166 RB_SET_BLACKRED(tmp, parent, field); \
167 RB_ROTATE_LEFT(head, parent, tmp, field);\
168 tmp = RB_RIGHT(parent, field); \
170 if ((RB_LEFT(tmp, field) == NULL || \
171 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
172 (RB_RIGHT(tmp, field) == NULL || \
173 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
174 RB_COLOR(tmp, field) = RB_RED; \
176 parent = RB_PARENT(elm, field); \
178 if (RB_RIGHT(tmp, field) == NULL || \
179 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
180 struct type *oleft; \
181 if ((oleft = RB_LEFT(tmp, field)) \
183 RB_COLOR(oleft, field) = RB_BLACK;\
184 RB_COLOR(tmp, field) = RB_RED; \
185 RB_ROTATE_RIGHT(head, tmp, oleft, field);\
186 tmp = RB_RIGHT(parent, field); \
188 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
189 RB_COLOR(parent, field) = RB_BLACK; \
190 if (RB_RIGHT(tmp, field)) \
191 RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
192 RB_ROTATE_LEFT(head, parent, tmp, field);\
193 elm = RB_ROOT(head); \
197 tmp = RB_LEFT(parent, field); \
198 if (RB_COLOR(tmp, field) == RB_RED) { \
199 RB_SET_BLACKRED(tmp, parent, field); \
200 RB_ROTATE_RIGHT(head, parent, tmp, field);\
201 tmp = RB_LEFT(parent, field); \
203 if ((RB_LEFT(tmp, field) == NULL || \
204 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
205 (RB_RIGHT(tmp, field) == NULL || \
206 RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
207 RB_COLOR(tmp, field) = RB_RED; \
209 parent = RB_PARENT(elm, field); \
211 if (RB_LEFT(tmp, field) == NULL || \
212 RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
213 struct type *oright; \
214 if ((oright = RB_RIGHT(tmp, field)) \
216 RB_COLOR(oright, field) = RB_BLACK;\
217 RB_COLOR(tmp, field) = RB_RED; \
218 RB_ROTATE_LEFT(head, tmp, oright, field);\
219 tmp = RB_LEFT(parent, field); \
221 RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
222 RB_COLOR(parent, field) = RB_BLACK; \
223 if (RB_LEFT(tmp, field)) \
224 RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
225 RB_ROTATE_RIGHT(head, parent, tmp, field);\
226 elm = RB_ROOT(head); \
232 RB_COLOR(elm, field) = RB_BLACK; \
236 name##_RB_REMOVE(struct name *head, struct type *elm) \
238 struct type *child, *parent, *old = elm; \
240 if (RB_LEFT(elm, field) == NULL) \
241 child = RB_RIGHT(elm, field); \
242 else if (RB_RIGHT(elm, field) == NULL) \
243 child = RB_LEFT(elm, field); \
246 elm = RB_RIGHT(elm, field); \
247 while ((left = RB_LEFT(elm, field)) != NULL) \
249 child = RB_RIGHT(elm, field); \
250 parent = RB_PARENT(elm, field); \
251 color = RB_COLOR(elm, field); \
253 RB_PARENT(child, field) = parent; \
255 if (RB_LEFT(parent, field) == elm) \
256 RB_LEFT(parent, field) = child; \
258 RB_RIGHT(parent, field) = child; \
259 RB_AUGMENT(parent); \
261 RB_ROOT(head) = child; \
262 if (RB_PARENT(elm, field) == old) \
264 (elm)->field = (old)->field; \
265 if (RB_PARENT(old, field)) { \
266 if (RB_LEFT(RB_PARENT(old, field), field) == old)\
267 RB_LEFT(RB_PARENT(old, field), field) = elm;\
269 RB_RIGHT(RB_PARENT(old, field), field) = elm;\
270 RB_AUGMENT(RB_PARENT(old, field)); \
272 RB_ROOT(head) = elm; \
273 RB_PARENT(RB_LEFT(old, field), field) = elm; \
274 if (RB_RIGHT(old, field)) \
275 RB_PARENT(RB_RIGHT(old, field), field) = elm; \
280 } while ((left = RB_PARENT(left, field)) != NULL); \
284 parent = RB_PARENT(elm, field); \
285 color = RB_COLOR(elm, field); \
287 RB_PARENT(child, field) = parent; \
289 if (RB_LEFT(parent, field) == elm) \
290 RB_LEFT(parent, field) = child; \
292 RB_RIGHT(parent, field) = child; \
293 RB_AUGMENT(parent); \
295 RB_ROOT(head) = child; \
297 if (color == RB_BLACK) \
298 name##_RB_REMOVE_COLOR(head, parent, child); \
302 /* Inserts a node into the RB tree */ \
304 name##_RB_INSERT(struct name *head, struct type *elm) \
307 struct type *parent = NULL; \
309 tmp = RB_ROOT(head); \
312 comp = (cmp)(elm, parent); \
314 tmp = RB_LEFT(tmp, field); \
316 tmp = RB_RIGHT(tmp, field); \
320 RB_SET(elm, parent, field); \
321 if (parent != NULL) { \
323 RB_LEFT(parent, field) = elm; \
325 RB_RIGHT(parent, field) = elm; \
326 RB_AUGMENT(parent); \
328 RB_ROOT(head) = elm; \
329 name##_RB_INSERT_COLOR(head, elm); \
333 /* Finds the node with the same key as elm */ \
335 name##_RB_FIND(struct name *head, struct type *elm) \
337 struct type *tmp = RB_ROOT(head); \
340 comp = cmp(elm, tmp); \
342 tmp = RB_LEFT(tmp, field); \
344 tmp = RB_RIGHT(tmp, field); \
353 name##_RB_NEXT(struct type *elm) \
355 if (RB_RIGHT(elm, field)) { \
356 elm = RB_RIGHT(elm, field); \
357 while (RB_LEFT(elm, field)) \
358 elm = RB_LEFT(elm, field); \
360 if (RB_PARENT(elm, field) && \
361 (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
362 elm = RB_PARENT(elm, field); \
364 while (RB_PARENT(elm, field) && \
365 (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
366 elm = RB_PARENT(elm, field); \
367 elm = RB_PARENT(elm, field); \
374 name##_RB_MINMAX(struct name *head, int val) \
376 struct type *tmp = RB_ROOT(head); \
377 struct type *parent = NULL; \
381 tmp = RB_LEFT(tmp, field); \
383 tmp = RB_RIGHT(tmp, field); \
390 #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
391 #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
392 #define RB_FIND(name, x, y) name##_RB_FIND(x, y)
393 #define RB_NEXT(name, x, y) name##_RB_NEXT(y)
394 #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)