Coverage Report

Created: 2026-02-09 06:05

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