xref: /f-stack/freebsd/sys/tree.h (revision 22ce4aff)
1a9643ea8Slogwang /*	$NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $	*/
2a9643ea8Slogwang /*	$OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $	*/
3a9643ea8Slogwang /* $FreeBSD$ */
4a9643ea8Slogwang 
5a9643ea8Slogwang /*-
6*22ce4affSfengbojiang  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7*22ce4affSfengbojiang  *
8a9643ea8Slogwang  * Copyright 2002 Niels Provos <[email protected]>
9a9643ea8Slogwang  * All rights reserved.
10a9643ea8Slogwang  *
11a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
12a9643ea8Slogwang  * modification, are permitted provided that the following conditions
13a9643ea8Slogwang  * are met:
14a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
15a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer.
16a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
17a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer in the
18a9643ea8Slogwang  *    documentation and/or other materials provided with the distribution.
19a9643ea8Slogwang  *
20a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21a9643ea8Slogwang  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22a9643ea8Slogwang  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23a9643ea8Slogwang  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24a9643ea8Slogwang  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25a9643ea8Slogwang  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26a9643ea8Slogwang  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27a9643ea8Slogwang  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28a9643ea8Slogwang  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29a9643ea8Slogwang  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30a9643ea8Slogwang  */
31a9643ea8Slogwang 
32a9643ea8Slogwang #ifndef	_SYS_TREE_H_
33a9643ea8Slogwang #define	_SYS_TREE_H_
34a9643ea8Slogwang 
35a9643ea8Slogwang #include <sys/cdefs.h>
36a9643ea8Slogwang 
37a9643ea8Slogwang /*
38a9643ea8Slogwang  * This file defines data structures for different types of trees:
39*22ce4affSfengbojiang  * splay trees and rank-balanced trees.
40a9643ea8Slogwang  *
41a9643ea8Slogwang  * A splay tree is a self-organizing data structure.  Every operation
42a9643ea8Slogwang  * on the tree causes a splay to happen.  The splay moves the requested
43a9643ea8Slogwang  * node to the root of the tree and partly rebalances it.
44a9643ea8Slogwang  *
45a9643ea8Slogwang  * This has the benefit that request locality causes faster lookups as
46a9643ea8Slogwang  * the requested nodes move to the top of the tree.  On the other hand,
47a9643ea8Slogwang  * every lookup causes memory writes.
48a9643ea8Slogwang  *
49a9643ea8Slogwang  * The Balance Theorem bounds the total access time for m operations
50a9643ea8Slogwang  * and n inserts on an initially empty tree as O((m + n)lg n).  The
51a9643ea8Slogwang  * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
52a9643ea8Slogwang  *
53*22ce4affSfengbojiang  * A rank-balanced tree is a binary search tree with an integer
54*22ce4affSfengbojiang  * rank-difference as an attribute of each pointer from parent to child.
55*22ce4affSfengbojiang  * The sum of the rank-differences on any path from a node down to null is
56*22ce4affSfengbojiang  * the same, and defines the rank of that node. The rank of the null node
57*22ce4affSfengbojiang  * is -1.
58a9643ea8Slogwang  *
59*22ce4affSfengbojiang  * Different additional conditions define different sorts of balanced
60*22ce4affSfengbojiang  * trees, including "red-black" and "AVL" trees.  The set of conditions
61*22ce4affSfengbojiang  * applied here are the "weak-AVL" conditions of Haeupler, Sen and Tarjan:
62*22ce4affSfengbojiang  *	- every rank-difference is 1 or 2.
63*22ce4affSfengbojiang  *	- the rank of any leaf is 1.
64*22ce4affSfengbojiang  *
65*22ce4affSfengbojiang  * For historical reasons, rank differences that are even are associated
66*22ce4affSfengbojiang  * with the color red (Rank-Even-Difference), and the child that a red edge
67*22ce4affSfengbojiang  * points to is called a red child.
68*22ce4affSfengbojiang  *
69*22ce4affSfengbojiang  * Every operation on a rank-balanced tree is bounded as O(lg n).
70*22ce4affSfengbojiang  * The maximum height of a rank-balanced tree is 2lg (n+1).
71a9643ea8Slogwang  */
72a9643ea8Slogwang 
73a9643ea8Slogwang #define SPLAY_HEAD(name, type)						\
74a9643ea8Slogwang struct name {								\
75a9643ea8Slogwang 	struct type *sph_root; /* root of the tree */			\
76a9643ea8Slogwang }
77a9643ea8Slogwang 
78a9643ea8Slogwang #define SPLAY_INITIALIZER(root)						\
79a9643ea8Slogwang 	{ NULL }
80a9643ea8Slogwang 
81a9643ea8Slogwang #define SPLAY_INIT(root) do {						\
82a9643ea8Slogwang 	(root)->sph_root = NULL;					\
83a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
84a9643ea8Slogwang 
85a9643ea8Slogwang #define SPLAY_ENTRY(type)						\
86a9643ea8Slogwang struct {								\
87a9643ea8Slogwang 	struct type *spe_left; /* left element */			\
88a9643ea8Slogwang 	struct type *spe_right; /* right element */			\
89a9643ea8Slogwang }
90a9643ea8Slogwang 
91a9643ea8Slogwang #define SPLAY_LEFT(elm, field)		(elm)->field.spe_left
92a9643ea8Slogwang #define SPLAY_RIGHT(elm, field)		(elm)->field.spe_right
93a9643ea8Slogwang #define SPLAY_ROOT(head)		(head)->sph_root
94a9643ea8Slogwang #define SPLAY_EMPTY(head)		(SPLAY_ROOT(head) == NULL)
95a9643ea8Slogwang 
96a9643ea8Slogwang /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
97a9643ea8Slogwang #define SPLAY_ROTATE_RIGHT(head, tmp, field) do {			\
98a9643ea8Slogwang 	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);	\
99a9643ea8Slogwang 	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
100a9643ea8Slogwang 	(head)->sph_root = tmp;						\
101a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
102a9643ea8Slogwang 
103a9643ea8Slogwang #define SPLAY_ROTATE_LEFT(head, tmp, field) do {			\
104a9643ea8Slogwang 	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);	\
105a9643ea8Slogwang 	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
106a9643ea8Slogwang 	(head)->sph_root = tmp;						\
107a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
108a9643ea8Slogwang 
109a9643ea8Slogwang #define SPLAY_LINKLEFT(head, tmp, field) do {				\
110a9643ea8Slogwang 	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
111a9643ea8Slogwang 	tmp = (head)->sph_root;						\
112a9643ea8Slogwang 	(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);		\
113a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
114a9643ea8Slogwang 
115a9643ea8Slogwang #define SPLAY_LINKRIGHT(head, tmp, field) do {				\
116a9643ea8Slogwang 	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
117a9643ea8Slogwang 	tmp = (head)->sph_root;						\
118a9643ea8Slogwang 	(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);	\
119a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
120a9643ea8Slogwang 
121a9643ea8Slogwang #define SPLAY_ASSEMBLE(head, node, left, right, field) do {		\
122a9643ea8Slogwang 	SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);	\
123a9643ea8Slogwang 	SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
124a9643ea8Slogwang 	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);	\
125a9643ea8Slogwang 	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);	\
126a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
127a9643ea8Slogwang 
128a9643ea8Slogwang /* Generates prototypes and inline functions */
129a9643ea8Slogwang 
130a9643ea8Slogwang #define SPLAY_PROTOTYPE(name, type, field, cmp)				\
131a9643ea8Slogwang void name##_SPLAY(struct name *, struct type *);			\
132a9643ea8Slogwang void name##_SPLAY_MINMAX(struct name *, int);				\
133a9643ea8Slogwang struct type *name##_SPLAY_INSERT(struct name *, struct type *);		\
134a9643ea8Slogwang struct type *name##_SPLAY_REMOVE(struct name *, struct type *);		\
135a9643ea8Slogwang 									\
136a9643ea8Slogwang /* Finds the node with the same key as elm */				\
137*22ce4affSfengbojiang static __unused __inline struct type *					\
138a9643ea8Slogwang name##_SPLAY_FIND(struct name *head, struct type *elm)			\
139a9643ea8Slogwang {									\
140a9643ea8Slogwang 	if (SPLAY_EMPTY(head))						\
141a9643ea8Slogwang 		return(NULL);						\
142a9643ea8Slogwang 	name##_SPLAY(head, elm);					\
143a9643ea8Slogwang 	if ((cmp)(elm, (head)->sph_root) == 0)				\
144a9643ea8Slogwang 		return (head->sph_root);				\
145a9643ea8Slogwang 	return (NULL);							\
146a9643ea8Slogwang }									\
147a9643ea8Slogwang 									\
148*22ce4affSfengbojiang static __unused __inline struct type *					\
149a9643ea8Slogwang name##_SPLAY_NEXT(struct name *head, struct type *elm)			\
150a9643ea8Slogwang {									\
151a9643ea8Slogwang 	name##_SPLAY(head, elm);					\
152a9643ea8Slogwang 	if (SPLAY_RIGHT(elm, field) != NULL) {				\
153a9643ea8Slogwang 		elm = SPLAY_RIGHT(elm, field);				\
154a9643ea8Slogwang 		while (SPLAY_LEFT(elm, field) != NULL) {		\
155a9643ea8Slogwang 			elm = SPLAY_LEFT(elm, field);			\
156a9643ea8Slogwang 		}							\
157a9643ea8Slogwang 	} else								\
158a9643ea8Slogwang 		elm = NULL;						\
159a9643ea8Slogwang 	return (elm);							\
160a9643ea8Slogwang }									\
161a9643ea8Slogwang 									\
162*22ce4affSfengbojiang static __unused __inline struct type *					\
163a9643ea8Slogwang name##_SPLAY_MIN_MAX(struct name *head, int val)			\
164a9643ea8Slogwang {									\
165a9643ea8Slogwang 	name##_SPLAY_MINMAX(head, val);					\
166a9643ea8Slogwang         return (SPLAY_ROOT(head));					\
167a9643ea8Slogwang }
168a9643ea8Slogwang 
169a9643ea8Slogwang /* Main splay operation.
170a9643ea8Slogwang  * Moves node close to the key of elm to top
171a9643ea8Slogwang  */
172a9643ea8Slogwang #define SPLAY_GENERATE(name, type, field, cmp)				\
173a9643ea8Slogwang struct type *								\
174a9643ea8Slogwang name##_SPLAY_INSERT(struct name *head, struct type *elm)		\
175a9643ea8Slogwang {									\
176a9643ea8Slogwang     if (SPLAY_EMPTY(head)) {						\
177a9643ea8Slogwang 	    SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;	\
178a9643ea8Slogwang     } else {								\
179a9643ea8Slogwang 	    int __comp;							\
180a9643ea8Slogwang 	    name##_SPLAY(head, elm);					\
181a9643ea8Slogwang 	    __comp = (cmp)(elm, (head)->sph_root);			\
182a9643ea8Slogwang 	    if(__comp < 0) {						\
183a9643ea8Slogwang 		    SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
184a9643ea8Slogwang 		    SPLAY_RIGHT(elm, field) = (head)->sph_root;		\
185a9643ea8Slogwang 		    SPLAY_LEFT((head)->sph_root, field) = NULL;		\
186a9643ea8Slogwang 	    } else if (__comp > 0) {					\
187a9643ea8Slogwang 		    SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
188a9643ea8Slogwang 		    SPLAY_LEFT(elm, field) = (head)->sph_root;		\
189a9643ea8Slogwang 		    SPLAY_RIGHT((head)->sph_root, field) = NULL;	\
190a9643ea8Slogwang 	    } else							\
191a9643ea8Slogwang 		    return ((head)->sph_root);				\
192a9643ea8Slogwang     }									\
193a9643ea8Slogwang     (head)->sph_root = (elm);						\
194a9643ea8Slogwang     return (NULL);							\
195a9643ea8Slogwang }									\
196a9643ea8Slogwang 									\
197a9643ea8Slogwang struct type *								\
198a9643ea8Slogwang name##_SPLAY_REMOVE(struct name *head, struct type *elm)		\
199a9643ea8Slogwang {									\
200a9643ea8Slogwang 	struct type *__tmp;						\
201a9643ea8Slogwang 	if (SPLAY_EMPTY(head))						\
202a9643ea8Slogwang 		return (NULL);						\
203a9643ea8Slogwang 	name##_SPLAY(head, elm);					\
204a9643ea8Slogwang 	if ((cmp)(elm, (head)->sph_root) == 0) {			\
205a9643ea8Slogwang 		if (SPLAY_LEFT((head)->sph_root, field) == NULL) {	\
206a9643ea8Slogwang 			(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
207a9643ea8Slogwang 		} else {						\
208a9643ea8Slogwang 			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
209a9643ea8Slogwang 			(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
210a9643ea8Slogwang 			name##_SPLAY(head, elm);			\
211a9643ea8Slogwang 			SPLAY_RIGHT((head)->sph_root, field) = __tmp;	\
212a9643ea8Slogwang 		}							\
213a9643ea8Slogwang 		return (elm);						\
214a9643ea8Slogwang 	}								\
215a9643ea8Slogwang 	return (NULL);							\
216a9643ea8Slogwang }									\
217a9643ea8Slogwang 									\
218a9643ea8Slogwang void									\
219a9643ea8Slogwang name##_SPLAY(struct name *head, struct type *elm)			\
220a9643ea8Slogwang {									\
221a9643ea8Slogwang 	struct type __node, *__left, *__right, *__tmp;			\
222a9643ea8Slogwang 	int __comp;							\
223a9643ea8Slogwang \
224a9643ea8Slogwang 	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
225a9643ea8Slogwang 	__left = __right = &__node;					\
226a9643ea8Slogwang \
227a9643ea8Slogwang 	while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) {		\
228a9643ea8Slogwang 		if (__comp < 0) {					\
229a9643ea8Slogwang 			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
230a9643ea8Slogwang 			if (__tmp == NULL)				\
231a9643ea8Slogwang 				break;					\
232a9643ea8Slogwang 			if ((cmp)(elm, __tmp) < 0){			\
233a9643ea8Slogwang 				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
234a9643ea8Slogwang 				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
235a9643ea8Slogwang 					break;				\
236a9643ea8Slogwang 			}						\
237a9643ea8Slogwang 			SPLAY_LINKLEFT(head, __right, field);		\
238a9643ea8Slogwang 		} else if (__comp > 0) {				\
239a9643ea8Slogwang 			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
240a9643ea8Slogwang 			if (__tmp == NULL)				\
241a9643ea8Slogwang 				break;					\
242a9643ea8Slogwang 			if ((cmp)(elm, __tmp) > 0){			\
243a9643ea8Slogwang 				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
244a9643ea8Slogwang 				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
245a9643ea8Slogwang 					break;				\
246a9643ea8Slogwang 			}						\
247a9643ea8Slogwang 			SPLAY_LINKRIGHT(head, __left, field);		\
248a9643ea8Slogwang 		}							\
249a9643ea8Slogwang 	}								\
250a9643ea8Slogwang 	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
251a9643ea8Slogwang }									\
252a9643ea8Slogwang 									\
253a9643ea8Slogwang /* Splay with either the minimum or the maximum element			\
254a9643ea8Slogwang  * Used to find minimum or maximum element in tree.			\
255a9643ea8Slogwang  */									\
256a9643ea8Slogwang void name##_SPLAY_MINMAX(struct name *head, int __comp) \
257a9643ea8Slogwang {									\
258a9643ea8Slogwang 	struct type __node, *__left, *__right, *__tmp;			\
259a9643ea8Slogwang \
260a9643ea8Slogwang 	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
261a9643ea8Slogwang 	__left = __right = &__node;					\
262a9643ea8Slogwang \
263a9643ea8Slogwang 	while (1) {							\
264a9643ea8Slogwang 		if (__comp < 0) {					\
265a9643ea8Slogwang 			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
266a9643ea8Slogwang 			if (__tmp == NULL)				\
267a9643ea8Slogwang 				break;					\
268a9643ea8Slogwang 			if (__comp < 0){				\
269a9643ea8Slogwang 				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
270a9643ea8Slogwang 				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
271a9643ea8Slogwang 					break;				\
272a9643ea8Slogwang 			}						\
273a9643ea8Slogwang 			SPLAY_LINKLEFT(head, __right, field);		\
274a9643ea8Slogwang 		} else if (__comp > 0) {				\
275a9643ea8Slogwang 			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
276a9643ea8Slogwang 			if (__tmp == NULL)				\
277a9643ea8Slogwang 				break;					\
278a9643ea8Slogwang 			if (__comp > 0) {				\
279a9643ea8Slogwang 				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
280a9643ea8Slogwang 				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
281a9643ea8Slogwang 					break;				\
282a9643ea8Slogwang 			}						\
283a9643ea8Slogwang 			SPLAY_LINKRIGHT(head, __left, field);		\
284a9643ea8Slogwang 		}							\
285a9643ea8Slogwang 	}								\
286a9643ea8Slogwang 	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
287a9643ea8Slogwang }
288a9643ea8Slogwang 
289a9643ea8Slogwang #define SPLAY_NEGINF	-1
290a9643ea8Slogwang #define SPLAY_INF	1
291a9643ea8Slogwang 
292a9643ea8Slogwang #define SPLAY_INSERT(name, x, y)	name##_SPLAY_INSERT(x, y)
293a9643ea8Slogwang #define SPLAY_REMOVE(name, x, y)	name##_SPLAY_REMOVE(x, y)
294a9643ea8Slogwang #define SPLAY_FIND(name, x, y)		name##_SPLAY_FIND(x, y)
295a9643ea8Slogwang #define SPLAY_NEXT(name, x, y)		name##_SPLAY_NEXT(x, y)
296a9643ea8Slogwang #define SPLAY_MIN(name, x)		(SPLAY_EMPTY(x) ? NULL	\
297a9643ea8Slogwang 					: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
298a9643ea8Slogwang #define SPLAY_MAX(name, x)		(SPLAY_EMPTY(x) ? NULL	\
299a9643ea8Slogwang 					: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
300a9643ea8Slogwang 
301a9643ea8Slogwang #define SPLAY_FOREACH(x, name, head)					\
302a9643ea8Slogwang 	for ((x) = SPLAY_MIN(name, head);				\
303a9643ea8Slogwang 	     (x) != NULL;						\
304a9643ea8Slogwang 	     (x) = SPLAY_NEXT(name, head, x))
305a9643ea8Slogwang 
306*22ce4affSfengbojiang /* Macros that define a rank-balanced tree */
307a9643ea8Slogwang #define RB_HEAD(name, type)						\
308a9643ea8Slogwang struct name {								\
309a9643ea8Slogwang 	struct type *rbh_root; /* root of the tree */			\
310a9643ea8Slogwang }
311a9643ea8Slogwang 
312a9643ea8Slogwang #define RB_INITIALIZER(root)						\
313a9643ea8Slogwang 	{ NULL }
314a9643ea8Slogwang 
315a9643ea8Slogwang #define RB_INIT(root) do {						\
316a9643ea8Slogwang 	(root)->rbh_root = NULL;					\
317a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
318a9643ea8Slogwang 
319a9643ea8Slogwang #define RB_ENTRY(type)							\
320a9643ea8Slogwang struct {								\
321a9643ea8Slogwang 	struct type *rbe_left;		/* left element */		\
322a9643ea8Slogwang 	struct type *rbe_right;		/* right element */		\
323a9643ea8Slogwang 	struct type *rbe_parent;	/* parent element */		\
324a9643ea8Slogwang }
325a9643ea8Slogwang 
326a9643ea8Slogwang #define RB_LEFT(elm, field)		(elm)->field.rbe_left
327a9643ea8Slogwang #define RB_RIGHT(elm, field)		(elm)->field.rbe_right
328*22ce4affSfengbojiang 
329*22ce4affSfengbojiang /*
330*22ce4affSfengbojiang  * With the expectation that any object of struct type has an
331*22ce4affSfengbojiang  * address that is a multiple of 4, and that therefore the
332*22ce4affSfengbojiang  * 2 least significant bits of a pointer to struct type are
333*22ce4affSfengbojiang  * always zero, this implementation sets those bits to indicate
334*22ce4affSfengbojiang  * that the left or right child of the tree node is "red".
335*22ce4affSfengbojiang  */
336*22ce4affSfengbojiang #define RB_UP(elm, field)		(elm)->field.rbe_parent
337*22ce4affSfengbojiang #define RB_BITS(elm, field)		(*(__uintptr_t *)&RB_UP(elm, field))
338*22ce4affSfengbojiang #define RB_RED_L			((__uintptr_t)1)
339*22ce4affSfengbojiang #define RB_RED_R			((__uintptr_t)2)
340*22ce4affSfengbojiang #define RB_RED_MASK			((__uintptr_t)3)
341*22ce4affSfengbojiang #define RB_FLIP_LEFT(elm, field)	(RB_BITS(elm, field) ^= RB_RED_L)
342*22ce4affSfengbojiang #define RB_FLIP_RIGHT(elm, field)	(RB_BITS(elm, field) ^= RB_RED_R)
343*22ce4affSfengbojiang #define RB_RED_LEFT(elm, field)		((RB_BITS(elm, field) & RB_RED_L) != 0)
344*22ce4affSfengbojiang #define RB_RED_RIGHT(elm, field)	((RB_BITS(elm, field) & RB_RED_R) != 0)
345*22ce4affSfengbojiang #define RB_PARENT(elm, field)		((__typeof(RB_UP(elm, field)))	\
346*22ce4affSfengbojiang 					 (RB_BITS(elm, field) & ~RB_RED_MASK))
347a9643ea8Slogwang #define RB_ROOT(head)			(head)->rbh_root
348a9643ea8Slogwang #define RB_EMPTY(head)			(RB_ROOT(head) == NULL)
349a9643ea8Slogwang 
350*22ce4affSfengbojiang #define RB_SET_PARENT(dst, src, field) do {				\
351*22ce4affSfengbojiang 	RB_BITS(dst, field) &= RB_RED_MASK;				\
352*22ce4affSfengbojiang 	RB_BITS(dst, field) |= (__uintptr_t)src;			\
353*22ce4affSfengbojiang } while (/*CONSTCOND*/ 0)
354*22ce4affSfengbojiang 
355a9643ea8Slogwang #define RB_SET(elm, parent, field) do {					\
356*22ce4affSfengbojiang 	RB_UP(elm, field) = parent;					\
357a9643ea8Slogwang 	RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;		\
358a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
359a9643ea8Slogwang 
360*22ce4affSfengbojiang #define RB_COLOR(elm, field)	(RB_PARENT(elm, field) == NULL ? 0 :	\
361*22ce4affSfengbojiang 				RB_LEFT(RB_PARENT(elm, field), field) == elm ? \
362*22ce4affSfengbojiang 				RB_RED_LEFT(RB_PARENT(elm, field), field) : \
363*22ce4affSfengbojiang 				RB_RED_RIGHT(RB_PARENT(elm, field), field))
364a9643ea8Slogwang 
365*22ce4affSfengbojiang /*
366*22ce4affSfengbojiang  * Something to be invoked in a loop at the root of every modified subtree,
367*22ce4affSfengbojiang  * from the bottom up to the root, to update augmented node data.
368*22ce4affSfengbojiang  */
369a9643ea8Slogwang #ifndef RB_AUGMENT
370*22ce4affSfengbojiang #define RB_AUGMENT(x)	break
371a9643ea8Slogwang #endif
372a9643ea8Slogwang 
373*22ce4affSfengbojiang #define RB_SWAP_CHILD(head, out, in, field) do {			\
374*22ce4affSfengbojiang 	if (RB_PARENT(out, field) == NULL)				\
375*22ce4affSfengbojiang 		RB_ROOT(head) = (in);					\
376*22ce4affSfengbojiang 	else if ((out) == RB_LEFT(RB_PARENT(out, field), field))	\
377*22ce4affSfengbojiang 		RB_LEFT(RB_PARENT(out, field), field) = (in);		\
378*22ce4affSfengbojiang 	else								\
379*22ce4affSfengbojiang 		RB_RIGHT(RB_PARENT(out, field), field) = (in);		\
380*22ce4affSfengbojiang } while (/*CONSTCOND*/ 0)
381*22ce4affSfengbojiang 
382a9643ea8Slogwang #define RB_ROTATE_LEFT(head, elm, tmp, field) do {			\
383a9643ea8Slogwang 	(tmp) = RB_RIGHT(elm, field);					\
384a9643ea8Slogwang 	if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) {	\
385*22ce4affSfengbojiang 		RB_SET_PARENT(RB_RIGHT(elm, field), elm, field);	\
386a9643ea8Slogwang 	}								\
387*22ce4affSfengbojiang 	RB_SET_PARENT(tmp, RB_PARENT(elm, field), field);		\
388*22ce4affSfengbojiang 	RB_SWAP_CHILD(head, elm, tmp, field);				\
389a9643ea8Slogwang 	RB_LEFT(tmp, field) = (elm);					\
390*22ce4affSfengbojiang 	RB_SET_PARENT(elm, tmp, field);					\
391*22ce4affSfengbojiang 	RB_AUGMENT(elm);						\
392a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
393a9643ea8Slogwang 
394a9643ea8Slogwang #define RB_ROTATE_RIGHT(head, elm, tmp, field) do {			\
395a9643ea8Slogwang 	(tmp) = RB_LEFT(elm, field);					\
396a9643ea8Slogwang 	if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {	\
397*22ce4affSfengbojiang 		RB_SET_PARENT(RB_LEFT(elm, field), elm, field);		\
398a9643ea8Slogwang 	}								\
399*22ce4affSfengbojiang 	RB_SET_PARENT(tmp, RB_PARENT(elm, field), field);		\
400*22ce4affSfengbojiang 	RB_SWAP_CHILD(head, elm, tmp, field);				\
401a9643ea8Slogwang 	RB_RIGHT(tmp, field) = (elm);					\
402*22ce4affSfengbojiang 	RB_SET_PARENT(elm, tmp, field);					\
403*22ce4affSfengbojiang 	RB_AUGMENT(elm);						\
404a9643ea8Slogwang } while (/*CONSTCOND*/ 0)
405a9643ea8Slogwang 
406a9643ea8Slogwang /* Generates prototypes and inline functions */
407a9643ea8Slogwang #define	RB_PROTOTYPE(name, type, field, cmp)				\
408a9643ea8Slogwang 	RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
409a9643ea8Slogwang #define	RB_PROTOTYPE_STATIC(name, type, field, cmp)			\
410a9643ea8Slogwang 	RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
411a9643ea8Slogwang #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)		\
412a9643ea8Slogwang 	RB_PROTOTYPE_INSERT_COLOR(name, type, attr);			\
413a9643ea8Slogwang 	RB_PROTOTYPE_REMOVE_COLOR(name, type, attr);			\
414a9643ea8Slogwang 	RB_PROTOTYPE_INSERT(name, type, attr);				\
415a9643ea8Slogwang 	RB_PROTOTYPE_REMOVE(name, type, attr);				\
416a9643ea8Slogwang 	RB_PROTOTYPE_FIND(name, type, attr);				\
417a9643ea8Slogwang 	RB_PROTOTYPE_NFIND(name, type, attr);				\
418a9643ea8Slogwang 	RB_PROTOTYPE_NEXT(name, type, attr);				\
419a9643ea8Slogwang 	RB_PROTOTYPE_PREV(name, type, attr);				\
420*22ce4affSfengbojiang 	RB_PROTOTYPE_MINMAX(name, type, attr);				\
421*22ce4affSfengbojiang 	RB_PROTOTYPE_REINSERT(name, type, attr);
422a9643ea8Slogwang #define RB_PROTOTYPE_INSERT_COLOR(name, type, attr)			\
423a9643ea8Slogwang 	attr void name##_RB_INSERT_COLOR(struct name *, struct type *)
424a9643ea8Slogwang #define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr)			\
425*22ce4affSfengbojiang 	attr void name##_RB_REMOVE_COLOR(struct name *,			\
426*22ce4affSfengbojiang 	    struct type *, struct type *)
427a9643ea8Slogwang #define RB_PROTOTYPE_REMOVE(name, type, attr)				\
428a9643ea8Slogwang 	attr struct type *name##_RB_REMOVE(struct name *, struct type *)
429a9643ea8Slogwang #define RB_PROTOTYPE_INSERT(name, type, attr)				\
430a9643ea8Slogwang 	attr struct type *name##_RB_INSERT(struct name *, struct type *)
431a9643ea8Slogwang #define RB_PROTOTYPE_FIND(name, type, attr)				\
432a9643ea8Slogwang 	attr struct type *name##_RB_FIND(struct name *, struct type *)
433a9643ea8Slogwang #define RB_PROTOTYPE_NFIND(name, type, attr)				\
434a9643ea8Slogwang 	attr struct type *name##_RB_NFIND(struct name *, struct type *)
435a9643ea8Slogwang #define RB_PROTOTYPE_NEXT(name, type, attr)				\
436a9643ea8Slogwang 	attr struct type *name##_RB_NEXT(struct type *)
437a9643ea8Slogwang #define RB_PROTOTYPE_PREV(name, type, attr)				\
438a9643ea8Slogwang 	attr struct type *name##_RB_PREV(struct type *)
439a9643ea8Slogwang #define RB_PROTOTYPE_MINMAX(name, type, attr)				\
440a9643ea8Slogwang 	attr struct type *name##_RB_MINMAX(struct name *, int)
441*22ce4affSfengbojiang #define RB_PROTOTYPE_REINSERT(name, type, attr)			\
442*22ce4affSfengbojiang 	attr struct type *name##_RB_REINSERT(struct name *, struct type *)
443a9643ea8Slogwang 
444a9643ea8Slogwang /* Main rb operation.
445a9643ea8Slogwang  * Moves node close to the key of elm to top
446a9643ea8Slogwang  */
447a9643ea8Slogwang #define	RB_GENERATE(name, type, field, cmp)				\
448a9643ea8Slogwang 	RB_GENERATE_INTERNAL(name, type, field, cmp,)
449a9643ea8Slogwang #define	RB_GENERATE_STATIC(name, type, field, cmp)			\
450a9643ea8Slogwang 	RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
451a9643ea8Slogwang #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)		\
452a9643ea8Slogwang 	RB_GENERATE_INSERT_COLOR(name, type, field, attr)		\
453a9643ea8Slogwang 	RB_GENERATE_REMOVE_COLOR(name, type, field, attr)		\
454a9643ea8Slogwang 	RB_GENERATE_INSERT(name, type, field, cmp, attr)		\
455a9643ea8Slogwang 	RB_GENERATE_REMOVE(name, type, field, attr)			\
456a9643ea8Slogwang 	RB_GENERATE_FIND(name, type, field, cmp, attr)			\
457a9643ea8Slogwang 	RB_GENERATE_NFIND(name, type, field, cmp, attr)			\
458a9643ea8Slogwang 	RB_GENERATE_NEXT(name, type, field, attr)			\
459a9643ea8Slogwang 	RB_GENERATE_PREV(name, type, field, attr)			\
460*22ce4affSfengbojiang 	RB_GENERATE_MINMAX(name, type, field, attr)			\
461*22ce4affSfengbojiang 	RB_GENERATE_REINSERT(name, type, field, cmp, attr)
462a9643ea8Slogwang 
463a9643ea8Slogwang #define RB_GENERATE_INSERT_COLOR(name, type, field, attr)		\
464a9643ea8Slogwang attr void								\
465a9643ea8Slogwang name##_RB_INSERT_COLOR(struct name *head, struct type *elm)		\
466a9643ea8Slogwang {									\
467*22ce4affSfengbojiang 	struct type *child, *parent;					\
468*22ce4affSfengbojiang 	while ((parent = RB_PARENT(elm, field)) != NULL) {		\
469a9643ea8Slogwang 		if (RB_LEFT(parent, field) == elm) {			\
470*22ce4affSfengbojiang 			if (RB_RED_LEFT(parent, field)) {		\
471*22ce4affSfengbojiang 				RB_FLIP_LEFT(parent, field);		\
472*22ce4affSfengbojiang 				return;					\
473a9643ea8Slogwang 			}						\
474*22ce4affSfengbojiang 			RB_FLIP_RIGHT(parent, field);			\
475*22ce4affSfengbojiang 			if (RB_RED_RIGHT(parent, field)) {		\
476*22ce4affSfengbojiang 				elm = parent;				\
477*22ce4affSfengbojiang 				continue;				\
478a9643ea8Slogwang 			}						\
479*22ce4affSfengbojiang 			if (!RB_RED_RIGHT(elm, field)) {		\
480*22ce4affSfengbojiang 				RB_FLIP_LEFT(elm, field);		\
481*22ce4affSfengbojiang 				RB_ROTATE_LEFT(head, elm, child, field);\
482*22ce4affSfengbojiang 				if (RB_RED_LEFT(child, field))		\
483*22ce4affSfengbojiang 					RB_FLIP_RIGHT(elm, field);	\
484*22ce4affSfengbojiang 				else if (RB_RED_RIGHT(child, field))	\
485*22ce4affSfengbojiang 					RB_FLIP_LEFT(parent, field);	\
486*22ce4affSfengbojiang 				elm = child;				\
487a9643ea8Slogwang 			}						\
488*22ce4affSfengbojiang 			RB_ROTATE_RIGHT(head, parent, elm, field);	\
489*22ce4affSfengbojiang 		} else {						\
490*22ce4affSfengbojiang 			if (RB_RED_RIGHT(parent, field)) {		\
491*22ce4affSfengbojiang 				RB_FLIP_RIGHT(parent, field);		\
492*22ce4affSfengbojiang 				return;					\
493*22ce4affSfengbojiang 			}						\
494*22ce4affSfengbojiang 			RB_FLIP_LEFT(parent, field);			\
495*22ce4affSfengbojiang 			if (RB_RED_LEFT(parent, field)) {		\
496*22ce4affSfengbojiang 				elm = parent;				\
497*22ce4affSfengbojiang 				continue;				\
498*22ce4affSfengbojiang 			}						\
499*22ce4affSfengbojiang 			if (!RB_RED_LEFT(elm, field)) {			\
500*22ce4affSfengbojiang 				RB_FLIP_RIGHT(elm, field);		\
501*22ce4affSfengbojiang 				RB_ROTATE_RIGHT(head, elm, child, field);\
502*22ce4affSfengbojiang 				if (RB_RED_RIGHT(child, field))		\
503*22ce4affSfengbojiang 					RB_FLIP_LEFT(elm, field);	\
504*22ce4affSfengbojiang 				else if (RB_RED_LEFT(child, field))	\
505*22ce4affSfengbojiang 					RB_FLIP_RIGHT(parent, field);	\
506*22ce4affSfengbojiang 				elm = child;				\
507*22ce4affSfengbojiang 			}						\
508*22ce4affSfengbojiang 			RB_ROTATE_LEFT(head, parent, elm, field);	\
509*22ce4affSfengbojiang 		}							\
510*22ce4affSfengbojiang 		RB_BITS(elm, field) &= ~RB_RED_MASK;			\
511*22ce4affSfengbojiang 		break;							\
512*22ce4affSfengbojiang 	}								\
513a9643ea8Slogwang }
514a9643ea8Slogwang 
515a9643ea8Slogwang #define RB_GENERATE_REMOVE_COLOR(name, type, field, attr)		\
516a9643ea8Slogwang attr void								\
517*22ce4affSfengbojiang name##_RB_REMOVE_COLOR(struct name *head,				\
518*22ce4affSfengbojiang     struct type *parent, struct type *elm)				\
519a9643ea8Slogwang {									\
520*22ce4affSfengbojiang 	struct type *sib;						\
521*22ce4affSfengbojiang 	if (RB_LEFT(parent, field) == elm &&				\
522*22ce4affSfengbojiang 	    RB_RIGHT(parent, field) == elm) {				\
523*22ce4affSfengbojiang 		RB_BITS(parent, field) &= ~RB_RED_MASK;			\
524*22ce4affSfengbojiang 		elm = parent;						\
525*22ce4affSfengbojiang 		parent = RB_PARENT(elm, field);				\
526*22ce4affSfengbojiang 		if (parent == NULL)					\
527*22ce4affSfengbojiang 			return;						\
528*22ce4affSfengbojiang 	}								\
529*22ce4affSfengbojiang 	do  {								\
530a9643ea8Slogwang 		if (RB_LEFT(parent, field) == elm) {			\
531*22ce4affSfengbojiang 			if (!RB_RED_LEFT(parent, field)) {		\
532*22ce4affSfengbojiang 				RB_FLIP_LEFT(parent, field);		\
533*22ce4affSfengbojiang 				return;					\
534a9643ea8Slogwang 			}						\
535*22ce4affSfengbojiang 			if (RB_RED_RIGHT(parent, field)) {		\
536*22ce4affSfengbojiang 				RB_FLIP_RIGHT(parent, field);		\
537a9643ea8Slogwang 				elm = parent;				\
538*22ce4affSfengbojiang 				continue;				\
539a9643ea8Slogwang 			}						\
540*22ce4affSfengbojiang 			sib = RB_RIGHT(parent, field);			\
541*22ce4affSfengbojiang 			if ((~RB_BITS(sib, field) & RB_RED_MASK) == 0) {\
542*22ce4affSfengbojiang 				RB_BITS(sib, field) &= ~RB_RED_MASK;	\
543a9643ea8Slogwang 				elm = parent;				\
544*22ce4affSfengbojiang 				continue;				\
545*22ce4affSfengbojiang 			}						\
546*22ce4affSfengbojiang 			RB_FLIP_RIGHT(sib, field);			\
547*22ce4affSfengbojiang 			if (RB_RED_LEFT(sib, field))			\
548*22ce4affSfengbojiang 				RB_FLIP_LEFT(parent, field);		\
549*22ce4affSfengbojiang 			else if (!RB_RED_RIGHT(sib, field)) {		\
550*22ce4affSfengbojiang 				RB_FLIP_LEFT(parent, field);		\
551*22ce4affSfengbojiang 				RB_ROTATE_RIGHT(head, sib, elm, field);	\
552*22ce4affSfengbojiang 				if (RB_RED_RIGHT(elm, field))		\
553*22ce4affSfengbojiang 					RB_FLIP_LEFT(sib, field);	\
554*22ce4affSfengbojiang 				if (RB_RED_LEFT(elm, field))		\
555*22ce4affSfengbojiang 					RB_FLIP_RIGHT(parent, field);	\
556*22ce4affSfengbojiang 				RB_BITS(elm, field) |= RB_RED_MASK;	\
557*22ce4affSfengbojiang 				sib = elm;				\
558*22ce4affSfengbojiang 			}						\
559*22ce4affSfengbojiang 			RB_ROTATE_LEFT(head, parent, sib, field);	\
560a9643ea8Slogwang 		} else {						\
561*22ce4affSfengbojiang 			if (!RB_RED_RIGHT(parent, field)) {		\
562*22ce4affSfengbojiang 				RB_FLIP_RIGHT(parent, field);		\
563*22ce4affSfengbojiang 				return;					\
564a9643ea8Slogwang 			}						\
565*22ce4affSfengbojiang 			if (RB_RED_LEFT(parent, field)) {		\
566*22ce4affSfengbojiang 				RB_FLIP_LEFT(parent, field);		\
567*22ce4affSfengbojiang 				elm = parent;				\
568*22ce4affSfengbojiang 				continue;				\
569*22ce4affSfengbojiang 			}						\
570*22ce4affSfengbojiang 			sib = RB_LEFT(parent, field);			\
571*22ce4affSfengbojiang 			if ((~RB_BITS(sib, field) & RB_RED_MASK) == 0) {\
572*22ce4affSfengbojiang 				RB_BITS(sib, field) &= ~RB_RED_MASK;	\
573*22ce4affSfengbojiang 				elm = parent;				\
574*22ce4affSfengbojiang 				continue;				\
575*22ce4affSfengbojiang 			}						\
576*22ce4affSfengbojiang 			RB_FLIP_LEFT(sib, field);			\
577*22ce4affSfengbojiang 			if (RB_RED_RIGHT(sib, field))			\
578*22ce4affSfengbojiang 				RB_FLIP_RIGHT(parent, field);		\
579*22ce4affSfengbojiang 			else if (!RB_RED_LEFT(sib, field)) {		\
580*22ce4affSfengbojiang 				RB_FLIP_RIGHT(parent, field);		\
581*22ce4affSfengbojiang 				RB_ROTATE_LEFT(head, sib, elm, field);	\
582*22ce4affSfengbojiang 				if (RB_RED_LEFT(elm, field))		\
583*22ce4affSfengbojiang 					RB_FLIP_RIGHT(sib, field);	\
584*22ce4affSfengbojiang 				if (RB_RED_RIGHT(elm, field))		\
585*22ce4affSfengbojiang 					RB_FLIP_LEFT(parent, field);	\
586*22ce4affSfengbojiang 				RB_BITS(elm, field) |= RB_RED_MASK;	\
587*22ce4affSfengbojiang 				sib = elm;				\
588*22ce4affSfengbojiang 			}						\
589*22ce4affSfengbojiang 			RB_ROTATE_RIGHT(head, parent, sib, field);	\
590*22ce4affSfengbojiang 		}							\
591a9643ea8Slogwang 		break;							\
592*22ce4affSfengbojiang 	} while ((parent = RB_PARENT(elm, field)) != NULL);		\
593a9643ea8Slogwang }
594a9643ea8Slogwang 
595a9643ea8Slogwang #define RB_GENERATE_REMOVE(name, type, field, attr)			\
596a9643ea8Slogwang attr struct type *							\
597a9643ea8Slogwang name##_RB_REMOVE(struct name *head, struct type *elm)			\
598a9643ea8Slogwang {									\
599*22ce4affSfengbojiang 	struct type *child, *old, *parent, *right;			\
600*22ce4affSfengbojiang 									\
601*22ce4affSfengbojiang 	old = elm;							\
602*22ce4affSfengbojiang 	parent = RB_PARENT(elm, field);					\
603*22ce4affSfengbojiang 	right = RB_RIGHT(elm, field);					\
604a9643ea8Slogwang 	if (RB_LEFT(elm, field) == NULL)				\
605*22ce4affSfengbojiang 		elm = child = right;					\
606*22ce4affSfengbojiang 	else if (right == NULL)						\
607*22ce4affSfengbojiang 		elm = child = RB_LEFT(elm, field);			\
608a9643ea8Slogwang 	else {								\
609*22ce4affSfengbojiang 		if ((child = RB_LEFT(right, field)) == NULL) {		\
610*22ce4affSfengbojiang 			child = RB_RIGHT(right, field);			\
611*22ce4affSfengbojiang 			RB_RIGHT(old, field) = child;			\
612*22ce4affSfengbojiang 			parent = elm = right;				\
613*22ce4affSfengbojiang 		} else {						\
614*22ce4affSfengbojiang 			do						\
615*22ce4affSfengbojiang 				elm = child;				\
616*22ce4affSfengbojiang 			while ((child = RB_LEFT(elm, field)) != NULL);	\
617a9643ea8Slogwang 			child = RB_RIGHT(elm, field);			\
618a9643ea8Slogwang 			parent = RB_PARENT(elm, field);			\
619a9643ea8Slogwang 			RB_LEFT(parent, field) = child;			\
620*22ce4affSfengbojiang 			RB_SET_PARENT(RB_RIGHT(old, field), elm, field);\
621a9643ea8Slogwang 		}							\
622*22ce4affSfengbojiang 		RB_SET_PARENT(RB_LEFT(old, field), elm, field);		\
623*22ce4affSfengbojiang 		elm->field = old->field;				\
624a9643ea8Slogwang 	}								\
625*22ce4affSfengbojiang 	RB_SWAP_CHILD(head, old, elm, field);				\
626*22ce4affSfengbojiang 	if (child != NULL)						\
627*22ce4affSfengbojiang 		RB_SET_PARENT(child, parent, field);			\
628*22ce4affSfengbojiang 	if (parent != NULL)						\
629a9643ea8Slogwang 		name##_RB_REMOVE_COLOR(head, parent, child);		\
630*22ce4affSfengbojiang 	while (parent != NULL) {					\
631*22ce4affSfengbojiang 		RB_AUGMENT(parent);					\
632*22ce4affSfengbojiang 		parent = RB_PARENT(parent, field);			\
633a9643ea8Slogwang 	}								\
634*22ce4affSfengbojiang 	return (old);							\
635*22ce4affSfengbojiang }
636a9643ea8Slogwang 
637a9643ea8Slogwang #define RB_GENERATE_INSERT(name, type, field, cmp, attr)		\
638a9643ea8Slogwang /* Inserts a node into the RB tree */					\
639a9643ea8Slogwang attr struct type *							\
640a9643ea8Slogwang name##_RB_INSERT(struct name *head, struct type *elm)			\
641a9643ea8Slogwang {									\
642a9643ea8Slogwang 	struct type *tmp;						\
643a9643ea8Slogwang 	struct type *parent = NULL;					\
644a9643ea8Slogwang 	int comp = 0;							\
645a9643ea8Slogwang 	tmp = RB_ROOT(head);						\
646a9643ea8Slogwang 	while (tmp) {							\
647a9643ea8Slogwang 		parent = tmp;						\
648a9643ea8Slogwang 		comp = (cmp)(elm, parent);				\
649a9643ea8Slogwang 		if (comp < 0)						\
650a9643ea8Slogwang 			tmp = RB_LEFT(tmp, field);			\
651a9643ea8Slogwang 		else if (comp > 0)					\
652a9643ea8Slogwang 			tmp = RB_RIGHT(tmp, field);			\
653a9643ea8Slogwang 		else							\
654a9643ea8Slogwang 			return (tmp);					\
655a9643ea8Slogwang 	}								\
656a9643ea8Slogwang 	RB_SET(elm, parent, field);					\
657*22ce4affSfengbojiang 	if (parent == NULL)						\
658*22ce4affSfengbojiang 		RB_ROOT(head) = elm;					\
659*22ce4affSfengbojiang 	else if (comp < 0)						\
660a9643ea8Slogwang 		RB_LEFT(parent, field) = elm;				\
661a9643ea8Slogwang 	else								\
662a9643ea8Slogwang 		RB_RIGHT(parent, field) = elm;				\
663a9643ea8Slogwang 	name##_RB_INSERT_COLOR(head, elm);				\
664*22ce4affSfengbojiang 	while (elm != NULL) {						\
665*22ce4affSfengbojiang 		RB_AUGMENT(elm);					\
666*22ce4affSfengbojiang 		elm = RB_PARENT(elm, field);				\
667*22ce4affSfengbojiang 	}								\
668a9643ea8Slogwang 	return (NULL);							\
669a9643ea8Slogwang }
670a9643ea8Slogwang 
671a9643ea8Slogwang #define RB_GENERATE_FIND(name, type, field, cmp, attr)			\
672a9643ea8Slogwang /* Finds the node with the same key as elm */				\
673a9643ea8Slogwang attr struct type *							\
674a9643ea8Slogwang name##_RB_FIND(struct name *head, struct type *elm)			\
675a9643ea8Slogwang {									\
676a9643ea8Slogwang 	struct type *tmp = RB_ROOT(head);				\
677a9643ea8Slogwang 	int comp;							\
678a9643ea8Slogwang 	while (tmp) {							\
679a9643ea8Slogwang 		comp = cmp(elm, tmp);					\
680a9643ea8Slogwang 		if (comp < 0)						\
681a9643ea8Slogwang 			tmp = RB_LEFT(tmp, field);			\
682a9643ea8Slogwang 		else if (comp > 0)					\
683a9643ea8Slogwang 			tmp = RB_RIGHT(tmp, field);			\
684a9643ea8Slogwang 		else							\
685a9643ea8Slogwang 			return (tmp);					\
686a9643ea8Slogwang 	}								\
687a9643ea8Slogwang 	return (NULL);							\
688a9643ea8Slogwang }
689a9643ea8Slogwang 
690a9643ea8Slogwang #define RB_GENERATE_NFIND(name, type, field, cmp, attr)			\
691a9643ea8Slogwang /* Finds the first node greater than or equal to the search key */	\
692a9643ea8Slogwang attr struct type *							\
693a9643ea8Slogwang name##_RB_NFIND(struct name *head, struct type *elm)			\
694a9643ea8Slogwang {									\
695a9643ea8Slogwang 	struct type *tmp = RB_ROOT(head);				\
696a9643ea8Slogwang 	struct type *res = NULL;					\
697a9643ea8Slogwang 	int comp;							\
698a9643ea8Slogwang 	while (tmp) {							\
699a9643ea8Slogwang 		comp = cmp(elm, tmp);					\
700a9643ea8Slogwang 		if (comp < 0) {						\
701a9643ea8Slogwang 			res = tmp;					\
702a9643ea8Slogwang 			tmp = RB_LEFT(tmp, field);			\
703a9643ea8Slogwang 		}							\
704a9643ea8Slogwang 		else if (comp > 0)					\
705a9643ea8Slogwang 			tmp = RB_RIGHT(tmp, field);			\
706a9643ea8Slogwang 		else							\
707a9643ea8Slogwang 			return (tmp);					\
708a9643ea8Slogwang 	}								\
709a9643ea8Slogwang 	return (res);							\
710a9643ea8Slogwang }
711a9643ea8Slogwang 
712a9643ea8Slogwang #define RB_GENERATE_NEXT(name, type, field, attr)			\
713a9643ea8Slogwang /* ARGSUSED */								\
714a9643ea8Slogwang attr struct type *							\
715a9643ea8Slogwang name##_RB_NEXT(struct type *elm)					\
716a9643ea8Slogwang {									\
717a9643ea8Slogwang 	if (RB_RIGHT(elm, field)) {					\
718a9643ea8Slogwang 		elm = RB_RIGHT(elm, field);				\
719a9643ea8Slogwang 		while (RB_LEFT(elm, field))				\
720a9643ea8Slogwang 			elm = RB_LEFT(elm, field);			\
721a9643ea8Slogwang 	} else {							\
722a9643ea8Slogwang 		if (RB_PARENT(elm, field) &&				\
723a9643ea8Slogwang 		    (elm == RB_LEFT(RB_PARENT(elm, field), field)))	\
724a9643ea8Slogwang 			elm = RB_PARENT(elm, field);			\
725a9643ea8Slogwang 		else {							\
726a9643ea8Slogwang 			while (RB_PARENT(elm, field) &&			\
727a9643ea8Slogwang 			    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
728a9643ea8Slogwang 				elm = RB_PARENT(elm, field);		\
729a9643ea8Slogwang 			elm = RB_PARENT(elm, field);			\
730a9643ea8Slogwang 		}							\
731a9643ea8Slogwang 	}								\
732a9643ea8Slogwang 	return (elm);							\
733a9643ea8Slogwang }
734a9643ea8Slogwang 
735a9643ea8Slogwang #define RB_GENERATE_PREV(name, type, field, attr)			\
736a9643ea8Slogwang /* ARGSUSED */								\
737a9643ea8Slogwang attr struct type *							\
738a9643ea8Slogwang name##_RB_PREV(struct type *elm)					\
739a9643ea8Slogwang {									\
740a9643ea8Slogwang 	if (RB_LEFT(elm, field)) {					\
741a9643ea8Slogwang 		elm = RB_LEFT(elm, field);				\
742a9643ea8Slogwang 		while (RB_RIGHT(elm, field))				\
743a9643ea8Slogwang 			elm = RB_RIGHT(elm, field);			\
744a9643ea8Slogwang 	} else {							\
745a9643ea8Slogwang 		if (RB_PARENT(elm, field) &&				\
746a9643ea8Slogwang 		    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))	\
747a9643ea8Slogwang 			elm = RB_PARENT(elm, field);			\
748a9643ea8Slogwang 		else {							\
749a9643ea8Slogwang 			while (RB_PARENT(elm, field) &&			\
750a9643ea8Slogwang 			    (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
751a9643ea8Slogwang 				elm = RB_PARENT(elm, field);		\
752a9643ea8Slogwang 			elm = RB_PARENT(elm, field);			\
753a9643ea8Slogwang 		}							\
754a9643ea8Slogwang 	}								\
755a9643ea8Slogwang 	return (elm);							\
756a9643ea8Slogwang }
757a9643ea8Slogwang 
758a9643ea8Slogwang #define RB_GENERATE_MINMAX(name, type, field, attr)			\
759a9643ea8Slogwang attr struct type *							\
760a9643ea8Slogwang name##_RB_MINMAX(struct name *head, int val)				\
761a9643ea8Slogwang {									\
762a9643ea8Slogwang 	struct type *tmp = RB_ROOT(head);				\
763a9643ea8Slogwang 	struct type *parent = NULL;					\
764a9643ea8Slogwang 	while (tmp) {							\
765a9643ea8Slogwang 		parent = tmp;						\
766a9643ea8Slogwang 		if (val < 0)						\
767a9643ea8Slogwang 			tmp = RB_LEFT(tmp, field);			\
768a9643ea8Slogwang 		else							\
769a9643ea8Slogwang 			tmp = RB_RIGHT(tmp, field);			\
770a9643ea8Slogwang 	}								\
771a9643ea8Slogwang 	return (parent);						\
772a9643ea8Slogwang }
773a9643ea8Slogwang 
774*22ce4affSfengbojiang #define	RB_GENERATE_REINSERT(name, type, field, cmp, attr)		\
775*22ce4affSfengbojiang attr struct type *							\
776*22ce4affSfengbojiang name##_RB_REINSERT(struct name *head, struct type *elm)			\
777*22ce4affSfengbojiang {									\
778*22ce4affSfengbojiang 	struct type *cmpelm;						\
779*22ce4affSfengbojiang 	if (((cmpelm = RB_PREV(name, head, elm)) != NULL &&		\
780*22ce4affSfengbojiang 	    cmp(cmpelm, elm) >= 0) ||					\
781*22ce4affSfengbojiang 	    ((cmpelm = RB_NEXT(name, head, elm)) != NULL &&		\
782*22ce4affSfengbojiang 	    cmp(elm, cmpelm) >= 0)) {					\
783*22ce4affSfengbojiang 		/* XXXLAS: Remove/insert is heavy handed. */		\
784*22ce4affSfengbojiang 		RB_REMOVE(name, head, elm);				\
785*22ce4affSfengbojiang 		return (RB_INSERT(name, head, elm));			\
786*22ce4affSfengbojiang 	}								\
787*22ce4affSfengbojiang 	return (NULL);							\
788*22ce4affSfengbojiang }									\
789*22ce4affSfengbojiang 
790a9643ea8Slogwang #define RB_NEGINF	-1
791a9643ea8Slogwang #define RB_INF	1
792a9643ea8Slogwang 
793a9643ea8Slogwang #define RB_INSERT(name, x, y)	name##_RB_INSERT(x, y)
794a9643ea8Slogwang #define RB_REMOVE(name, x, y)	name##_RB_REMOVE(x, y)
795a9643ea8Slogwang #define RB_FIND(name, x, y)	name##_RB_FIND(x, y)
796a9643ea8Slogwang #define RB_NFIND(name, x, y)	name##_RB_NFIND(x, y)
797a9643ea8Slogwang #define RB_NEXT(name, x, y)	name##_RB_NEXT(y)
798a9643ea8Slogwang #define RB_PREV(name, x, y)	name##_RB_PREV(y)
799a9643ea8Slogwang #define RB_MIN(name, x)		name##_RB_MINMAX(x, RB_NEGINF)
800a9643ea8Slogwang #define RB_MAX(name, x)		name##_RB_MINMAX(x, RB_INF)
801*22ce4affSfengbojiang #define RB_REINSERT(name, x, y)	name##_RB_REINSERT(x, y)
802a9643ea8Slogwang 
803a9643ea8Slogwang #define RB_FOREACH(x, name, head)					\
804a9643ea8Slogwang 	for ((x) = RB_MIN(name, head);					\
805a9643ea8Slogwang 	     (x) != NULL;						\
806a9643ea8Slogwang 	     (x) = name##_RB_NEXT(x))
807a9643ea8Slogwang 
808a9643ea8Slogwang #define RB_FOREACH_FROM(x, name, y)					\
809a9643ea8Slogwang 	for ((x) = (y);							\
810a9643ea8Slogwang 	    ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);	\
811a9643ea8Slogwang 	     (x) = (y))
812a9643ea8Slogwang 
813a9643ea8Slogwang #define RB_FOREACH_SAFE(x, name, head, y)				\
814a9643ea8Slogwang 	for ((x) = RB_MIN(name, head);					\
815a9643ea8Slogwang 	    ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);	\
816a9643ea8Slogwang 	     (x) = (y))
817a9643ea8Slogwang 
818a9643ea8Slogwang #define RB_FOREACH_REVERSE(x, name, head)				\
819a9643ea8Slogwang 	for ((x) = RB_MAX(name, head);					\
820a9643ea8Slogwang 	     (x) != NULL;						\
821a9643ea8Slogwang 	     (x) = name##_RB_PREV(x))
822a9643ea8Slogwang 
823a9643ea8Slogwang #define RB_FOREACH_REVERSE_FROM(x, name, y)				\
824a9643ea8Slogwang 	for ((x) = (y);							\
825a9643ea8Slogwang 	    ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);	\
826a9643ea8Slogwang 	     (x) = (y))
827a9643ea8Slogwang 
828a9643ea8Slogwang #define RB_FOREACH_REVERSE_SAFE(x, name, head, y)			\
829a9643ea8Slogwang 	for ((x) = RB_MAX(name, head);					\
830a9643ea8Slogwang 	    ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);	\
831a9643ea8Slogwang 	     (x) = (y))
832a9643ea8Slogwang 
833a9643ea8Slogwang #endif	/* _SYS_TREE_H_ */
834