Line data Source code
1 : /* $OpenBSD: subr_tree.c,v 1.9 2017/06/08 03:30:52 dlg Exp $ */
2 :
3 : /*
4 : * Copyright 2002 Niels Provos <provos@citi.umich.edu>
5 : * All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : *
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 :
28 : /*
29 : * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
30 : *
31 : * Permission to use, copy, modify, and distribute this software for any
32 : * purpose with or without fee is hereby granted, provided that the above
33 : * copyright notice and this permission notice appear in all copies.
34 : *
35 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
36 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
37 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
38 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
39 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
40 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
41 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 : */
43 :
44 : #ifdef HAVE_CONFIG_H
45 : #include "config.h"
46 : #endif
47 :
48 : #include <stdlib.h>
49 :
50 : #include <lib/openbsd-tree.h>
51 :
52 284 : static inline struct rb_entry *rb_n2e(const struct rb_type *t, void *node)
53 : {
54 284 : unsigned long addr = (unsigned long)node;
55 :
56 284 : return ((struct rb_entry *)(addr + t->t_offset));
57 : }
58 :
59 1442 : static inline void *rb_e2n(const struct rb_type *t, struct rb_entry *rbe)
60 : {
61 1442 : unsigned long addr = (unsigned long)rbe;
62 :
63 1442 : return ((void *)(addr - t->t_offset));
64 : }
65 :
66 : #define RBE_LEFT(_rbe) (_rbe)->rbt_left
67 : #define RBE_RIGHT(_rbe) (_rbe)->rbt_right
68 : #define RBE_PARENT(_rbe) (_rbe)->rbt_parent
69 : #define RBE_COLOR(_rbe) (_rbe)->rbt_color
70 :
71 : #define RBH_ROOT(_rbt) (_rbt)->rbt_root
72 :
73 69 : static inline void rbe_set(struct rb_entry *rbe, struct rb_entry *parent)
74 : {
75 69 : RBE_PARENT(rbe) = parent;
76 69 : RBE_LEFT(rbe) = RBE_RIGHT(rbe) = NULL;
77 69 : RBE_COLOR(rbe) = RB_RED;
78 : }
79 :
80 16 : static inline void rbe_set_blackred(struct rb_entry *black,
81 : struct rb_entry *red)
82 : {
83 16 : RBE_COLOR(black) = RB_BLACK;
84 16 : RBE_COLOR(red) = RB_RED;
85 : }
86 :
87 0 : static inline void rbe_augment(const struct rb_type *t, struct rb_entry *rbe)
88 : {
89 0 : (*t->t_augment)(rb_e2n(t, rbe));
90 0 : }
91 :
92 70 : static inline void rbe_if_augment(const struct rb_type *t, struct rb_entry *rbe)
93 : {
94 70 : if (t->t_augment != NULL)
95 0 : rbe_augment(t, rbe);
96 : }
97 :
98 14 : static inline void rbe_rotate_left(const struct rb_type *t,
99 : struct rbt_tree *rbt, struct rb_entry *rbe)
100 : {
101 14 : struct rb_entry *parent;
102 14 : struct rb_entry *tmp;
103 :
104 14 : tmp = RBE_RIGHT(rbe);
105 14 : RBE_RIGHT(rbe) = RBE_LEFT(tmp);
106 14 : if (RBE_RIGHT(rbe) != NULL)
107 0 : RBE_PARENT(RBE_LEFT(tmp)) = rbe;
108 :
109 14 : parent = RBE_PARENT(rbe);
110 14 : RBE_PARENT(tmp) = parent;
111 14 : if (parent != NULL) {
112 6 : if (rbe == RBE_LEFT(parent))
113 0 : RBE_LEFT(parent) = tmp;
114 : else
115 6 : RBE_RIGHT(parent) = tmp;
116 : } else
117 8 : RBH_ROOT(rbt) = tmp;
118 :
119 14 : RBE_LEFT(tmp) = rbe;
120 14 : RBE_PARENT(rbe) = tmp;
121 :
122 14 : if (t->t_augment != NULL) {
123 0 : rbe_augment(t, rbe);
124 0 : rbe_augment(t, tmp);
125 0 : parent = RBE_PARENT(tmp);
126 0 : if (parent != NULL)
127 0 : rbe_augment(t, parent);
128 : }
129 14 : }
130 :
131 6 : static inline void rbe_rotate_right(const struct rb_type *t,
132 : struct rbt_tree *rbt, struct rb_entry *rbe)
133 : {
134 6 : struct rb_entry *parent;
135 6 : struct rb_entry *tmp;
136 :
137 6 : tmp = RBE_LEFT(rbe);
138 6 : RBE_LEFT(rbe) = RBE_RIGHT(tmp);
139 6 : if (RBE_LEFT(rbe) != NULL)
140 0 : RBE_PARENT(RBE_RIGHT(tmp)) = rbe;
141 :
142 6 : parent = RBE_PARENT(rbe);
143 6 : RBE_PARENT(tmp) = parent;
144 6 : if (parent != NULL) {
145 2 : if (rbe == RBE_LEFT(parent))
146 0 : RBE_LEFT(parent) = tmp;
147 : else
148 2 : RBE_RIGHT(parent) = tmp;
149 : } else
150 4 : RBH_ROOT(rbt) = tmp;
151 :
152 6 : RBE_RIGHT(tmp) = rbe;
153 6 : RBE_PARENT(rbe) = tmp;
154 :
155 6 : if (t->t_augment != NULL) {
156 0 : rbe_augment(t, rbe);
157 0 : rbe_augment(t, tmp);
158 0 : parent = RBE_PARENT(tmp);
159 0 : if (parent != NULL)
160 0 : rbe_augment(t, parent);
161 : }
162 6 : }
163 :
164 69 : static inline void rbe_insert_color(const struct rb_type *t,
165 : struct rbt_tree *rbt, struct rb_entry *rbe)
166 : {
167 69 : struct rb_entry *parent, *gparent, *tmp;
168 :
169 69 : while ((parent = RBE_PARENT(rbe)) != NULL
170 85 : && RBE_COLOR(parent) == RB_RED) {
171 16 : gparent = RBE_PARENT(parent);
172 :
173 16 : if (parent == RBE_LEFT(gparent)) {
174 2 : tmp = RBE_RIGHT(gparent);
175 2 : if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) {
176 2 : RBE_COLOR(tmp) = RB_BLACK;
177 2 : rbe_set_blackred(parent, gparent);
178 2 : rbe = gparent;
179 2 : continue;
180 : }
181 :
182 0 : if (RBE_RIGHT(parent) == rbe) {
183 0 : rbe_rotate_left(t, rbt, parent);
184 0 : tmp = parent;
185 0 : parent = rbe;
186 0 : rbe = tmp;
187 : }
188 :
189 0 : rbe_set_blackred(parent, gparent);
190 0 : rbe_rotate_right(t, rbt, gparent);
191 : } else {
192 14 : tmp = RBE_LEFT(gparent);
193 14 : if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) {
194 6 : RBE_COLOR(tmp) = RB_BLACK;
195 6 : rbe_set_blackred(parent, gparent);
196 6 : rbe = gparent;
197 6 : continue;
198 : }
199 :
200 8 : if (RBE_LEFT(parent) == rbe) {
201 2 : rbe_rotate_right(t, rbt, parent);
202 2 : tmp = parent;
203 2 : parent = rbe;
204 2 : rbe = tmp;
205 : }
206 :
207 8 : rbe_set_blackred(parent, gparent);
208 8 : rbe_rotate_left(t, rbt, gparent);
209 : }
210 : }
211 :
212 69 : RBE_COLOR(RBH_ROOT(rbt)) = RB_BLACK;
213 69 : }
214 :
215 91 : static inline void rbe_remove_color(const struct rb_type *t,
216 : struct rbt_tree *rbt,
217 : struct rb_entry *parent,
218 : struct rb_entry *rbe)
219 : {
220 91 : struct rb_entry *tmp;
221 :
222 135 : while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK)
223 115 : && rbe != RBH_ROOT(rbt) && parent) {
224 24 : if (RBE_LEFT(parent) == rbe) {
225 12 : tmp = RBE_RIGHT(parent);
226 12 : if (RBE_COLOR(tmp) == RB_RED) {
227 0 : rbe_set_blackred(tmp, parent);
228 0 : rbe_rotate_left(t, rbt, parent);
229 0 : tmp = RBE_RIGHT(parent);
230 : }
231 12 : if ((RBE_LEFT(tmp) == NULL
232 0 : || RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
233 12 : && (RBE_RIGHT(tmp) == NULL
234 6 : || RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
235 6 : RBE_COLOR(tmp) = RB_RED;
236 6 : rbe = parent;
237 6 : parent = RBE_PARENT(rbe);
238 : } else {
239 6 : if (RBE_RIGHT(tmp) == NULL
240 6 : || RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) {
241 0 : struct rb_entry *oleft;
242 :
243 0 : oleft = RBE_LEFT(tmp);
244 0 : if (oleft != NULL)
245 0 : RBE_COLOR(oleft) = RB_BLACK;
246 :
247 0 : RBE_COLOR(tmp) = RB_RED;
248 0 : rbe_rotate_right(t, rbt, tmp);
249 0 : tmp = RBE_RIGHT(parent);
250 : }
251 :
252 6 : RBE_COLOR(tmp) = RBE_COLOR(parent);
253 6 : RBE_COLOR(parent) = RB_BLACK;
254 6 : if (RBE_RIGHT(tmp))
255 6 : RBE_COLOR(RBE_RIGHT(tmp)) = RB_BLACK;
256 :
257 6 : rbe_rotate_left(t, rbt, parent);
258 6 : rbe = RBH_ROOT(rbt);
259 6 : break;
260 : }
261 : } else {
262 12 : tmp = RBE_LEFT(parent);
263 12 : if (RBE_COLOR(tmp) == RB_RED) {
264 0 : rbe_set_blackred(tmp, parent);
265 0 : rbe_rotate_right(t, rbt, parent);
266 0 : tmp = RBE_LEFT(parent);
267 : }
268 :
269 12 : if ((RBE_LEFT(tmp) == NULL
270 4 : || RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
271 8 : && (RBE_RIGHT(tmp) == NULL
272 0 : || RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
273 8 : RBE_COLOR(tmp) = RB_RED;
274 8 : rbe = parent;
275 8 : parent = RBE_PARENT(rbe);
276 : } else {
277 4 : if (RBE_LEFT(tmp) == NULL
278 4 : || RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) {
279 0 : struct rb_entry *oright;
280 :
281 0 : oright = RBE_RIGHT(tmp);
282 0 : if (oright != NULL)
283 0 : RBE_COLOR(oright) = RB_BLACK;
284 :
285 0 : RBE_COLOR(tmp) = RB_RED;
286 0 : rbe_rotate_left(t, rbt, tmp);
287 0 : tmp = RBE_LEFT(parent);
288 : }
289 :
290 4 : RBE_COLOR(tmp) = RBE_COLOR(parent);
291 4 : RBE_COLOR(parent) = RB_BLACK;
292 4 : if (RBE_LEFT(tmp) != NULL)
293 4 : RBE_COLOR(RBE_LEFT(tmp)) = RB_BLACK;
294 :
295 4 : rbe_rotate_right(t, rbt, parent);
296 4 : rbe = RBH_ROOT(rbt);
297 4 : break;
298 : }
299 : }
300 : }
301 :
302 91 : if (rbe != NULL)
303 54 : RBE_COLOR(rbe) = RB_BLACK;
304 91 : }
305 :
306 : static inline struct rb_entry *
307 91 : rbe_remove(const struct rb_type *t, struct rbt_tree *rbt, struct rb_entry *rbe)
308 : {
309 91 : struct rb_entry *child, *parent, *old = rbe;
310 91 : unsigned int color;
311 :
312 91 : if (RBE_LEFT(rbe) == NULL)
313 51 : child = RBE_RIGHT(rbe);
314 40 : else if (RBE_RIGHT(rbe) == NULL)
315 : child = RBE_LEFT(rbe);
316 : else {
317 : struct rb_entry *tmp;
318 :
319 : rbe = RBE_RIGHT(rbe);
320 44 : while ((tmp = RBE_LEFT(rbe)) != NULL)
321 : rbe = tmp;
322 :
323 32 : child = RBE_RIGHT(rbe);
324 32 : parent = RBE_PARENT(rbe);
325 32 : color = RBE_COLOR(rbe);
326 32 : if (child != NULL)
327 12 : RBE_PARENT(child) = parent;
328 32 : if (parent != NULL) {
329 32 : if (RBE_LEFT(parent) == rbe)
330 12 : RBE_LEFT(parent) = child;
331 : else
332 20 : RBE_RIGHT(parent) = child;
333 :
334 32 : rbe_if_augment(t, parent);
335 : } else
336 0 : RBH_ROOT(rbt) = child;
337 32 : if (RBE_PARENT(rbe) == old)
338 20 : parent = rbe;
339 32 : *rbe = *old;
340 :
341 32 : tmp = RBE_PARENT(old);
342 32 : if (tmp != NULL) {
343 0 : if (RBE_LEFT(tmp) == old)
344 0 : RBE_LEFT(tmp) = rbe;
345 : else
346 0 : RBE_RIGHT(tmp) = rbe;
347 :
348 0 : rbe_if_augment(t, tmp);
349 : } else
350 32 : RBH_ROOT(rbt) = rbe;
351 :
352 32 : RBE_PARENT(RBE_LEFT(old)) = rbe;
353 32 : if (RBE_RIGHT(old))
354 20 : RBE_PARENT(RBE_RIGHT(old)) = rbe;
355 :
356 32 : if (t->t_augment != NULL && parent != NULL) {
357 : tmp = parent;
358 0 : do {
359 0 : rbe_augment(t, tmp);
360 0 : tmp = RBE_PARENT(tmp);
361 0 : } while (tmp != NULL);
362 : }
363 :
364 32 : goto color;
365 : }
366 :
367 59 : parent = RBE_PARENT(rbe);
368 59 : color = RBE_COLOR(rbe);
369 :
370 59 : if (child != NULL)
371 18 : RBE_PARENT(child) = parent;
372 59 : if (parent != NULL) {
373 4 : if (RBE_LEFT(parent) == rbe)
374 4 : RBE_LEFT(parent) = child;
375 : else
376 0 : RBE_RIGHT(parent) = child;
377 :
378 4 : rbe_if_augment(t, parent);
379 : } else
380 55 : RBH_ROOT(rbt) = child;
381 91 : color:
382 91 : if (color == RB_BLACK)
383 91 : rbe_remove_color(t, rbt, parent, child);
384 :
385 91 : return (old);
386 : }
387 :
388 91 : void *_rb_remove(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
389 : {
390 91 : struct rb_entry *rbe = rb_n2e(t, elm);
391 91 : struct rb_entry *old;
392 :
393 91 : old = rbe_remove(t, rbt, rbe);
394 :
395 91 : return (old == NULL ? NULL : rb_e2n(t, old));
396 : }
397 :
398 69 : void *_rb_insert(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
399 : {
400 69 : struct rb_entry *rbe = rb_n2e(t, elm);
401 69 : struct rb_entry *tmp;
402 69 : struct rb_entry *parent = NULL;
403 69 : void *node;
404 69 : int comp = 0;
405 :
406 69 : tmp = RBH_ROOT(rbt);
407 129 : while (tmp != NULL) {
408 60 : parent = tmp;
409 :
410 60 : node = rb_e2n(t, tmp);
411 60 : comp = (*t->t_compare)(elm, node);
412 60 : if (comp < 0)
413 8 : tmp = RBE_LEFT(tmp);
414 52 : else if (comp > 0)
415 52 : tmp = RBE_RIGHT(tmp);
416 : else
417 0 : return (node);
418 : }
419 :
420 69 : rbe_set(rbe, parent);
421 :
422 69 : if (parent != NULL) {
423 34 : if (comp < 0)
424 4 : RBE_LEFT(parent) = rbe;
425 : else
426 30 : RBE_RIGHT(parent) = rbe;
427 :
428 34 : rbe_if_augment(t, parent);
429 : } else
430 35 : RBH_ROOT(rbt) = rbe;
431 :
432 69 : rbe_insert_color(t, rbt, rbe);
433 :
434 69 : return NULL;
435 : }
436 :
437 : /* Finds the node with the same key as elm */
438 952 : void *_rb_find(const struct rb_type *t, const struct rbt_tree *rbt,
439 : const void *key)
440 : {
441 952 : struct rb_entry *tmp = RBH_ROOT(rbt);
442 952 : void *node;
443 952 : int comp;
444 :
445 1042 : while (tmp != NULL) {
446 1000 : node = rb_e2n(t, tmp);
447 1000 : comp = (*t->t_compare)(key, node);
448 1000 : if (comp < 0)
449 4 : tmp = RBE_LEFT(tmp);
450 996 : else if (comp > 0)
451 86 : tmp = RBE_RIGHT(tmp);
452 : else
453 910 : return (node);
454 : }
455 :
456 : return NULL;
457 : }
458 :
459 : /* Finds the first node greater than or equal to the search key */
460 0 : void *_rb_nfind(const struct rb_type *t, const struct rbt_tree *rbt,
461 : const void *key)
462 : {
463 0 : struct rb_entry *tmp = RBH_ROOT(rbt);
464 0 : void *node;
465 0 : void *res = NULL;
466 0 : int comp;
467 :
468 0 : while (tmp != NULL) {
469 0 : node = rb_e2n(t, tmp);
470 0 : comp = (*t->t_compare)(key, node);
471 0 : if (comp < 0) {
472 0 : res = node;
473 0 : tmp = RBE_LEFT(tmp);
474 0 : } else if (comp > 0)
475 0 : tmp = RBE_RIGHT(tmp);
476 : else
477 0 : return (node);
478 : }
479 :
480 : return (res);
481 : }
482 :
483 124 : void *_rb_next(const struct rb_type *t, void *elm)
484 : {
485 124 : struct rb_entry *rbe = rb_n2e(t, elm);
486 :
487 124 : if (RBE_RIGHT(rbe) != NULL) {
488 : rbe = RBE_RIGHT(rbe);
489 34 : while (RBE_LEFT(rbe) != NULL)
490 : rbe = RBE_LEFT(rbe);
491 : } else {
492 90 : if (RBE_PARENT(rbe) && (rbe == RBE_LEFT(RBE_PARENT(rbe))))
493 : rbe = RBE_PARENT(rbe);
494 : else {
495 106 : while (RBE_PARENT(rbe)
496 106 : && (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
497 : rbe = RBE_PARENT(rbe);
498 : rbe = RBE_PARENT(rbe);
499 : }
500 : }
501 :
502 124 : return (rbe == NULL ? NULL : rb_e2n(t, rbe));
503 : }
504 :
505 0 : void *_rb_prev(const struct rb_type *t, void *elm)
506 : {
507 0 : struct rb_entry *rbe = rb_n2e(t, elm);
508 :
509 0 : if (RBE_LEFT(rbe)) {
510 : rbe = RBE_LEFT(rbe);
511 0 : while (RBE_RIGHT(rbe))
512 : rbe = RBE_RIGHT(rbe);
513 : } else {
514 0 : if (RBE_PARENT(rbe) && (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
515 : rbe = RBE_PARENT(rbe);
516 : else {
517 0 : while (RBE_PARENT(rbe)
518 0 : && (rbe == RBE_LEFT(RBE_PARENT(rbe))))
519 : rbe = RBE_PARENT(rbe);
520 : rbe = RBE_PARENT(rbe);
521 : }
522 : }
523 :
524 0 : return (rbe == NULL ? NULL : rb_e2n(t, rbe));
525 : }
526 :
527 61 : void *_rb_root(const struct rb_type *t, const struct rbt_tree *rbt)
528 : {
529 61 : struct rb_entry *rbe = RBH_ROOT(rbt);
530 :
531 61 : return (rbe == NULL ? rbe : rb_e2n(t, rbe));
532 : }
533 :
534 237 : void *_rb_min(const struct rb_type *t, const struct rbt_tree *rbt)
535 : {
536 237 : struct rb_entry *rbe = RBH_ROOT(rbt);
537 237 : struct rb_entry *parent = NULL;
538 :
539 433 : while (rbe != NULL) {
540 196 : parent = rbe;
541 196 : rbe = RBE_LEFT(rbe);
542 : }
543 :
544 237 : return (parent == NULL ? NULL : rb_e2n(t, parent));
545 : }
546 :
547 0 : void *_rb_max(const struct rb_type *t, const struct rbt_tree *rbt)
548 : {
549 0 : struct rb_entry *rbe = RBH_ROOT(rbt);
550 0 : struct rb_entry *parent = NULL;
551 :
552 0 : while (rbe != NULL) {
553 0 : parent = rbe;
554 0 : rbe = RBE_RIGHT(rbe);
555 : }
556 :
557 0 : return (parent == NULL ? NULL : rb_e2n(t, parent));
558 : }
559 :
560 0 : void *_rb_left(const struct rb_type *t, void *node)
561 : {
562 0 : struct rb_entry *rbe = rb_n2e(t, node);
563 0 : rbe = RBE_LEFT(rbe);
564 0 : return (rbe == NULL ? NULL : rb_e2n(t, rbe));
565 : }
566 :
567 0 : void *_rb_right(const struct rb_type *t, void *node)
568 : {
569 0 : struct rb_entry *rbe = rb_n2e(t, node);
570 0 : rbe = RBE_RIGHT(rbe);
571 0 : return (rbe == NULL ? NULL : rb_e2n(t, rbe));
572 : }
573 :
574 0 : void *_rb_parent(const struct rb_type *t, void *node)
575 : {
576 0 : struct rb_entry *rbe = rb_n2e(t, node);
577 0 : rbe = RBE_PARENT(rbe);
578 0 : return (rbe == NULL ? NULL : rb_e2n(t, rbe));
579 : }
580 :
581 0 : void _rb_set_left(const struct rb_type *t, void *node, void *left)
582 : {
583 0 : struct rb_entry *rbe = rb_n2e(t, node);
584 0 : struct rb_entry *rbl = (left == NULL) ? NULL : rb_n2e(t, left);
585 :
586 0 : RBE_LEFT(rbe) = rbl;
587 0 : }
588 :
589 0 : void _rb_set_right(const struct rb_type *t, void *node, void *right)
590 : {
591 0 : struct rb_entry *rbe = rb_n2e(t, node);
592 0 : struct rb_entry *rbr = (right == NULL) ? NULL : rb_n2e(t, right);
593 :
594 0 : RBE_RIGHT(rbe) = rbr;
595 0 : }
596 :
597 0 : void _rb_set_parent(const struct rb_type *t, void *node, void *parent)
598 : {
599 0 : struct rb_entry *rbe = rb_n2e(t, node);
600 0 : struct rb_entry *rbp = (parent == NULL) ? NULL : rb_n2e(t, parent);
601 :
602 0 : RBE_PARENT(rbe) = rbp;
603 0 : }
604 :
605 0 : void _rb_poison(const struct rb_type *t, void *node, unsigned long poison)
606 : {
607 0 : struct rb_entry *rbe = rb_n2e(t, node);
608 :
609 0 : RBE_PARENT(rbe) = RBE_LEFT(rbe) = RBE_RIGHT(rbe) =
610 0 : (struct rb_entry *)poison;
611 0 : }
612 :
613 0 : int _rb_check(const struct rb_type *t, void *node, unsigned long poison)
614 : {
615 0 : struct rb_entry *rbe = rb_n2e(t, node);
616 :
617 0 : return ((unsigned long)RBE_PARENT(rbe) == poison
618 0 : && (unsigned long)RBE_LEFT(rbe) == poison
619 0 : && (unsigned long)RBE_RIGHT(rbe) == poison);
620 : }
|