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