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