Coverage Report

Created: 2025-07-02 06:55

/src/openssh/openbsd-compat/sys-tree.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: tree.h,v 1.13 2011/07/09 00:19:45 pirofti Exp $ */
2
/*
3
 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
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
/* OPENBSD ORIGINAL: sys/sys/tree.h */
28
29
#include "config.h"
30
#ifdef NO_ATTRIBUTE_ON_RETURN_TYPE
31
# define __attribute__(x)
32
#endif
33
34
#ifndef _SYS_TREE_H_
35
#define _SYS_TREE_H_
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 (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 (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 (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 (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 (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 (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))) {   \
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
  while (1) {             \
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
0
#define RB_INIT(root) do {           \
307
0
  (root)->rbh_root = NULL;          \
308
0
} while (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 (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 (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))) {   \
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))) {   \
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 (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))) {   \
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))) {   \
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 (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, __attribute__((__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, __attribute__((__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)) &&      \
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
}                  \
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_INSERT_COLOR
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_INSERT_COLOR
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_INSERT_COLOR
450
                  \
451
attr void               \
452
0
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
453
0
{                 \
454
0
  struct type *tmp;           \
455
0
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&  \
456
0
      elm != RB_ROOT(head)) {         \
457
0
    if (RB_LEFT(parent, field) == elm) {     \
458
0
      tmp = RB_RIGHT(parent, field);      \
459
0
      if (RB_COLOR(tmp, field) == RB_RED) {   \
460
0
        RB_SET_BLACKRED(tmp, parent, field); \
461
0
        RB_ROTATE_LEFT(head, parent, tmp, field);\
462
0
        tmp = RB_RIGHT(parent, field);    \
463
0
      }           \
464
0
      if ((RB_LEFT(tmp, field) == NULL ||   \
465
0
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
466
0
          (RB_RIGHT(tmp, field) == NULL ||   \
467
0
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
468
0
        RB_COLOR(tmp, field) = RB_RED;   \
469
0
        elm = parent;       \
470
0
        parent = RB_PARENT(elm, field);   \
471
0
      } else {         \
472
0
        if (RB_RIGHT(tmp, field) == NULL || \
473
0
            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
474
0
          struct type *oleft;   \
475
0
          if ((oleft = RB_LEFT(tmp, field)))\
476
0
            RB_COLOR(oleft, field) = RB_BLACK;\
477
0
          RB_COLOR(tmp, field) = RB_RED; \
478
0
          RB_ROTATE_RIGHT(head, tmp, oleft, field);\
479
0
          tmp = RB_RIGHT(parent, field);  \
480
0
        }         \
481
0
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
482
0
        RB_COLOR(parent, field) = RB_BLACK; \
483
0
        if (RB_RIGHT(tmp, field))   \
484
0
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
485
0
        RB_ROTATE_LEFT(head, parent, tmp, field);\
486
0
        elm = RB_ROOT(head);     \
487
0
        break;          \
488
0
      }           \
489
0
    } else {           \
490
0
      tmp = RB_LEFT(parent, field);      \
491
0
      if (RB_COLOR(tmp, field) == RB_RED) {   \
492
0
        RB_SET_BLACKRED(tmp, parent, field); \
493
0
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
494
0
        tmp = RB_LEFT(parent, field);    \
495
0
      }           \
496
0
      if ((RB_LEFT(tmp, field) == NULL ||   \
497
0
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
498
0
          (RB_RIGHT(tmp, field) == NULL ||   \
499
0
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
500
0
        RB_COLOR(tmp, field) = RB_RED;   \
501
0
        elm = parent;       \
502
0
        parent = RB_PARENT(elm, field);   \
503
0
      } else {         \
504
0
        if (RB_LEFT(tmp, field) == NULL || \
505
0
            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
506
0
          struct type *oright;    \
507
0
          if ((oright = RB_RIGHT(tmp, field)))\
508
0
            RB_COLOR(oright, field) = RB_BLACK;\
509
0
          RB_COLOR(tmp, field) = RB_RED; \
510
0
          RB_ROTATE_LEFT(head, tmp, oright, field);\
511
0
          tmp = RB_LEFT(parent, field);  \
512
0
        }         \
513
0
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
514
0
        RB_COLOR(parent, field) = RB_BLACK; \
515
0
        if (RB_LEFT(tmp, field))   \
516
0
          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
517
0
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
518
0
        elm = RB_ROOT(head);     \
519
0
        break;          \
520
0
      }           \
521
0
    }             \
522
0
  }               \
523
0
  if (elm)             \
524
0
    RB_COLOR(elm, field) = RB_BLACK;     \
525
0
}                  \
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_REMOVE_COLOR
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_REMOVE_COLOR
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_REMOVE_COLOR
526
                  \
527
attr struct type *              \
528
0
name##_RB_REMOVE(struct name *head, struct type *elm)     \
529
0
{                 \
530
0
  struct type *child, *parent, *old = elm;      \
531
0
  int color;              \
532
0
  if (RB_LEFT(elm, field) == NULL)       \
533
0
    child = RB_RIGHT(elm, field);       \
534
0
  else if (RB_RIGHT(elm, field) == NULL)       \
535
0
    child = RB_LEFT(elm, field);       \
536
0
  else {               \
537
0
    struct type *left;          \
538
0
    elm = RB_RIGHT(elm, field);       \
539
0
    while ((left = RB_LEFT(elm, field)))      \
540
0
      elm = left;         \
541
0
    child = RB_RIGHT(elm, field);       \
542
0
    parent = RB_PARENT(elm, field);       \
543
0
    color = RB_COLOR(elm, field);       \
544
0
    if (child)           \
545
0
      RB_PARENT(child, field) = parent;   \
546
0
    if (parent) {           \
547
0
      if (RB_LEFT(parent, field) == elm)   \
548
0
        RB_LEFT(parent, field) = child;   \
549
0
      else            \
550
0
        RB_RIGHT(parent, field) = child; \
551
0
      RB_AUGMENT(parent);       \
552
0
    } else              \
553
0
      RB_ROOT(head) = child;       \
554
0
    if (RB_PARENT(elm, field) == old)     \
555
0
      parent = elm;         \
556
0
    (elm)->field = (old)->field;        \
557
0
    if (RB_PARENT(old, field)) {       \
558
0
      if (RB_LEFT(RB_PARENT(old, field), field) == old)\
559
0
        RB_LEFT(RB_PARENT(old, field), field) = elm;\
560
0
      else            \
561
0
        RB_RIGHT(RB_PARENT(old, field), field) = elm;\
562
0
      RB_AUGMENT(RB_PARENT(old, field));    \
563
0
    } else              \
564
0
      RB_ROOT(head) = elm;       \
565
0
    RB_PARENT(RB_LEFT(old, field), field) = elm;   \
566
0
    if (RB_RIGHT(old, field))       \
567
0
      RB_PARENT(RB_RIGHT(old, field), field) = elm; \
568
0
    if (parent) {           \
569
0
      left = parent;          \
570
0
      do {           \
571
0
        RB_AUGMENT(left);     \
572
0
      } while ((left = RB_PARENT(left, field)));  \
573
0
    }             \
574
0
    goto color;           \
575
0
  }               \
576
0
  parent = RB_PARENT(elm, field);         \
577
0
  color = RB_COLOR(elm, field);         \
578
0
  if (child)             \
579
0
    RB_PARENT(child, field) = parent;     \
580
0
  if (parent) {             \
581
0
    if (RB_LEFT(parent, field) == elm)     \
582
0
      RB_LEFT(parent, field) = child;     \
583
0
    else              \
584
0
      RB_RIGHT(parent, field) = child;   \
585
0
    RB_AUGMENT(parent);         \
586
0
  } else                \
587
0
    RB_ROOT(head) = child;         \
588
0
color:                  \
589
0
  if (color == RB_BLACK)           \
590
0
    name##_RB_REMOVE_COLOR(head, parent, child);   \
591
0
  return (old);             \
592
0
}                  \
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_REMOVE
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_REMOVE
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_REMOVE
593
                  \
594
/* Inserts a node into the RB tree */         \
595
attr struct type *              \
596
0
name##_RB_INSERT(struct name *head, struct type *elm)     \
597
0
{                 \
598
0
  struct type *tmp;           \
599
0
  struct type *parent = NULL;         \
600
0
  int comp = 0;             \
601
0
  tmp = RB_ROOT(head);           \
602
0
  while (tmp) {             \
603
0
    parent = tmp;           \
604
0
    comp = (cmp)(elm, parent);        \
605
0
    if (comp < 0)           \
606
0
      tmp = RB_LEFT(tmp, field);     \
607
0
    else if (comp > 0)         \
608
0
      tmp = RB_RIGHT(tmp, field);     \
609
0
    else              \
610
0
      return (tmp);         \
611
0
  }               \
612
0
  RB_SET(elm, parent, field);         \
613
0
  if (parent != NULL) {           \
614
0
    if (comp < 0)           \
615
0
      RB_LEFT(parent, field) = elm;     \
616
0
    else              \
617
0
      RB_RIGHT(parent, field) = elm;     \
618
0
    RB_AUGMENT(parent);         \
619
0
  } else                \
620
0
    RB_ROOT(head) = elm;         \
621
0
  name##_RB_INSERT_COLOR(head, elm);        \
622
0
  return (NULL);              \
623
0
}                  \
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_INSERT
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_INSERT
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_INSERT
624
                  \
625
/* Finds the node with the same key as elm */       \
626
attr struct type *              \
627
0
name##_RB_FIND(struct name *head, struct type *elm)     \
628
0
{                 \
629
0
  struct type *tmp = RB_ROOT(head);       \
630
0
  int comp;             \
631
0
  while (tmp) {             \
632
0
    comp = cmp(elm, tmp);         \
633
0
    if (comp < 0)           \
634
0
      tmp = RB_LEFT(tmp, field);     \
635
0
    else if (comp > 0)         \
636
0
      tmp = RB_RIGHT(tmp, field);     \
637
0
    else              \
638
0
      return (tmp);         \
639
0
  }               \
640
0
  return (NULL);             \
641
0
}                  \
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_FIND
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_FIND
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_FIND
642
                  \
643
/* Finds the first node greater than or equal to the search key */  \
644
attr struct type *              \
645
0
name##_RB_NFIND(struct name *head, struct type *elm)      \
646
0
{                 \
647
0
  struct type *tmp = RB_ROOT(head);       \
648
0
  struct type *res = NULL;          \
649
0
  int comp;             \
650
0
  while (tmp) {             \
651
0
    comp = cmp(elm, tmp);         \
652
0
    if (comp < 0) {           \
653
0
      res = tmp;          \
654
0
      tmp = RB_LEFT(tmp, field);     \
655
0
    }             \
656
0
    else if (comp > 0)         \
657
0
      tmp = RB_RIGHT(tmp, field);     \
658
0
    else              \
659
0
      return (tmp);         \
660
0
  }               \
661
0
  return (res);             \
662
0
}                  \
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_NFIND
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_NFIND
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_NFIND
663
                  \
664
/* ARGSUSED */                \
665
attr struct type *              \
666
0
name##_RB_NEXT(struct type *elm)          \
667
0
{                 \
668
0
  if (RB_RIGHT(elm, field)) {         \
669
0
    elm = RB_RIGHT(elm, field);       \
670
0
    while (RB_LEFT(elm, field))       \
671
0
      elm = RB_LEFT(elm, field);     \
672
0
  } else {             \
673
0
    if (RB_PARENT(elm, field) &&       \
674
0
        (elm == RB_LEFT(RB_PARENT(elm, field), field)))  \
675
0
      elm = RB_PARENT(elm, field);     \
676
0
    else {             \
677
0
      while (RB_PARENT(elm, field) &&     \
678
0
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
679
0
        elm = RB_PARENT(elm, field);   \
680
0
      elm = RB_PARENT(elm, field);     \
681
0
    }             \
682
0
  }               \
683
0
  return (elm);             \
684
0
}                  \
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_NEXT
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_NEXT
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_NEXT
685
                  \
686
/* ARGSUSED */                \
687
attr struct type *              \
688
0
name##_RB_PREV(struct type *elm)          \
689
0
{                 \
690
0
  if (RB_LEFT(elm, field)) {         \
691
0
    elm = RB_LEFT(elm, field);       \
692
0
    while (RB_RIGHT(elm, field))       \
693
0
      elm = RB_RIGHT(elm, field);     \
694
0
  } else {             \
695
0
    if (RB_PARENT(elm, field) &&       \
696
0
        (elm == RB_RIGHT(RB_PARENT(elm, field), field)))  \
697
0
      elm = RB_PARENT(elm, field);     \
698
0
    else {             \
699
0
      while (RB_PARENT(elm, field) &&     \
700
0
          (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
701
0
        elm = RB_PARENT(elm, field);   \
702
0
      elm = RB_PARENT(elm, field);     \
703
0
    }             \
704
0
  }               \
705
0
  return (elm);             \
706
0
}                  \
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_PREV
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_PREV
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_PREV
707
                  \
708
attr struct type *              \
709
0
name##_RB_MINMAX(struct name *head, int val)        \
710
0
{                 \
711
0
  struct type *tmp = RB_ROOT(head);       \
712
0
  struct type *parent = NULL;         \
713
0
  while (tmp) {             \
714
0
    parent = tmp;           \
715
0
    if (val < 0)           \
716
0
      tmp = RB_LEFT(tmp, field);     \
717
0
    else              \
718
0
      tmp = RB_RIGHT(tmp, field);     \
719
0
  }               \
720
0
  return (parent);            \
721
0
}
Unexecuted instantiation: krl.c:revoked_blob_tree_RB_MINMAX
Unexecuted instantiation: krl.c:revoked_serial_tree_RB_MINMAX
Unexecuted instantiation: krl.c:revoked_key_id_tree_RB_MINMAX
722
723
0
#define RB_NEGINF -1
724
#define RB_INF  1
725
726
0
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
727
0
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
728
0
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
729
0
#define RB_NFIND(name, x, y)  name##_RB_NFIND(x, y)
730
0
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
731
0
#define RB_PREV(name, x, y) name##_RB_PREV(y)
732
0
#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
733
#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
734
735
#define RB_FOREACH(x, name, head)         \
736
0
  for ((x) = RB_MIN(name, head);         \
737
0
       (x) != NULL;           \
738
0
       (x) = name##_RB_NEXT(x))
739
740
#define RB_FOREACH_SAFE(x, name, head, y)       \
741
0
  for ((x) = RB_MIN(name, head);         \
742
0
      ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1);   \
743
0
       (x) = (y))
744
745
#define RB_FOREACH_REVERSE(x, name, head)       \
746
  for ((x) = RB_MAX(name, head);          \
747
       (x) != NULL;           \
748
       (x) = name##_RB_PREV(x))
749
750
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)     \
751
  for ((x) = RB_MAX(name, head);          \
752
      ((x) != NULL) && ((y) = name##_RB_PREV(x), 1);    \
753
       (x) = (y))
754
755
#endif  /* _SYS_TREE_H_ */