Coverage Report

Created: 2026-10-16 07:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/rbtree/rbtree.c
Line
Count
Source
1
/*
2
 * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright (c) 2016 David Gwynne <david@gwynne.id.au>
4
 *
5
 * Licensed under the Apache License 2.0 (the "License").  You may not use
6
 * this file except in compliance with the License.  You can obtain a copy
7
 * in the file LICENSE in the source distribution or at
8
 * https://www.openssl.org/source/license.html
9
 */
10
11
/*
12
 * The code here comes from David Gwynne <david@gwynne.id.au>. The original
13
 * version can be found:
14
 *    https://github.com/dgwynne/data-structures/
15
 * file bst.h. The same code is also part of OpenBSD OS where it is shipped
16
 * under BSD license.
17
 *
18
 * David Gwynne agrees to include modified version to OpenSSL and ship it
19
 * under OpenSSL Apache 2.0 license.
20
 */
21
22
#include "internal/ossl_rbtree.h"
23
24
#ifndef NDEBUG
25
#include <assert.h>
26
#endif
27
28
0
#define OSSL_RBT_BLACK 0
29
0
#define OSSL_RBT_RED 1
30
31
static struct ossl_rbt_entry *
32
rbt_n2e(const struct ossl_rbt_type *t, void *node)
33
0
{
34
0
    uintptr_t addr = (uintptr_t)node;
35
36
0
    return (struct ossl_rbt_entry *)(addr + t->t_offset);
37
0
}
38
39
static void *
40
rbt_e2n(const struct ossl_rbt_type *t, struct ossl_rbt_entry *rbe)
41
0
{
42
0
    uintptr_t addr = (uintptr_t)rbe;
43
44
0
    return (void *)(addr - t->t_offset);
45
0
}
46
47
0
#define OSSL_RBE_LEFT(_rbe) (_rbe)->rb_left
48
0
#define OSSL_RBE_RIGHT(_rbe) (_rbe)->rb_right
49
0
#define OSSL_RBE_PARENT(_rbe) (_rbe)->rb_parent
50
0
#define OSSL_RBE_COLOR(_rbe) (_rbe)->rb_color
51
52
0
#define OSSL_RBH_ROOT(_rbt) (_rbt)->rb_root
53
54
static void
55
rbe_set(struct ossl_rbt_entry *rbe, struct ossl_rbt_entry *parent)
56
0
{
57
0
    OSSL_RBE_PARENT(rbe) = parent;
58
0
    OSSL_RBE_LEFT(rbe) = OSSL_RBE_RIGHT(rbe) = NULL;
59
0
    OSSL_RBE_COLOR(rbe) = OSSL_RBT_RED;
60
0
}
61
62
static void
63
rbe_set_blackred(struct ossl_rbt_entry *black, struct ossl_rbt_entry *red)
64
0
{
65
0
    OSSL_RBE_COLOR(black) = OSSL_RBT_BLACK;
66
0
    OSSL_RBE_COLOR(red) = OSSL_RBT_RED;
67
0
}
68
69
static void
70
rbe_rotate_left(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
71
0
{
72
0
    struct ossl_rbt_entry *parent;
73
0
    struct ossl_rbt_entry *tmp;
74
75
0
    tmp = OSSL_RBE_RIGHT(rbe);
76
0
    OSSL_RBE_RIGHT(rbe) = OSSL_RBE_LEFT(tmp);
77
0
    if (OSSL_RBE_RIGHT(rbe) != NULL)
78
0
        OSSL_RBE_PARENT(OSSL_RBE_LEFT(tmp)) = rbe;
79
80
0
    parent = OSSL_RBE_PARENT(rbe);
81
0
    OSSL_RBE_PARENT(tmp) = parent;
82
0
    if (parent != NULL) {
83
0
        if (rbe == OSSL_RBE_LEFT(parent))
84
0
            OSSL_RBE_LEFT(parent) = tmp;
85
0
        else
86
0
            OSSL_RBE_RIGHT(parent) = tmp;
87
0
    } else
88
0
        OSSL_RBH_ROOT(rbt) = tmp;
89
90
0
    OSSL_RBE_LEFT(tmp) = rbe;
91
0
    OSSL_RBE_PARENT(rbe) = tmp;
92
0
}
93
94
static void
95
rbe_rotate_right(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
96
0
{
97
0
    struct ossl_rbt_entry *parent;
98
0
    struct ossl_rbt_entry *tmp;
99
100
0
    tmp = OSSL_RBE_LEFT(rbe);
101
0
    OSSL_RBE_LEFT(rbe) = OSSL_RBE_RIGHT(tmp);
102
0
    if (OSSL_RBE_LEFT(rbe) != NULL)
103
0
        OSSL_RBE_PARENT(OSSL_RBE_RIGHT(tmp)) = rbe;
104
105
0
    parent = OSSL_RBE_PARENT(rbe);
106
0
    OSSL_RBE_PARENT(tmp) = parent;
107
0
    if (parent != NULL) {
108
0
        if (rbe == OSSL_RBE_LEFT(parent))
109
0
            OSSL_RBE_LEFT(parent) = tmp;
110
0
        else
111
0
            OSSL_RBE_RIGHT(parent) = tmp;
112
0
    } else
113
0
        OSSL_RBH_ROOT(rbt) = tmp;
114
115
0
    OSSL_RBE_RIGHT(tmp) = rbe;
116
0
    OSSL_RBE_PARENT(rbe) = tmp;
117
0
}
118
119
static void
120
rbe_insert_color(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
121
0
{
122
0
    struct ossl_rbt_entry *parent, *gparent, *tmp;
123
124
0
    while ((parent = OSSL_RBE_PARENT(rbe)) != NULL && OSSL_RBE_COLOR(parent) == OSSL_RBT_RED) {
125
0
        gparent = OSSL_RBE_PARENT(parent);
126
127
0
        if (parent == OSSL_RBE_LEFT(gparent)) {
128
0
            tmp = OSSL_RBE_RIGHT(gparent);
129
0
            if (tmp != NULL && OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
130
0
                OSSL_RBE_COLOR(tmp) = OSSL_RBT_BLACK;
131
0
                rbe_set_blackred(parent, gparent);
132
0
                rbe = gparent;
133
0
                continue;
134
0
            }
135
136
0
            if (OSSL_RBE_RIGHT(parent) == rbe) {
137
0
                rbe_rotate_left(rbt, parent);
138
0
                tmp = parent;
139
0
                parent = rbe;
140
0
                rbe = tmp;
141
0
            }
142
143
0
            rbe_set_blackred(parent, gparent);
144
0
            rbe_rotate_right(rbt, gparent);
145
0
        } else {
146
0
            tmp = OSSL_RBE_LEFT(gparent);
147
0
            if (tmp != NULL && OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
148
0
                OSSL_RBE_COLOR(tmp) = OSSL_RBT_BLACK;
149
0
                rbe_set_blackred(parent, gparent);
150
0
                rbe = gparent;
151
0
                continue;
152
0
            }
153
154
0
            if (OSSL_RBE_LEFT(parent) == rbe) {
155
0
                rbe_rotate_right(rbt, parent);
156
0
                tmp = parent;
157
0
                parent = rbe;
158
0
                rbe = tmp;
159
0
            }
160
161
0
            rbe_set_blackred(parent, gparent);
162
0
            rbe_rotate_left(rbt, gparent);
163
0
        }
164
0
    }
165
166
0
    OSSL_RBE_COLOR(OSSL_RBH_ROOT(rbt)) = OSSL_RBT_BLACK;
167
0
}
168
169
static void
170
rbe_remove_color(struct ossl_rbt_tree *rbt,
171
    struct ossl_rbt_entry *parent, struct ossl_rbt_entry *rbe)
172
0
{
173
0
    struct ossl_rbt_entry *tmp;
174
175
0
    while ((rbe == NULL || OSSL_RBE_COLOR(rbe) == OSSL_RBT_BLACK) && rbe != OSSL_RBH_ROOT(rbt)) {
176
0
        if (OSSL_RBE_LEFT(parent) == rbe) {
177
0
            tmp = OSSL_RBE_RIGHT(parent);
178
0
            if (OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
179
0
                rbe_set_blackred(tmp, parent);
180
0
                rbe_rotate_left(rbt, parent);
181
0
                tmp = OSSL_RBE_RIGHT(parent);
182
0
            }
183
0
            if ((OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) && (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK)) {
184
0
                OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
185
0
                rbe = parent;
186
0
                parent = OSSL_RBE_PARENT(rbe);
187
0
            } else {
188
0
                if (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK) {
189
0
                    struct ossl_rbt_entry *oleft;
190
191
0
                    oleft = OSSL_RBE_LEFT(tmp);
192
0
                    if (oleft != NULL)
193
0
                        OSSL_RBE_COLOR(oleft) = OSSL_RBT_BLACK;
194
195
0
                    OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
196
0
                    rbe_rotate_right(rbt, tmp);
197
0
                    tmp = OSSL_RBE_RIGHT(parent);
198
0
                }
199
200
0
                OSSL_RBE_COLOR(tmp) = OSSL_RBE_COLOR(parent);
201
0
                OSSL_RBE_COLOR(parent) = OSSL_RBT_BLACK;
202
0
                if (OSSL_RBE_RIGHT(tmp))
203
0
                    OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) = OSSL_RBT_BLACK;
204
205
0
                rbe_rotate_left(rbt, parent);
206
0
                rbe = OSSL_RBH_ROOT(rbt);
207
0
                break;
208
0
            }
209
0
        } else {
210
0
            tmp = OSSL_RBE_LEFT(parent);
211
0
            if (OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
212
0
                rbe_set_blackred(tmp, parent);
213
0
                rbe_rotate_right(rbt, parent);
214
0
                tmp = OSSL_RBE_LEFT(parent);
215
0
            }
216
217
0
            if ((OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) && (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK)) {
218
0
                OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
219
0
                rbe = parent;
220
0
                parent = OSSL_RBE_PARENT(rbe);
221
0
            } else {
222
0
                if (OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) {
223
0
                    struct ossl_rbt_entry *oright;
224
225
0
                    oright = OSSL_RBE_RIGHT(tmp);
226
0
                    if (oright != NULL)
227
0
                        OSSL_RBE_COLOR(oright) = OSSL_RBT_BLACK;
228
229
0
                    OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
230
0
                    rbe_rotate_left(rbt, tmp);
231
0
                    tmp = OSSL_RBE_LEFT(parent);
232
0
                }
233
234
0
                OSSL_RBE_COLOR(tmp) = OSSL_RBE_COLOR(parent);
235
0
                OSSL_RBE_COLOR(parent) = OSSL_RBT_BLACK;
236
0
                if (OSSL_RBE_LEFT(tmp) != NULL)
237
0
                    OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) = OSSL_RBT_BLACK;
238
239
0
                rbe_rotate_right(rbt, parent);
240
0
                rbe = OSSL_RBH_ROOT(rbt);
241
0
                break;
242
0
            }
243
0
        }
244
0
    }
245
246
0
    if (rbe != NULL)
247
0
        OSSL_RBE_COLOR(rbe) = OSSL_RBT_BLACK;
248
0
}
249
250
static struct ossl_rbt_entry *
251
rbe_remove(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
252
0
{
253
0
    struct ossl_rbt_entry *child, *parent, *old = rbe;
254
0
    unsigned int color;
255
256
0
    if (OSSL_RBE_LEFT(rbe) == NULL)
257
0
        child = OSSL_RBE_RIGHT(rbe);
258
0
    else if (OSSL_RBE_RIGHT(rbe) == NULL)
259
0
        child = OSSL_RBE_LEFT(rbe);
260
0
    else {
261
0
        struct ossl_rbt_entry *tmp;
262
263
0
        rbe = OSSL_RBE_RIGHT(rbe);
264
0
        while ((tmp = OSSL_RBE_LEFT(rbe)) != NULL)
265
0
            rbe = tmp;
266
267
0
        child = OSSL_RBE_RIGHT(rbe);
268
0
        parent = OSSL_RBE_PARENT(rbe);
269
0
        color = OSSL_RBE_COLOR(rbe);
270
0
        if (child != NULL)
271
0
            OSSL_RBE_PARENT(child) = parent;
272
0
        if (parent != NULL) {
273
0
            if (OSSL_RBE_LEFT(parent) == rbe)
274
0
                OSSL_RBE_LEFT(parent) = child;
275
0
            else
276
0
                OSSL_RBE_RIGHT(parent) = child;
277
0
        } else
278
0
            OSSL_RBH_ROOT(rbt) = child;
279
0
        if (OSSL_RBE_PARENT(rbe) == old)
280
0
            parent = rbe;
281
0
        *rbe = *old;
282
283
0
        tmp = OSSL_RBE_PARENT(old);
284
0
        if (tmp != NULL) {
285
0
            if (OSSL_RBE_LEFT(tmp) == old)
286
0
                OSSL_RBE_LEFT(tmp) = rbe;
287
0
            else
288
0
                OSSL_RBE_RIGHT(tmp) = rbe;
289
0
        } else
290
0
            OSSL_RBH_ROOT(rbt) = rbe;
291
292
0
        OSSL_RBE_PARENT(OSSL_RBE_LEFT(old)) = rbe;
293
0
        if (OSSL_RBE_RIGHT(old))
294
0
            OSSL_RBE_PARENT(OSSL_RBE_RIGHT(old)) = rbe;
295
0
        goto color;
296
0
    }
297
298
0
    parent = OSSL_RBE_PARENT(rbe);
299
0
    color = OSSL_RBE_COLOR(rbe);
300
301
0
    if (child != NULL)
302
0
        OSSL_RBE_PARENT(child) = parent;
303
0
    if (parent != NULL) {
304
0
        if (OSSL_RBE_LEFT(parent) == rbe)
305
0
            OSSL_RBE_LEFT(parent) = child;
306
0
        else
307
0
            OSSL_RBE_RIGHT(parent) = child;
308
0
    } else
309
0
        OSSL_RBH_ROOT(rbt) = child;
310
0
color:
311
0
    if (color == OSSL_RBT_BLACK)
312
0
        rbe_remove_color(rbt, parent, child);
313
314
#ifndef NDEBUG
315
    if (old != NULL) {
316
        OSSL_RBE_PARENT(old) = NULL;
317
        OSSL_RBE_LEFT(old) = NULL;
318
        OSSL_RBE_RIGHT(old) = NULL;
319
    }
320
#endif
321
322
0
    return old;
323
0
}
324
325
void *
326
ossl_rbt_remove(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, void *elm)
327
0
{
328
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
329
0
    struct ossl_rbt_entry *old;
330
331
0
    old = rbe_remove(rbt, rbe);
332
333
0
    return old == NULL ? NULL : rbt_e2n(t, old);
334
0
}
335
336
void *
337
ossl_rbt_insert(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, void *elm)
338
0
{
339
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
340
0
    struct ossl_rbt_entry *tmp;
341
0
    struct ossl_rbt_entry *parent = NULL;
342
0
    void *node;
343
0
    int comp = 0;
344
345
#ifndef NDEBUG
346
    assert(rbe->rb_parent == NULL);
347
    assert(rbe->rb_left == NULL);
348
    assert(rbe->rb_right == NULL);
349
#endif
350
351
0
    tmp = OSSL_RBH_ROOT(rbt);
352
0
    while (tmp != NULL) {
353
0
        parent = tmp;
354
355
0
        node = rbt_e2n(t, tmp);
356
0
        comp = (*t->t_compare)(elm, node);
357
0
        if (comp < 0)
358
0
            tmp = OSSL_RBE_LEFT(tmp);
359
0
        else if (comp > 0)
360
0
            tmp = OSSL_RBE_RIGHT(tmp);
361
0
        else
362
0
            return node;
363
0
    }
364
365
0
    rbe_set(rbe, parent);
366
367
0
    if (parent != NULL) {
368
0
        if (comp < 0)
369
0
            OSSL_RBE_LEFT(parent) = rbe;
370
0
        else
371
0
            OSSL_RBE_RIGHT(parent) = rbe;
372
0
    } else
373
0
        OSSL_RBH_ROOT(rbt) = rbe;
374
375
0
    rbe_insert_color(rbt, rbe);
376
377
0
    return NULL;
378
0
}
379
380
/* Finds the node with the same key as elm */
381
void *
382
ossl_rbt_find(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, const void *key)
383
0
{
384
0
    struct ossl_rbt_entry *tmp = OSSL_RBH_ROOT(rbt);
385
0
    void *node;
386
0
    int comp;
387
388
0
    while (tmp != NULL) {
389
0
        node = rbt_e2n(t, tmp);
390
0
        comp = (*t->t_compare)(key, node);
391
0
        if (comp < 0)
392
0
            tmp = OSSL_RBE_LEFT(tmp);
393
0
        else if (comp > 0)
394
0
            tmp = OSSL_RBE_RIGHT(tmp);
395
0
        else
396
0
            return node;
397
0
    }
398
399
0
    return NULL;
400
0
}
401
402
/* Finds the first node greater than or equal to the search key */
403
void *
404
ossl_rbt_nfind(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, const void *key)
405
0
{
406
0
    struct ossl_rbt_entry *tmp = OSSL_RBH_ROOT(rbt);
407
0
    void *node;
408
0
    void *res = NULL;
409
0
    int comp;
410
411
0
    while (tmp != NULL) {
412
0
        node = rbt_e2n(t, tmp);
413
0
        comp = (*t->t_compare)(key, node);
414
0
        if (comp < 0) {
415
0
            res = node;
416
0
            tmp = OSSL_RBE_LEFT(tmp);
417
0
        } else if (comp > 0)
418
0
            tmp = OSSL_RBE_RIGHT(tmp);
419
0
        else
420
0
            return node;
421
0
    }
422
423
0
    return res;
424
0
}
425
426
void *
427
ossl_rbt_next(const struct ossl_rbt_type *t, void *elm)
428
0
{
429
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
430
431
0
    if (OSSL_RBE_RIGHT(rbe) != NULL) {
432
0
        rbe = OSSL_RBE_RIGHT(rbe);
433
0
        while (OSSL_RBE_LEFT(rbe) != NULL)
434
0
            rbe = OSSL_RBE_LEFT(rbe);
435
0
    } else {
436
0
        if (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_LEFT(OSSL_RBE_PARENT(rbe))))
437
0
            rbe = OSSL_RBE_PARENT(rbe);
438
0
        else {
439
0
            while (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_RIGHT(OSSL_RBE_PARENT(rbe))))
440
0
                rbe = OSSL_RBE_PARENT(rbe);
441
0
            rbe = OSSL_RBE_PARENT(rbe);
442
0
        }
443
0
    }
444
445
0
    return rbe == NULL ? NULL : rbt_e2n(t, rbe);
446
0
}
447
448
void *
449
ossl_rbt_prev(const struct ossl_rbt_type *t, void *elm)
450
0
{
451
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
452
453
0
    if (OSSL_RBE_LEFT(rbe)) {
454
0
        rbe = OSSL_RBE_LEFT(rbe);
455
0
        while (OSSL_RBE_RIGHT(rbe))
456
0
            rbe = OSSL_RBE_RIGHT(rbe);
457
0
    } else {
458
0
        if (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_RIGHT(OSSL_RBE_PARENT(rbe))))
459
0
            rbe = OSSL_RBE_PARENT(rbe);
460
0
        else {
461
0
            while (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_LEFT(OSSL_RBE_PARENT(rbe))))
462
0
                rbe = OSSL_RBE_PARENT(rbe);
463
0
            rbe = OSSL_RBE_PARENT(rbe);
464
0
        }
465
0
    }
466
467
0
    return rbe == NULL ? NULL : rbt_e2n(t, rbe);
468
0
}
469
470
void *
471
ossl_rbt_root(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt)
472
0
{
473
0
    struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt);
474
475
0
    return rbe == NULL ? rbe : rbt_e2n(t, rbe);
476
0
}
477
478
void *
479
ossl_rbt_min(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt)
480
0
{
481
0
    struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt);
482
0
    struct ossl_rbt_entry *parent = NULL;
483
484
0
    while (rbe != NULL) {
485
0
        parent = rbe;
486
0
        rbe = OSSL_RBE_LEFT(rbe);
487
0
    }
488
489
0
    return parent == NULL ? NULL : rbt_e2n(t, parent);
490
0
}
491
492
void *
493
ossl_rbt_max(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt)
494
0
{
495
0
    struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt);
496
0
    struct ossl_rbt_entry *parent = NULL;
497
498
0
    while (rbe != NULL) {
499
0
        parent = rbe;
500
0
        rbe = OSSL_RBE_RIGHT(rbe);
501
0
    }
502
503
0
    return parent == NULL ? NULL : rbt_e2n(t, parent);
504
0
}
505
506
void *
507
ossl_rbt_left(const struct ossl_rbt_type *t, void *node)
508
0
{
509
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
510
0
    rbe = OSSL_RBE_LEFT(rbe);
511
0
    return rbe == NULL ? NULL : rbt_e2n(t, rbe);
512
0
}
513
514
void *
515
ossl_rbt_right(const struct ossl_rbt_type *t, void *node)
516
0
{
517
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
518
0
    rbe = OSSL_RBE_RIGHT(rbe);
519
0
    return rbe == NULL ? NULL : rbt_e2n(t, rbe);
520
0
}
521
522
void *
523
ossl_rbt_parent(const struct ossl_rbt_type *t, void *node)
524
0
{
525
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
526
0
    rbe = OSSL_RBE_PARENT(rbe);
527
0
    return rbe == NULL ? NULL : rbt_e2n(t, rbe);
528
0
}
529
530
void ossl_rbt_set_left(const struct ossl_rbt_type *t, void *node, void *left)
531
0
{
532
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
533
0
    struct ossl_rbt_entry *rbl = (left == NULL) ? NULL : rbt_n2e(t, left);
534
535
0
    OSSL_RBE_LEFT(rbe) = rbl;
536
0
}
537
538
void ossl_rbt_set_right(const struct ossl_rbt_type *t, void *node, void *right)
539
0
{
540
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
541
0
    struct ossl_rbt_entry *rbr = (right == NULL) ? NULL : rbt_n2e(t, right);
542
543
0
    OSSL_RBE_RIGHT(rbe) = rbr;
544
0
}
545
546
void ossl_rbt_set_parent(const struct ossl_rbt_type *t, void *node, void *parent)
547
0
{
548
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
549
0
    struct ossl_rbt_entry *rbp = (parent == NULL) ? NULL : rbt_n2e(t, parent);
550
551
0
    OSSL_RBE_PARENT(rbe) = rbp;
552
0
}
553
554
void ossl_rbt_init_rbe(const struct ossl_rbt_type *t, void *node)
555
0
{
556
0
    struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
557
558
0
    OSSL_RBE_PARENT(rbe) = NULL;
559
0
    OSSL_RBE_LEFT(rbe) = NULL;
560
0
    OSSL_RBE_RIGHT(rbe) = NULL;
561
0
}