WPILibC++
2027.0.0-alpha-2
Loading...
Searching...
No Matches
tree.h
Go to the documentation of this file.
1
/*-
2
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
*/
25
26
#ifndef UV_TREE_H_
27
#define UV_TREE_H_
28
29
#ifndef UV__UNUSED
30
# if __GNUC__
31
# define UV__UNUSED __attribute__((unused))
32
# else
33
# define UV__UNUSED
34
# endif
35
#endif
36
37
/*
38
* This file defines data structures for red-black trees.
39
* A red-black tree is a binary search tree with the node color as an
40
* extra attribute. It fulfills a set of conditions:
41
* - every search path from the root to a leaf consists of the
42
* same number of black nodes,
43
* - each red node (except for the root) has a black parent,
44
* - each leaf node is black.
45
*
46
* Every operation on a red-black tree is bounded as O(lg n).
47
* The maximum height of a red-black tree is 2lg (n+1).
48
*/
49
50
/* Macros that define a red-black tree */
51
#define RB_HEAD(name, type) \
52
struct name { \
53
struct type *rbh_root;
/* root of the tree */
\
54
}
55
56
#define RB_INITIALIZER(root) \
57
{ NULL }
58
59
#define RB_INIT(root) do { \
60
(root)->rbh_root = NULL; \
61
} while (
/*CONSTCOND*/
0)
62
63
#define RB_BLACK 0
64
#define RB_RED 1
65
#define RB_ENTRY(type) \
66
struct { \
67
struct type *rbe_left;
/* left element */
\
68
struct type *rbe_right;
/* right element */
\
69
struct type *rbe_parent;
/* parent element */
\
70
int rbe_color;
/* node color */
\
71
}
72
73
#define RB_LEFT(elm, field) (elm)->field.rbe_left
74
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
75
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
76
#define RB_COLOR(elm, field) (elm)->field.rbe_color
77
#define RB_ROOT(head) (head)->rbh_root
78
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
79
80
#define RB_SET(elm, parent, field) do { \
81
RB_PARENT(elm, field) = parent; \
82
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
83
RB_COLOR(elm, field) = RB_RED; \
84
} while (
/*CONSTCOND*/
0)
85
86
#define RB_SET_BLACKRED(black, red, field) do { \
87
RB_COLOR(black, field) = RB_BLACK; \
88
RB_COLOR(red, field) = RB_RED; \
89
} while (
/*CONSTCOND*/
0)
90
91
#ifndef RB_AUGMENT
92
#define RB_AUGMENT(x) do {} while (0)
93
#endif
94
95
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
96
(tmp) = RB_RIGHT(elm, field); \
97
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
98
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
99
} \
100
RB_AUGMENT(elm); \
101
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
102
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
103
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
104
else \
105
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
106
} else \
107
(head)->rbh_root = (tmp); \
108
RB_LEFT(tmp, field) = (elm); \
109
RB_PARENT(elm, field) = (tmp); \
110
RB_AUGMENT(tmp); \
111
if ((RB_PARENT(tmp, field))) \
112
RB_AUGMENT(RB_PARENT(tmp, field)); \
113
} while (
/*CONSTCOND*/
0)
114
115
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
116
(tmp) = RB_LEFT(elm, field); \
117
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
118
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
119
} \
120
RB_AUGMENT(elm); \
121
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
122
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
123
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
124
else \
125
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
126
} else \
127
(head)->rbh_root = (tmp); \
128
RB_RIGHT(tmp, field) = (elm); \
129
RB_PARENT(elm, field) = (tmp); \
130
RB_AUGMENT(tmp); \
131
if ((RB_PARENT(tmp, field))) \
132
RB_AUGMENT(RB_PARENT(tmp, field)); \
133
} while (
/*CONSTCOND*/
0)
134
135
/* Generates prototypes and inline functions */
136
#define RB_PROTOTYPE(name, type, field, cmp) \
137
RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
138
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
139
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
140
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
141
attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
142
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
143
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
144
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
145
attr struct type *name##_RB_FIND(struct name *, struct type *); \
146
attr struct type *name##_RB_NFIND(struct name *, struct type *); \
147
attr struct type *name##_RB_NEXT(struct type *); \
148
attr struct type *name##_RB_PREV(struct type *); \
149
attr struct type *name##_RB_MINMAX(struct name *, int); \
150
\
151
152
/* Main rb operation.
153
* Moves node close to the key of elm to top
154
*/
155
#define RB_GENERATE(name, type, field, cmp) \
156
RB_GENERATE_INTERNAL(name, type, field, cmp,)
157
#define RB_GENERATE_STATIC(name, type, field, cmp) \
158
RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
159
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
160
attr void \
161
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
162
{ \
163
struct type *parent, *gparent, *tmp; \
164
while ((parent = RB_PARENT(elm, field)) != NULL && \
165
RB_COLOR(parent, field) == RB_RED) { \
166
gparent = RB_PARENT(parent, field); \
167
if (parent == RB_LEFT(gparent, field)) { \
168
tmp = RB_RIGHT(gparent, field); \
169
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
170
RB_COLOR(tmp, field) = RB_BLACK; \
171
RB_SET_BLACKRED(parent, gparent, field); \
172
elm = gparent; \
173
continue; \
174
} \
175
if (RB_RIGHT(parent, field) == elm) { \
176
RB_ROTATE_LEFT(head, parent, tmp, field); \
177
tmp = parent; \
178
parent = elm; \
179
elm = tmp; \
180
} \
181
RB_SET_BLACKRED(parent, gparent, field); \
182
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
183
} else { \
184
tmp = RB_LEFT(gparent, field); \
185
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
186
RB_COLOR(tmp, field) = RB_BLACK; \
187
RB_SET_BLACKRED(parent, gparent, field); \
188
elm = gparent; \
189
continue; \
190
} \
191
if (RB_LEFT(parent, field) == elm) { \
192
RB_ROTATE_RIGHT(head, parent, tmp, field); \
193
tmp = parent; \
194
parent = elm; \
195
elm = tmp; \
196
} \
197
RB_SET_BLACKRED(parent, gparent, field); \
198
RB_ROTATE_LEFT(head, gparent, tmp, field); \
199
} \
200
} \
201
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
202
} \
203
\
204
attr void \
205
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \
206
struct type *elm) \
207
{ \
208
struct type *tmp; \
209
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
210
elm != RB_ROOT(head)) { \
211
if (RB_LEFT(parent, field) == elm) { \
212
tmp = RB_RIGHT(parent, field); \
213
if (RB_COLOR(tmp, field) == RB_RED) { \
214
RB_SET_BLACKRED(tmp, parent, field); \
215
RB_ROTATE_LEFT(head, parent, tmp, field); \
216
tmp = RB_RIGHT(parent, field); \
217
} \
218
if ((RB_LEFT(tmp, field) == NULL || \
219
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
220
(RB_RIGHT(tmp, field) == NULL || \
221
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
222
RB_COLOR(tmp, field) = RB_RED; \
223
elm = parent; \
224
parent = RB_PARENT(elm, field); \
225
} else { \
226
if (RB_RIGHT(tmp, field) == NULL || \
227
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \
228
struct type *oleft; \
229
if ((oleft = RB_LEFT(tmp, field)) \
230
!= NULL) \
231
RB_COLOR(oleft, field) = RB_BLACK; \
232
RB_COLOR(tmp, field) = RB_RED; \
233
RB_ROTATE_RIGHT(head, tmp, oleft, field); \
234
tmp = RB_RIGHT(parent, field); \
235
} \
236
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
237
RB_COLOR(parent, field) = RB_BLACK; \
238
if (RB_RIGHT(tmp, field)) \
239
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
240
RB_ROTATE_LEFT(head, parent, tmp, field); \
241
elm = RB_ROOT(head); \
242
break; \
243
} \
244
} else { \
245
tmp = RB_LEFT(parent, field); \
246
if (RB_COLOR(tmp, field) == RB_RED) { \
247
RB_SET_BLACKRED(tmp, parent, field); \
248
RB_ROTATE_RIGHT(head, parent, tmp, field); \
249
tmp = RB_LEFT(parent, field); \
250
} \
251
if ((RB_LEFT(tmp, field) == NULL || \
252
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
253
(RB_RIGHT(tmp, field) == NULL || \
254
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
255
RB_COLOR(tmp, field) = RB_RED; \
256
elm = parent; \
257
parent = RB_PARENT(elm, field); \
258
} else { \
259
if (RB_LEFT(tmp, field) == NULL || \
260
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \
261
struct type *oright; \
262
if ((oright = RB_RIGHT(tmp, field)) \
263
!= NULL) \
264
RB_COLOR(oright, field) = RB_BLACK; \
265
RB_COLOR(tmp, field) = RB_RED; \
266
RB_ROTATE_LEFT(head, tmp, oright, field); \
267
tmp = RB_LEFT(parent, field); \
268
} \
269
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
270
RB_COLOR(parent, field) = RB_BLACK; \
271
if (RB_LEFT(tmp, field)) \
272
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
273
RB_ROTATE_RIGHT(head, parent, tmp, field); \
274
elm = RB_ROOT(head); \
275
break; \
276
} \
277
} \
278
} \
279
if (elm) \
280
RB_COLOR(elm, field) = RB_BLACK; \
281
} \
282
\
283
attr struct type * \
284
name##_RB_REMOVE(struct name *head, struct type *elm) \
285
{ \
286
struct type *child, *parent, *old = elm; \
287
int color; \
288
if (RB_LEFT(elm, field) == NULL) \
289
child = RB_RIGHT(elm, field); \
290
else if (RB_RIGHT(elm, field) == NULL) \
291
child = RB_LEFT(elm, field); \
292
else { \
293
struct type *left; \
294
elm = RB_RIGHT(elm, field); \
295
while ((left = RB_LEFT(elm, field)) != NULL) \
296
elm = left; \
297
child = RB_RIGHT(elm, field); \
298
parent = RB_PARENT(elm, field); \
299
color = RB_COLOR(elm, field); \
300
if (child) \
301
RB_PARENT(child, field) = parent; \
302
if (parent) { \
303
if (RB_LEFT(parent, field) == elm) \
304
RB_LEFT(parent, field) = child; \
305
else \
306
RB_RIGHT(parent, field) = child; \
307
RB_AUGMENT(parent); \
308
} else \
309
RB_ROOT(head) = child; \
310
if (RB_PARENT(elm, field) == old) \
311
parent = elm; \
312
(elm)->field = (old)->field; \
313
if (RB_PARENT(old, field)) { \
314
if (RB_LEFT(RB_PARENT(old, field), field) == old) \
315
RB_LEFT(RB_PARENT(old, field), field) = elm; \
316
else \
317
RB_RIGHT(RB_PARENT(old, field), field) = elm; \
318
RB_AUGMENT(RB_PARENT(old, field)); \
319
} else \
320
RB_ROOT(head) = elm; \
321
RB_PARENT(RB_LEFT(old, field), field) = elm; \
322
if (RB_RIGHT(old, field)) \
323
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
324
if (parent) { \
325
left = parent; \
326
do { \
327
RB_AUGMENT(left); \
328
} while ((left = RB_PARENT(left, field)) != NULL); \
329
} \
330
goto color; \
331
} \
332
parent = RB_PARENT(elm, field); \
333
color = RB_COLOR(elm, field); \
334
if (child) \
335
RB_PARENT(child, field) = parent; \
336
if (parent) { \
337
if (RB_LEFT(parent, field) == elm) \
338
RB_LEFT(parent, field) = child; \
339
else \
340
RB_RIGHT(parent, field) = child; \
341
RB_AUGMENT(parent); \
342
} else \
343
RB_ROOT(head) = child; \
344
color: \
345
if (color == RB_BLACK) \
346
name##_RB_REMOVE_COLOR(head, parent, child); \
347
return (old); \
348
} \
349
\
350
/* Inserts a node into the RB tree */
\
351
attr struct type * \
352
name##_RB_INSERT(struct name *head, struct type *elm) \
353
{ \
354
struct type *tmp; \
355
struct type *parent = NULL; \
356
int comp = 0; \
357
tmp = RB_ROOT(head); \
358
while (tmp) { \
359
parent = tmp; \
360
comp = (cmp)(elm, parent); \
361
if (comp < 0) \
362
tmp = RB_LEFT(tmp, field); \
363
else if (comp > 0) \
364
tmp = RB_RIGHT(tmp, field); \
365
else \
366
return (tmp); \
367
} \
368
RB_SET(elm, parent, field); \
369
if (parent != NULL) { \
370
if (comp < 0) \
371
RB_LEFT(parent, field) = elm; \
372
else \
373
RB_RIGHT(parent, field) = elm; \
374
RB_AUGMENT(parent); \
375
} else \
376
RB_ROOT(head) = elm; \
377
name##_RB_INSERT_COLOR(head, elm); \
378
return (NULL); \
379
} \
380
\
381
/* Finds the node with the same key as elm */
\
382
attr struct type * \
383
name##_RB_FIND(struct name *head, struct type *elm) \
384
{ \
385
struct type *tmp = RB_ROOT(head); \
386
int comp; \
387
while (tmp) { \
388
comp = cmp(elm, tmp); \
389
if (comp < 0) \
390
tmp = RB_LEFT(tmp, field); \
391
else if (comp > 0) \
392
tmp = RB_RIGHT(tmp, field); \
393
else \
394
return (tmp); \
395
} \
396
return (NULL); \
397
} \
398
\
399
/* Finds the first node greater than or equal to the search key */
\
400
attr struct type * \
401
name##_RB_NFIND(struct name *head, struct type *elm) \
402
{ \
403
struct type *tmp = RB_ROOT(head); \
404
struct type *res = NULL; \
405
int comp; \
406
while (tmp) { \
407
comp = cmp(elm, tmp); \
408
if (comp < 0) { \
409
res = tmp; \
410
tmp = RB_LEFT(tmp, field); \
411
} \
412
else if (comp > 0) \
413
tmp = RB_RIGHT(tmp, field); \
414
else \
415
return (tmp); \
416
} \
417
return (res); \
418
} \
419
\
420
/* ARGSUSED */
\
421
attr struct type * \
422
name##_RB_NEXT(struct type *elm) \
423
{ \
424
if (RB_RIGHT(elm, field)) { \
425
elm = RB_RIGHT(elm, field); \
426
while (RB_LEFT(elm, field)) \
427
elm = RB_LEFT(elm, field); \
428
} else { \
429
if (RB_PARENT(elm, field) && \
430
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
431
elm = RB_PARENT(elm, field); \
432
else { \
433
while (RB_PARENT(elm, field) && \
434
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
435
elm = RB_PARENT(elm, field); \
436
elm = RB_PARENT(elm, field); \
437
} \
438
} \
439
return (elm); \
440
} \
441
\
442
/* ARGSUSED */
\
443
attr struct type * \
444
name##_RB_PREV(struct type *elm) \
445
{ \
446
if (RB_LEFT(elm, field)) { \
447
elm = RB_LEFT(elm, field); \
448
while (RB_RIGHT(elm, field)) \
449
elm = RB_RIGHT(elm, field); \
450
} else { \
451
if (RB_PARENT(elm, field) && \
452
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
453
elm = RB_PARENT(elm, field); \
454
else { \
455
while (RB_PARENT(elm, field) && \
456
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
457
elm = RB_PARENT(elm, field); \
458
elm = RB_PARENT(elm, field); \
459
} \
460
} \
461
return (elm); \
462
} \
463
\
464
attr struct type * \
465
name##_RB_MINMAX(struct name *head, int val) \
466
{ \
467
struct type *tmp = RB_ROOT(head); \
468
struct type *parent = NULL; \
469
while (tmp) { \
470
parent = tmp; \
471
if (val < 0) \
472
tmp = RB_LEFT(tmp, field); \
473
else \
474
tmp = RB_RIGHT(tmp, field); \
475
} \
476
return (parent); \
477
}
478
479
#define RB_NEGINF -1
480
#define RB_INF 1
481
482
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
483
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
484
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
485
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
486
#define RB_NEXT(name, x) name##_RB_NEXT(x)
487
#define RB_PREV(name, x) name##_RB_PREV(x)
488
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
489
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
490
491
#define RB_FOREACH(x, name, head) \
492
for ((x) = RB_MIN(name, head); \
493
(x) != NULL; \
494
(x) = name##_RB_NEXT(x))
495
496
#define RB_FOREACH_FROM(x, name, y) \
497
for ((x) = (y); \
498
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
499
(x) = (y))
500
501
#define RB_FOREACH_SAFE(x, name, head, y) \
502
for ((x) = RB_MIN(name, head); \
503
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
504
(x) = (y))
505
506
#define RB_FOREACH_REVERSE(x, name, head) \
507
for ((x) = RB_MAX(name, head); \
508
(x) != NULL; \
509
(x) = name##_RB_PREV(x))
510
511
#define RB_FOREACH_REVERSE_FROM(x, name, y) \
512
for ((x) = (y); \
513
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
514
(x) = (y))
515
516
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
517
for ((x) = RB_MAX(name, head); \
518
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
519
(x) = (y))
520
521
#endif
/* UV_TREE_H_ */
thirdparty
libuv
include
uv
tree.h
Generated on Wed Jul 23 2025 00:48:18 for WPILibC++ by
1.12.0