Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/core/coreutils/src/compat/tree.h
1067 views
1
/* $OpenBSD: tree.h,v 1.30 2020/10/10 18:03:41 otto Exp $ */
2
/*
3
* Copyright 2002 Niels Provos <[email protected]>
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
*/
26
27
#ifndef _SYS_TREE_H_
28
#define _SYS_TREE_H_
29
30
/*
31
* This file defines data structures for different types of trees:
32
* splay trees and red-black trees.
33
*
34
* A splay tree is a self-organizing data structure. Every operation
35
* on the tree causes a splay to happen. The splay moves the requested
36
* node to the root of the tree and partly rebalances it.
37
*
38
* This has the benefit that request locality causes faster lookups as
39
* the requested nodes move to the top of the tree. On the other hand,
40
* every lookup causes memory writes.
41
*
42
* The Balance Theorem bounds the total access time for m operations
43
* and n inserts on an initially empty tree as O((m + n)lg n). The
44
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
45
*
46
* A red-black tree is a binary search tree with the node color as an
47
* extra attribute. It fulfills a set of conditions:
48
* - every search path from the root to a leaf consists of the
49
* same number of black nodes,
50
* - each red node (except for the root) has a black parent,
51
* - each leaf node is black.
52
*
53
* Every operation on a red-black tree is bounded as O(lg n).
54
* The maximum height of a red-black tree is 2lg (n+1).
55
*/
56
57
#define SPLAY_HEAD(name, type) \
58
struct name { \
59
struct type *sph_root; /* root of the tree */ \
60
}
61
62
#define SPLAY_INITIALIZER(root) \
63
{ NULL }
64
65
#define SPLAY_INIT(root) do { \
66
(root)->sph_root = NULL; \
67
} while (0)
68
69
#define SPLAY_ENTRY(type) \
70
struct { \
71
struct type *spe_left; /* left element */ \
72
struct type *spe_right; /* right element */ \
73
}
74
75
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
76
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
77
#define SPLAY_ROOT(head) (head)->sph_root
78
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
79
80
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
81
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
82
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
83
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
84
(head)->sph_root = tmp; \
85
} while (0)
86
87
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
88
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
89
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
90
(head)->sph_root = tmp; \
91
} while (0)
92
93
#define SPLAY_LINKLEFT(head, tmp, field) do { \
94
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
95
tmp = (head)->sph_root; \
96
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
97
} while (0)
98
99
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
100
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
101
tmp = (head)->sph_root; \
102
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
103
} while (0)
104
105
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
106
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
107
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
108
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
109
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
110
} while (0)
111
112
/* Generates prototypes and inline functions */
113
114
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
115
void name##_SPLAY(struct name *, struct type *); \
116
void name##_SPLAY_MINMAX(struct name *, int); \
117
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
118
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
119
\
120
/* Finds the node with the same key as elm */ \
121
static __unused __inline struct type * \
122
name##_SPLAY_FIND(struct name *head, struct type *elm) \
123
{ \
124
if (SPLAY_EMPTY(head)) \
125
return(NULL); \
126
name##_SPLAY(head, elm); \
127
if ((cmp)(elm, (head)->sph_root) == 0) \
128
return (head->sph_root); \
129
return (NULL); \
130
} \
131
\
132
static __unused __inline struct type * \
133
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
134
{ \
135
name##_SPLAY(head, elm); \
136
if (SPLAY_RIGHT(elm, field) != NULL) { \
137
elm = SPLAY_RIGHT(elm, field); \
138
while (SPLAY_LEFT(elm, field) != NULL) { \
139
elm = SPLAY_LEFT(elm, field); \
140
} \
141
} else \
142
elm = NULL; \
143
return (elm); \
144
} \
145
\
146
static __unused __inline struct type * \
147
name##_SPLAY_MIN_MAX(struct name *head, int val) \
148
{ \
149
name##_SPLAY_MINMAX(head, val); \
150
return (SPLAY_ROOT(head)); \
151
}
152
153
/* Main splay operation.
154
* Moves node close to the key of elm to top
155
*/
156
#define SPLAY_GENERATE(name, type, field, cmp) \
157
struct type * \
158
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
159
{ \
160
if (SPLAY_EMPTY(head)) { \
161
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
162
} else { \
163
int __comp; \
164
name##_SPLAY(head, elm); \
165
__comp = (cmp)(elm, (head)->sph_root); \
166
if(__comp < 0) { \
167
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
168
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
169
SPLAY_LEFT((head)->sph_root, field) = NULL; \
170
} else if (__comp > 0) { \
171
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
172
SPLAY_LEFT(elm, field) = (head)->sph_root; \
173
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
174
} else \
175
return ((head)->sph_root); \
176
} \
177
(head)->sph_root = (elm); \
178
return (NULL); \
179
} \
180
\
181
struct type * \
182
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
183
{ \
184
struct type *__tmp; \
185
if (SPLAY_EMPTY(head)) \
186
return (NULL); \
187
name##_SPLAY(head, elm); \
188
if ((cmp)(elm, (head)->sph_root) == 0) { \
189
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
190
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
191
} else { \
192
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
193
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
194
name##_SPLAY(head, elm); \
195
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
196
} \
197
return (elm); \
198
} \
199
return (NULL); \
200
} \
201
\
202
void \
203
name##_SPLAY(struct name *head, struct type *elm) \
204
{ \
205
struct type __node, *__left, *__right, *__tmp; \
206
int __comp; \
207
\
208
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
209
__left = __right = &__node; \
210
\
211
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
212
if (__comp < 0) { \
213
__tmp = SPLAY_LEFT((head)->sph_root, field); \
214
if (__tmp == NULL) \
215
break; \
216
if ((cmp)(elm, __tmp) < 0){ \
217
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
218
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
219
break; \
220
} \
221
SPLAY_LINKLEFT(head, __right, field); \
222
} else if (__comp > 0) { \
223
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
224
if (__tmp == NULL) \
225
break; \
226
if ((cmp)(elm, __tmp) > 0){ \
227
SPLAY_ROTATE_LEFT(head, __tmp, field); \
228
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
229
break; \
230
} \
231
SPLAY_LINKRIGHT(head, __left, field); \
232
} \
233
} \
234
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
235
} \
236
\
237
/* Splay with either the minimum or the maximum element \
238
* Used to find minimum or maximum element in tree. \
239
*/ \
240
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
241
{ \
242
struct type __node, *__left, *__right, *__tmp; \
243
\
244
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
245
__left = __right = &__node; \
246
\
247
while (1) { \
248
if (__comp < 0) { \
249
__tmp = SPLAY_LEFT((head)->sph_root, field); \
250
if (__tmp == NULL) \
251
break; \
252
if (__comp < 0){ \
253
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
254
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
255
break; \
256
} \
257
SPLAY_LINKLEFT(head, __right, field); \
258
} else if (__comp > 0) { \
259
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
260
if (__tmp == NULL) \
261
break; \
262
if (__comp > 0) { \
263
SPLAY_ROTATE_LEFT(head, __tmp, field); \
264
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
265
break; \
266
} \
267
SPLAY_LINKRIGHT(head, __left, field); \
268
} \
269
} \
270
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
271
}
272
273
#define SPLAY_NEGINF -1
274
#define SPLAY_INF 1
275
276
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
277
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
278
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
279
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
280
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
281
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
282
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
283
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
284
285
#define SPLAY_FOREACH(x, name, head) \
286
for ((x) = SPLAY_MIN(name, head); \
287
(x) != NULL; \
288
(x) = SPLAY_NEXT(name, head, x))
289
290
/* Macros that define a red-black tree */
291
#define RB_HEAD(name, type) \
292
struct name { \
293
struct type *rbh_root; /* root of the tree */ \
294
}
295
296
#define RB_INITIALIZER(root) \
297
{ NULL }
298
299
#define RB_INIT(root) do { \
300
(root)->rbh_root = NULL; \
301
} while (0)
302
303
#define RB_BLACK 0
304
#define RB_RED 1
305
#define RB_ENTRY(type) \
306
struct { \
307
struct type *rbe_left; /* left element */ \
308
struct type *rbe_right; /* right element */ \
309
struct type *rbe_parent; /* parent element */ \
310
int rbe_color; /* node color */ \
311
}
312
313
#define RB_LEFT(elm, field) (elm)->field.rbe_left
314
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
315
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
316
#define RB_COLOR(elm, field) (elm)->field.rbe_color
317
#define RB_ROOT(head) (head)->rbh_root
318
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
319
320
#define RB_SET(elm, parent, field) do { \
321
RB_PARENT(elm, field) = parent; \
322
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
323
RB_COLOR(elm, field) = RB_RED; \
324
} while (0)
325
326
#define RB_SET_BLACKRED(black, red, field) do { \
327
RB_COLOR(black, field) = RB_BLACK; \
328
RB_COLOR(red, field) = RB_RED; \
329
} while (0)
330
331
#ifndef RB_AUGMENT
332
#define RB_AUGMENT(x) do {} while (0)
333
#endif
334
335
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
336
(tmp) = RB_RIGHT(elm, field); \
337
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \
338
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
339
} \
340
RB_AUGMENT(elm); \
341
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
342
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
343
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
344
else \
345
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
346
} else \
347
(head)->rbh_root = (tmp); \
348
RB_LEFT(tmp, field) = (elm); \
349
RB_PARENT(elm, field) = (tmp); \
350
RB_AUGMENT(tmp); \
351
if ((RB_PARENT(tmp, field))) \
352
RB_AUGMENT(RB_PARENT(tmp, field)); \
353
} while (0)
354
355
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
356
(tmp) = RB_LEFT(elm, field); \
357
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \
358
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
359
} \
360
RB_AUGMENT(elm); \
361
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
362
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
363
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
364
else \
365
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
366
} else \
367
(head)->rbh_root = (tmp); \
368
RB_RIGHT(tmp, field) = (elm); \
369
RB_PARENT(elm, field) = (tmp); \
370
RB_AUGMENT(tmp); \
371
if ((RB_PARENT(tmp, field))) \
372
RB_AUGMENT(RB_PARENT(tmp, field)); \
373
} while (0)
374
375
/* Generates prototypes and inline functions */
376
#define RB_PROTOTYPE(name, type, field, cmp) \
377
RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
378
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
379
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
380
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
381
attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
382
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
383
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
384
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
385
attr struct type *name##_RB_FIND(struct name *, struct type *); \
386
attr struct type *name##_RB_NFIND(struct name *, struct type *); \
387
attr struct type *name##_RB_NEXT(struct type *); \
388
attr struct type *name##_RB_PREV(struct type *); \
389
attr struct type *name##_RB_MINMAX(struct name *, int); \
390
\
391
392
/* Main rb operation.
393
* Moves node close to the key of elm to top
394
*/
395
#define RB_GENERATE(name, type, field, cmp) \
396
RB_GENERATE_INTERNAL(name, type, field, cmp,)
397
#define RB_GENERATE_STATIC(name, type, field, cmp) \
398
RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
399
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
400
attr void \
401
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
402
{ \
403
struct type *parent, *gparent, *tmp; \
404
while ((parent = RB_PARENT(elm, field)) && \
405
RB_COLOR(parent, field) == RB_RED) { \
406
gparent = RB_PARENT(parent, field); \
407
if (parent == RB_LEFT(gparent, field)) { \
408
tmp = RB_RIGHT(gparent, field); \
409
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
410
RB_COLOR(tmp, field) = RB_BLACK; \
411
RB_SET_BLACKRED(parent, gparent, field);\
412
elm = gparent; \
413
continue; \
414
} \
415
if (RB_RIGHT(parent, field) == elm) { \
416
RB_ROTATE_LEFT(head, parent, tmp, field);\
417
tmp = parent; \
418
parent = elm; \
419
elm = tmp; \
420
} \
421
RB_SET_BLACKRED(parent, gparent, field); \
422
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
423
} else { \
424
tmp = RB_LEFT(gparent, field); \
425
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
426
RB_COLOR(tmp, field) = RB_BLACK; \
427
RB_SET_BLACKRED(parent, gparent, field);\
428
elm = gparent; \
429
continue; \
430
} \
431
if (RB_LEFT(parent, field) == elm) { \
432
RB_ROTATE_RIGHT(head, parent, tmp, field);\
433
tmp = parent; \
434
parent = elm; \
435
elm = tmp; \
436
} \
437
RB_SET_BLACKRED(parent, gparent, field); \
438
RB_ROTATE_LEFT(head, gparent, tmp, field); \
439
} \
440
} \
441
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
442
} \
443
\
444
attr void \
445
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
446
{ \
447
struct type *tmp; \
448
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
449
elm != RB_ROOT(head)) { \
450
if (RB_LEFT(parent, field) == elm) { \
451
tmp = RB_RIGHT(parent, field); \
452
if (RB_COLOR(tmp, field) == RB_RED) { \
453
RB_SET_BLACKRED(tmp, parent, field); \
454
RB_ROTATE_LEFT(head, parent, tmp, field);\
455
tmp = RB_RIGHT(parent, field); \
456
} \
457
if ((RB_LEFT(tmp, field) == NULL || \
458
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
459
(RB_RIGHT(tmp, field) == NULL || \
460
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
461
RB_COLOR(tmp, field) = RB_RED; \
462
elm = parent; \
463
parent = RB_PARENT(elm, field); \
464
} else { \
465
if (RB_RIGHT(tmp, field) == NULL || \
466
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
467
struct type *oleft; \
468
if ((oleft = RB_LEFT(tmp, field)))\
469
RB_COLOR(oleft, field) = RB_BLACK;\
470
RB_COLOR(tmp, field) = RB_RED; \
471
RB_ROTATE_RIGHT(head, tmp, oleft, field);\
472
tmp = RB_RIGHT(parent, field); \
473
} \
474
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
475
RB_COLOR(parent, field) = RB_BLACK; \
476
if (RB_RIGHT(tmp, field)) \
477
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
478
RB_ROTATE_LEFT(head, parent, tmp, field);\
479
elm = RB_ROOT(head); \
480
break; \
481
} \
482
} else { \
483
tmp = RB_LEFT(parent, field); \
484
if (RB_COLOR(tmp, field) == RB_RED) { \
485
RB_SET_BLACKRED(tmp, parent, field); \
486
RB_ROTATE_RIGHT(head, parent, tmp, field);\
487
tmp = RB_LEFT(parent, field); \
488
} \
489
if ((RB_LEFT(tmp, field) == NULL || \
490
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
491
(RB_RIGHT(tmp, field) == NULL || \
492
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
493
RB_COLOR(tmp, field) = RB_RED; \
494
elm = parent; \
495
parent = RB_PARENT(elm, field); \
496
} else { \
497
if (RB_LEFT(tmp, field) == NULL || \
498
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
499
struct type *oright; \
500
if ((oright = RB_RIGHT(tmp, field)))\
501
RB_COLOR(oright, field) = RB_BLACK;\
502
RB_COLOR(tmp, field) = RB_RED; \
503
RB_ROTATE_LEFT(head, tmp, oright, field);\
504
tmp = RB_LEFT(parent, field); \
505
} \
506
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
507
RB_COLOR(parent, field) = RB_BLACK; \
508
if (RB_LEFT(tmp, field)) \
509
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
510
RB_ROTATE_RIGHT(head, parent, tmp, field);\
511
elm = RB_ROOT(head); \
512
break; \
513
} \
514
} \
515
} \
516
if (elm) \
517
RB_COLOR(elm, field) = RB_BLACK; \
518
} \
519
\
520
attr struct type * \
521
name##_RB_REMOVE(struct name *head, struct type *elm) \
522
{ \
523
struct type *child, *parent, *old = elm; \
524
int color; \
525
if (RB_LEFT(elm, field) == NULL) \
526
child = RB_RIGHT(elm, field); \
527
else if (RB_RIGHT(elm, field) == NULL) \
528
child = RB_LEFT(elm, field); \
529
else { \
530
struct type *left; \
531
elm = RB_RIGHT(elm, field); \
532
while ((left = RB_LEFT(elm, field))) \
533
elm = left; \
534
child = RB_RIGHT(elm, field); \
535
parent = RB_PARENT(elm, field); \
536
color = RB_COLOR(elm, field); \
537
if (child) \
538
RB_PARENT(child, field) = parent; \
539
if (parent) { \
540
if (RB_LEFT(parent, field) == elm) \
541
RB_LEFT(parent, field) = child; \
542
else \
543
RB_RIGHT(parent, field) = child; \
544
RB_AUGMENT(parent); \
545
} else \
546
RB_ROOT(head) = child; \
547
if (RB_PARENT(elm, field) == old) \
548
parent = elm; \
549
(elm)->field = (old)->field; \
550
if (RB_PARENT(old, field)) { \
551
if (RB_LEFT(RB_PARENT(old, field), field) == old)\
552
RB_LEFT(RB_PARENT(old, field), field) = elm;\
553
else \
554
RB_RIGHT(RB_PARENT(old, field), field) = elm;\
555
RB_AUGMENT(RB_PARENT(old, field)); \
556
} else \
557
RB_ROOT(head) = elm; \
558
RB_PARENT(RB_LEFT(old, field), field) = elm; \
559
if (RB_RIGHT(old, field)) \
560
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
561
if (parent) { \
562
left = parent; \
563
do { \
564
RB_AUGMENT(left); \
565
} while ((left = RB_PARENT(left, field))); \
566
} \
567
goto color; \
568
} \
569
parent = RB_PARENT(elm, field); \
570
color = RB_COLOR(elm, field); \
571
if (child) \
572
RB_PARENT(child, field) = parent; \
573
if (parent) { \
574
if (RB_LEFT(parent, field) == elm) \
575
RB_LEFT(parent, field) = child; \
576
else \
577
RB_RIGHT(parent, field) = child; \
578
RB_AUGMENT(parent); \
579
} else \
580
RB_ROOT(head) = child; \
581
color: \
582
if (color == RB_BLACK) \
583
name##_RB_REMOVE_COLOR(head, parent, child); \
584
return (old); \
585
} \
586
\
587
/* Inserts a node into the RB tree */ \
588
attr struct type * \
589
name##_RB_INSERT(struct name *head, struct type *elm) \
590
{ \
591
struct type *tmp; \
592
struct type *parent = NULL; \
593
int comp = 0; \
594
tmp = RB_ROOT(head); \
595
while (tmp) { \
596
parent = tmp; \
597
comp = (cmp)(elm, parent); \
598
if (comp < 0) \
599
tmp = RB_LEFT(tmp, field); \
600
else if (comp > 0) \
601
tmp = RB_RIGHT(tmp, field); \
602
else \
603
return (tmp); \
604
} \
605
RB_SET(elm, parent, field); \
606
if (parent != NULL) { \
607
if (comp < 0) \
608
RB_LEFT(parent, field) = elm; \
609
else \
610
RB_RIGHT(parent, field) = elm; \
611
RB_AUGMENT(parent); \
612
} else \
613
RB_ROOT(head) = elm; \
614
name##_RB_INSERT_COLOR(head, elm); \
615
return (NULL); \
616
} \
617
\
618
/* Finds the node with the same key as elm */ \
619
attr struct type * \
620
name##_RB_FIND(struct name *head, struct type *elm) \
621
{ \
622
struct type *tmp = RB_ROOT(head); \
623
int comp; \
624
while (tmp) { \
625
comp = cmp(elm, tmp); \
626
if (comp < 0) \
627
tmp = RB_LEFT(tmp, field); \
628
else if (comp > 0) \
629
tmp = RB_RIGHT(tmp, field); \
630
else \
631
return (tmp); \
632
} \
633
return (NULL); \
634
} \
635
\
636
/* Finds the first node greater than or equal to the search key */ \
637
attr struct type * \
638
name##_RB_NFIND(struct name *head, struct type *elm) \
639
{ \
640
struct type *tmp = RB_ROOT(head); \
641
struct type *res = NULL; \
642
int comp; \
643
while (tmp) { \
644
comp = cmp(elm, tmp); \
645
if (comp < 0) { \
646
res = tmp; \
647
tmp = RB_LEFT(tmp, field); \
648
} \
649
else if (comp > 0) \
650
tmp = RB_RIGHT(tmp, field); \
651
else \
652
return (tmp); \
653
} \
654
return (res); \
655
} \
656
\
657
/* ARGSUSED */ \
658
attr struct type * \
659
name##_RB_NEXT(struct type *elm) \
660
{ \
661
if (RB_RIGHT(elm, field)) { \
662
elm = RB_RIGHT(elm, field); \
663
while (RB_LEFT(elm, field)) \
664
elm = RB_LEFT(elm, field); \
665
} else { \
666
if (RB_PARENT(elm, field) && \
667
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
668
elm = RB_PARENT(elm, field); \
669
else { \
670
while (RB_PARENT(elm, field) && \
671
(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
672
elm = RB_PARENT(elm, field); \
673
elm = RB_PARENT(elm, field); \
674
} \
675
} \
676
return (elm); \
677
} \
678
\
679
/* ARGSUSED */ \
680
attr struct type * \
681
name##_RB_PREV(struct type *elm) \
682
{ \
683
if (RB_LEFT(elm, field)) { \
684
elm = RB_LEFT(elm, field); \
685
while (RB_RIGHT(elm, field)) \
686
elm = RB_RIGHT(elm, field); \
687
} else { \
688
if (RB_PARENT(elm, field) && \
689
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
690
elm = RB_PARENT(elm, field); \
691
else { \
692
while (RB_PARENT(elm, field) && \
693
(elm == RB_LEFT(RB_PARENT(elm, field), field)))\
694
elm = RB_PARENT(elm, field); \
695
elm = RB_PARENT(elm, field); \
696
} \
697
} \
698
return (elm); \
699
} \
700
\
701
attr struct type * \
702
name##_RB_MINMAX(struct name *head, int val) \
703
{ \
704
struct type *tmp = RB_ROOT(head); \
705
struct type *parent = NULL; \
706
while (tmp) { \
707
parent = tmp; \
708
if (val < 0) \
709
tmp = RB_LEFT(tmp, field); \
710
else \
711
tmp = RB_RIGHT(tmp, field); \
712
} \
713
return (parent); \
714
}
715
716
#define RB_NEGINF -1
717
#define RB_INF 1
718
719
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
720
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
721
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
722
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
723
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
724
#define RB_PREV(name, x, y) name##_RB_PREV(y)
725
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
726
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
727
728
#define RB_FOREACH(x, name, head) \
729
for ((x) = RB_MIN(name, head); \
730
(x) != NULL; \
731
(x) = name##_RB_NEXT(x))
732
733
#define RB_FOREACH_SAFE(x, name, head, y) \
734
for ((x) = RB_MIN(name, head); \
735
((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \
736
(x) = (y))
737
738
#define RB_FOREACH_REVERSE(x, name, head) \
739
for ((x) = RB_MAX(name, head); \
740
(x) != NULL; \
741
(x) = name##_RB_PREV(x))
742
743
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
744
for ((x) = RB_MAX(name, head); \
745
((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \
746
(x) = (y))
747
748
749
/*
750
* Copyright (c) 2016 David Gwynne <[email protected]>
751
*
752
* Permission to use, copy, modify, and distribute this software for any
753
* purpose with or without fee is hereby granted, provided that the above
754
* copyright notice and this permission notice appear in all copies.
755
*
756
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
757
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
758
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
759
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
760
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
761
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
762
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
763
*/
764
765
struct rb_type {
766
int (*t_compare)(const void *, const void *);
767
void (*t_augment)(void *);
768
unsigned int t_offset; /* offset of rb_entry in type */
769
};
770
771
struct rb_tree {
772
struct rb_entry *rbt_root;
773
};
774
775
struct rb_entry {
776
struct rb_entry *rbt_parent;
777
struct rb_entry *rbt_left;
778
struct rb_entry *rbt_right;
779
unsigned int rbt_color;
780
};
781
782
#define RBT_HEAD(_name, _type) \
783
struct _name { \
784
struct rb_tree rbh_root; \
785
}
786
787
#define RBT_ENTRY(_type) struct rb_entry
788
789
static inline void
790
_rb_init(struct rb_tree *rbt)
791
{
792
rbt->rbt_root = NULL;
793
}
794
795
static inline int
796
_rb_empty(struct rb_tree *rbt)
797
{
798
return (rbt->rbt_root == NULL);
799
}
800
801
void *_rb_insert(const struct rb_type *, struct rb_tree *, void *);
802
void *_rb_remove(const struct rb_type *, struct rb_tree *, void *);
803
void *_rb_find(const struct rb_type *, struct rb_tree *, const void *);
804
void *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *);
805
void *_rb_root(const struct rb_type *, struct rb_tree *);
806
void *_rb_min(const struct rb_type *, struct rb_tree *);
807
void *_rb_max(const struct rb_type *, struct rb_tree *);
808
void *_rb_next(const struct rb_type *, void *);
809
void *_rb_prev(const struct rb_type *, void *);
810
void *_rb_left(const struct rb_type *, void *);
811
void *_rb_right(const struct rb_type *, void *);
812
void *_rb_parent(const struct rb_type *, void *);
813
void _rb_set_left(const struct rb_type *, void *, void *);
814
void _rb_set_right(const struct rb_type *, void *, void *);
815
void _rb_set_parent(const struct rb_type *, void *, void *);
816
void _rb_poison(const struct rb_type *, void *, unsigned long);
817
int _rb_check(const struct rb_type *, void *, unsigned long);
818
819
#define RBT_INITIALIZER(_head) { { NULL } }
820
821
#define RBT_PROTOTYPE(_name, _type, _field, _cmp) \
822
extern const struct rb_type *const _name##_RBT_TYPE; \
823
\
824
__unused static inline void \
825
_name##_RBT_INIT(struct _name *head) \
826
{ \
827
_rb_init(&head->rbh_root); \
828
} \
829
\
830
__unused static inline struct _type * \
831
_name##_RBT_INSERT(struct _name *head, struct _type *elm) \
832
{ \
833
return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm); \
834
} \
835
\
836
__unused static inline struct _type * \
837
_name##_RBT_REMOVE(struct _name *head, struct _type *elm) \
838
{ \
839
return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm); \
840
} \
841
\
842
__unused static inline struct _type * \
843
_name##_RBT_FIND(struct _name *head, const struct _type *key) \
844
{ \
845
return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key); \
846
} \
847
\
848
__unused static inline struct _type * \
849
_name##_RBT_NFIND(struct _name *head, const struct _type *key) \
850
{ \
851
return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \
852
} \
853
\
854
__unused static inline struct _type * \
855
_name##_RBT_ROOT(struct _name *head) \
856
{ \
857
return _rb_root(_name##_RBT_TYPE, &head->rbh_root); \
858
} \
859
\
860
__unused static inline int \
861
_name##_RBT_EMPTY(struct _name *head) \
862
{ \
863
return _rb_empty(&head->rbh_root); \
864
} \
865
\
866
__unused static inline struct _type * \
867
_name##_RBT_MIN(struct _name *head) \
868
{ \
869
return _rb_min(_name##_RBT_TYPE, &head->rbh_root); \
870
} \
871
\
872
__unused static inline struct _type * \
873
_name##_RBT_MAX(struct _name *head) \
874
{ \
875
return _rb_max(_name##_RBT_TYPE, &head->rbh_root); \
876
} \
877
\
878
__unused static inline struct _type * \
879
_name##_RBT_NEXT(struct _type *elm) \
880
{ \
881
return _rb_next(_name##_RBT_TYPE, elm); \
882
} \
883
\
884
__unused static inline struct _type * \
885
_name##_RBT_PREV(struct _type *elm) \
886
{ \
887
return _rb_prev(_name##_RBT_TYPE, elm); \
888
} \
889
\
890
__unused static inline struct _type * \
891
_name##_RBT_LEFT(struct _type *elm) \
892
{ \
893
return _rb_left(_name##_RBT_TYPE, elm); \
894
} \
895
\
896
__unused static inline struct _type * \
897
_name##_RBT_RIGHT(struct _type *elm) \
898
{ \
899
return _rb_right(_name##_RBT_TYPE, elm); \
900
} \
901
\
902
__unused static inline struct _type * \
903
_name##_RBT_PARENT(struct _type *elm) \
904
{ \
905
return _rb_parent(_name##_RBT_TYPE, elm); \
906
} \
907
\
908
__unused static inline void \
909
_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left) \
910
{ \
911
_rb_set_left(_name##_RBT_TYPE, elm, left); \
912
} \
913
\
914
__unused static inline void \
915
_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right) \
916
{ \
917
_rb_set_right(_name##_RBT_TYPE, elm, right); \
918
} \
919
\
920
__unused static inline void \
921
_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent) \
922
{ \
923
_rb_set_parent(_name##_RBT_TYPE, elm, parent); \
924
} \
925
\
926
__unused static inline void \
927
_name##_RBT_POISON(struct _type *elm, unsigned long poison) \
928
{ \
929
_rb_poison(_name##_RBT_TYPE, elm, poison); \
930
} \
931
\
932
__unused static inline int \
933
_name##_RBT_CHECK(struct _type *elm, unsigned long poison) \
934
{ \
935
return _rb_check(_name##_RBT_TYPE, elm, poison); \
936
}
937
938
#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
939
static int \
940
_name##_RBT_COMPARE(const void *lptr, const void *rptr) \
941
{ \
942
const struct _type *l = lptr, *r = rptr; \
943
return _cmp(l, r); \
944
} \
945
static const struct rb_type _name##_RBT_INFO = { \
946
_name##_RBT_COMPARE, \
947
_aug, \
948
offsetof(struct _type, _field), \
949
}; \
950
const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO
951
952
#define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \
953
static void \
954
_name##_RBT_AUGMENT(void *ptr) \
955
{ \
956
struct _type *p = ptr; \
957
return _aug(p); \
958
} \
959
RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)
960
961
#define RBT_GENERATE(_name, _type, _field, _cmp) \
962
RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
963
964
#define RBT_INIT(_name, _head) _name##_RBT_INIT(_head)
965
#define RBT_INSERT(_name, _head, _elm) _name##_RBT_INSERT(_head, _elm)
966
#define RBT_REMOVE(_name, _head, _elm) _name##_RBT_REMOVE(_head, _elm)
967
#define RBT_FIND(_name, _head, _key) _name##_RBT_FIND(_head, _key)
968
#define RBT_NFIND(_name, _head, _key) _name##_RBT_NFIND(_head, _key)
969
#define RBT_ROOT(_name, _head) _name##_RBT_ROOT(_head)
970
#define RBT_EMPTY(_name, _head) _name##_RBT_EMPTY(_head)
971
#define RBT_MIN(_name, _head) _name##_RBT_MIN(_head)
972
#define RBT_MAX(_name, _head) _name##_RBT_MAX(_head)
973
#define RBT_NEXT(_name, _elm) _name##_RBT_NEXT(_elm)
974
#define RBT_PREV(_name, _elm) _name##_RBT_PREV(_elm)
975
#define RBT_LEFT(_name, _elm) _name##_RBT_LEFT(_elm)
976
#define RBT_RIGHT(_name, _elm) _name##_RBT_RIGHT(_elm)
977
#define RBT_PARENT(_name, _elm) _name##_RBT_PARENT(_elm)
978
#define RBT_SET_LEFT(_name, _elm, _l) _name##_RBT_SET_LEFT(_elm, _l)
979
#define RBT_SET_RIGHT(_name, _elm, _r) _name##_RBT_SET_RIGHT(_elm, _r)
980
#define RBT_SET_PARENT(_name, _elm, _p) _name##_RBT_SET_PARENT(_elm, _p)
981
#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p)
982
#define RBT_CHECK(_name, _elm, _p) _name##_RBT_CHECK(_elm, _p)
983
984
#define RBT_FOREACH(_e, _name, _head) \
985
for ((_e) = RBT_MIN(_name, (_head)); \
986
(_e) != NULL; \
987
(_e) = RBT_NEXT(_name, (_e)))
988
989
#define RBT_FOREACH_SAFE(_e, _name, _head, _n) \
990
for ((_e) = RBT_MIN(_name, (_head)); \
991
(_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1); \
992
(_e) = (_n))
993
994
#define RBT_FOREACH_REVERSE(_e, _name, _head) \
995
for ((_e) = RBT_MAX(_name, (_head)); \
996
(_e) != NULL; \
997
(_e) = RBT_PREV(_name, (_e)))
998
999
#define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
1000
for ((_e) = RBT_MAX(_name, (_head)); \
1001
(_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1); \
1002
(_e) = (_n))
1003
1004
#endif /* _SYS_TREE_H_ */
1005
1006