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