xref: /openbsd-src/lib/libc/gen/tree.c (revision 6728b1666b77468c8838e1c56283e867ac1159a7)
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