Home | History | Annotate | Line # | Download | only in WIN32-Code
tree.h revision 1.1.1.1.6.2
      1  1.1.1.1.6.2       snj /*	$NetBSD: tree.h,v 1.1.1.1.6.2 2015/04/23 18:53:06 snj Exp $	*/
      2          1.1  christos 
      3          1.1  christos /*	$OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $	*/
      4          1.1  christos /*
      5          1.1  christos  * Copyright 2002 Niels Provos <provos (at) citi.umich.edu>
      6          1.1  christos  * All rights reserved.
      7          1.1  christos  *
      8          1.1  christos  * Redistribution and use in source and binary forms, with or without
      9          1.1  christos  * modification, are permitted provided that the following conditions
     10          1.1  christos  * are met:
     11          1.1  christos  * 1. Redistributions of source code must retain the above copyright
     12          1.1  christos  *    notice, this list of conditions and the following disclaimer.
     13          1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     14          1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     15          1.1  christos  *    documentation and/or other materials provided with the distribution.
     16          1.1  christos  *
     17          1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18          1.1  christos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19          1.1  christos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20          1.1  christos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21          1.1  christos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22          1.1  christos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23          1.1  christos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24          1.1  christos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25          1.1  christos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26          1.1  christos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27          1.1  christos  */
     28          1.1  christos 
     29          1.1  christos #ifndef	_SYS_TREE_H_
     30          1.1  christos #define	_SYS_TREE_H_
     31          1.1  christos 
     32          1.1  christos /*
     33          1.1  christos  * This file defines data structures for different types of trees:
     34          1.1  christos  * splay trees and red-black trees.
     35          1.1  christos  *
     36          1.1  christos  * A splay tree is a self-organizing data structure.  Every operation
     37          1.1  christos  * on the tree causes a splay to happen.  The splay moves the requested
     38          1.1  christos  * node to the root of the tree and partly rebalances it.
     39          1.1  christos  *
     40          1.1  christos  * This has the benefit that request locality causes faster lookups as
     41          1.1  christos  * the requested nodes move to the top of the tree.  On the other hand,
     42          1.1  christos  * every lookup causes memory writes.
     43          1.1  christos  *
     44          1.1  christos  * The Balance Theorem bounds the total access time for m operations
     45          1.1  christos  * and n inserts on an initially empty tree as O((m + n)lg n).  The
     46          1.1  christos  * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
     47          1.1  christos  *
     48          1.1  christos  * A red-black tree is a binary search tree with the node color as an
     49          1.1  christos  * extra attribute.  It fulfills a set of conditions:
     50          1.1  christos  *	- every search path from the root to a leaf consists of the
     51          1.1  christos  *	  same number of black nodes,
     52          1.1  christos  *	- each red node (except for the root) has a black parent,
     53          1.1  christos  *	- each leaf node is black.
     54          1.1  christos  *
     55          1.1  christos  * Every operation on a red-black tree is bounded as O(lg n).
     56          1.1  christos  * The maximum height of a red-black tree is 2lg (n+1).
     57          1.1  christos  */
     58          1.1  christos 
     59          1.1  christos #define SPLAY_HEAD(name, type)						\
     60          1.1  christos struct name {								\
     61          1.1  christos 	struct type *sph_root; /* root of the tree */			\
     62          1.1  christos }
     63          1.1  christos 
     64          1.1  christos #define SPLAY_INITIALIZER(root)						\
     65          1.1  christos 	{ NULL }
     66          1.1  christos 
     67          1.1  christos #define SPLAY_INIT(root) do {						\
     68          1.1  christos 	(root)->sph_root = NULL;					\
     69          1.1  christos } while (0)
     70          1.1  christos 
     71          1.1  christos #define SPLAY_ENTRY(type)						\
     72          1.1  christos struct {								\
     73          1.1  christos 	struct type *spe_left; /* left element */			\
     74          1.1  christos 	struct type *spe_right; /* right element */			\
     75          1.1  christos }
     76          1.1  christos 
     77          1.1  christos #define SPLAY_LEFT(elm, field)		(elm)->field.spe_left
     78          1.1  christos #define SPLAY_RIGHT(elm, field)		(elm)->field.spe_right
     79          1.1  christos #define SPLAY_ROOT(head)		(head)->sph_root
     80          1.1  christos #define SPLAY_EMPTY(head)		(SPLAY_ROOT(head) == NULL)
     81          1.1  christos 
     82          1.1  christos /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
     83          1.1  christos #define SPLAY_ROTATE_RIGHT(head, tmp, field) do {			\
     84          1.1  christos 	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);	\
     85          1.1  christos 	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
     86          1.1  christos 	(head)->sph_root = tmp;						\
     87          1.1  christos } while (0)
     88          1.1  christos 
     89          1.1  christos #define SPLAY_ROTATE_LEFT(head, tmp, field) do {			\
     90          1.1  christos 	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);	\
     91          1.1  christos 	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
     92          1.1  christos 	(head)->sph_root = tmp;						\
     93          1.1  christos } while (0)
     94          1.1  christos 
     95          1.1  christos #define SPLAY_LINKLEFT(head, tmp, field) do {				\
     96          1.1  christos 	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
     97          1.1  christos 	tmp = (head)->sph_root;						\
     98          1.1  christos 	(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);		\
     99          1.1  christos } while (0)
    100          1.1  christos 
    101          1.1  christos #define SPLAY_LINKRIGHT(head, tmp, field) do {				\
    102          1.1  christos 	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
    103          1.1  christos 	tmp = (head)->sph_root;						\
    104          1.1  christos 	(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);	\
    105          1.1  christos } while (0)
    106          1.1  christos 
    107          1.1  christos #define SPLAY_ASSEMBLE(head, node, left, right, field) do {		\
    108          1.1  christos 	SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);	\
    109          1.1  christos 	SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
    110          1.1  christos 	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);	\
    111          1.1  christos 	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);	\
    112          1.1  christos } while (0)
    113          1.1  christos 
    114          1.1  christos /* Generates prototypes and inline functions */
    115          1.1  christos 
    116          1.1  christos #define SPLAY_PROTOTYPE(name, type, field, cmp)				\
    117          1.1  christos void name##_SPLAY(struct name *, struct type *);			\
    118          1.1  christos void name##_SPLAY_MINMAX(struct name *, int);				\
    119          1.1  christos struct type *name##_SPLAY_INSERT(struct name *, struct type *);		\
    120          1.1  christos struct type *name##_SPLAY_REMOVE(struct name *, struct type *);		\
    121          1.1  christos 									\
    122          1.1  christos /* Finds the node with the same key as elm */				\
    123          1.1  christos static __inline struct type *						\
    124          1.1  christos name##_SPLAY_FIND(struct name *head, struct type *elm)			\
    125          1.1  christos {									\
    126          1.1  christos 	if (SPLAY_EMPTY(head))						\
    127          1.1  christos 		return(NULL);						\
    128          1.1  christos 	name##_SPLAY(head, elm);					\
    129          1.1  christos 	if ((cmp)(elm, (head)->sph_root) == 0)				\
    130          1.1  christos 		return (head->sph_root);				\
    131          1.1  christos 	return (NULL);							\
    132          1.1  christos }									\
    133          1.1  christos 									\
    134          1.1  christos static __inline struct type *						\
    135          1.1  christos name##_SPLAY_NEXT(struct name *head, struct type *elm)			\
    136          1.1  christos {									\
    137          1.1  christos 	name##_SPLAY(head, elm);					\
    138          1.1  christos 	if (SPLAY_RIGHT(elm, field) != NULL) {				\
    139          1.1  christos 		elm = SPLAY_RIGHT(elm, field);				\
    140          1.1  christos 		while (SPLAY_LEFT(elm, field) != NULL) {		\
    141          1.1  christos 			elm = SPLAY_LEFT(elm, field);			\
    142          1.1  christos 		}							\
    143          1.1  christos 	} else								\
    144          1.1  christos 		elm = NULL;						\
    145          1.1  christos 	return (elm);							\
    146          1.1  christos }									\
    147          1.1  christos 									\
    148          1.1  christos static __inline struct type *						\
    149          1.1  christos name##_SPLAY_MIN_MAX(struct name *head, int val)			\
    150          1.1  christos {									\
    151          1.1  christos 	name##_SPLAY_MINMAX(head, val);					\
    152          1.1  christos 	return (SPLAY_ROOT(head));					\
    153          1.1  christos }
    154          1.1  christos 
    155          1.1  christos /* Main splay operation.
    156          1.1  christos  * Moves node close to the key of elm to top
    157          1.1  christos  */
    158          1.1  christos #define SPLAY_GENERATE(name, type, field, cmp)				\
    159          1.1  christos struct type *								\
    160          1.1  christos name##_SPLAY_INSERT(struct name *head, struct type *elm)		\
    161          1.1  christos {									\
    162          1.1  christos     if (SPLAY_EMPTY(head)) {						\
    163          1.1  christos 	    SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;	\
    164          1.1  christos     } else {								\
    165          1.1  christos 	    int __comp;							\
    166          1.1  christos 	    name##_SPLAY(head, elm);					\
    167          1.1  christos 	    __comp = (cmp)(elm, (head)->sph_root);			\
    168          1.1  christos 	    if(__comp < 0) {						\
    169          1.1  christos 		    SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
    170          1.1  christos 		    SPLAY_RIGHT(elm, field) = (head)->sph_root;		\
    171          1.1  christos 		    SPLAY_LEFT((head)->sph_root, field) = NULL;		\
    172          1.1  christos 	    } else if (__comp > 0) {					\
    173          1.1  christos 		    SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
    174          1.1  christos 		    SPLAY_LEFT(elm, field) = (head)->sph_root;		\
    175          1.1  christos 		    SPLAY_RIGHT((head)->sph_root, field) = NULL;	\
    176          1.1  christos 	    } else							\
    177          1.1  christos 		    return ((head)->sph_root);				\
    178          1.1  christos     }									\
    179          1.1  christos     (head)->sph_root = (elm);						\
    180          1.1  christos     return (NULL);							\
    181          1.1  christos }									\
    182          1.1  christos 									\
    183          1.1  christos struct type *								\
    184          1.1  christos name##_SPLAY_REMOVE(struct name *head, struct type *elm)		\
    185          1.1  christos {									\
    186          1.1  christos 	struct type *__tmp;						\
    187          1.1  christos 	if (SPLAY_EMPTY(head))						\
    188          1.1  christos 		return (NULL);						\
    189          1.1  christos 	name##_SPLAY(head, elm);					\
    190          1.1  christos 	if ((cmp)(elm, (head)->sph_root) == 0) {			\
    191          1.1  christos 		if (SPLAY_LEFT((head)->sph_root, field) == NULL) {	\
    192          1.1  christos 			(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
    193          1.1  christos 		} else {						\
    194          1.1  christos 			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
    195          1.1  christos 			(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
    196          1.1  christos 			name##_SPLAY(head, elm);			\
    197          1.1  christos 			SPLAY_RIGHT((head)->sph_root, field) = __tmp;	\
    198          1.1  christos 		}							\
    199          1.1  christos 		return (elm);						\
    200          1.1  christos 	}								\
    201          1.1  christos 	return (NULL);							\
    202          1.1  christos }									\
    203          1.1  christos 									\
    204          1.1  christos void									\
    205          1.1  christos name##_SPLAY(struct name *head, struct type *elm)			\
    206          1.1  christos {									\
    207          1.1  christos 	struct type __node, *__left, *__right, *__tmp;			\
    208          1.1  christos 	int __comp;							\
    209          1.1  christos \
    210          1.1  christos 	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
    211          1.1  christos 	__left = __right = &__node;					\
    212          1.1  christos \
    213          1.1  christos 	while ((__comp = (cmp)(elm, (head)->sph_root))) {		\
    214          1.1  christos 		if (__comp < 0) {					\
    215          1.1  christos 			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
    216          1.1  christos 			if (__tmp == NULL)				\
    217          1.1  christos 				break;					\
    218          1.1  christos 			if ((cmp)(elm, __tmp) < 0){			\
    219          1.1  christos 				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
    220          1.1  christos 				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
    221          1.1  christos 					break;				\
    222          1.1  christos 			}						\
    223          1.1  christos 			SPLAY_LINKLEFT(head, __right, field);		\
    224          1.1  christos 		} else if (__comp > 0) {				\
    225          1.1  christos 			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
    226          1.1  christos 			if (__tmp == NULL)				\
    227          1.1  christos 				break;					\
    228          1.1  christos 			if ((cmp)(elm, __tmp) > 0){			\
    229          1.1  christos 				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
    230          1.1  christos 				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
    231          1.1  christos 					break;				\
    232          1.1  christos 			}						\
    233          1.1  christos 			SPLAY_LINKRIGHT(head, __left, field);		\
    234          1.1  christos 		}							\
    235          1.1  christos 	}								\
    236          1.1  christos 	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
    237          1.1  christos }									\
    238          1.1  christos 									\
    239          1.1  christos /* Splay with either the minimum or the maximum element			\
    240          1.1  christos  * Used to find minimum or maximum element in tree.			\
    241          1.1  christos  */									\
    242          1.1  christos void name##_SPLAY_MINMAX(struct name *head, int __comp) \
    243          1.1  christos {									\
    244          1.1  christos 	struct type __node, *__left, *__right, *__tmp;			\
    245          1.1  christos \
    246          1.1  christos 	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
    247          1.1  christos 	__left = __right = &__node;					\
    248          1.1  christos \
    249          1.1  christos 	while (1) {							\
    250          1.1  christos 		if (__comp < 0) {					\
    251          1.1  christos 			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
    252          1.1  christos 			if (__tmp == NULL)				\
    253          1.1  christos 				break;					\
    254          1.1  christos 			if (__comp < 0){				\
    255          1.1  christos 				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
    256          1.1  christos 				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
    257          1.1  christos 					break;				\
    258          1.1  christos 			}						\
    259          1.1  christos 			SPLAY_LINKLEFT(head, __right, field);		\
    260          1.1  christos 		} else if (__comp > 0) {				\
    261          1.1  christos 			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
    262          1.1  christos 			if (__tmp == NULL)				\
    263          1.1  christos 				break;					\
    264          1.1  christos 			if (__comp > 0) {				\
    265          1.1  christos 				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
    266          1.1  christos 				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
    267          1.1  christos 					break;				\
    268          1.1  christos 			}						\
    269          1.1  christos 			SPLAY_LINKRIGHT(head, __left, field);		\
    270          1.1  christos 		}							\
    271          1.1  christos 	}								\
    272          1.1  christos 	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
    273          1.1  christos }
    274          1.1  christos 
    275          1.1  christos #define SPLAY_NEGINF	-1
    276          1.1  christos #define SPLAY_INF	1
    277          1.1  christos 
    278          1.1  christos #define SPLAY_INSERT(name, x, y)	name##_SPLAY_INSERT(x, y)
    279          1.1  christos #define SPLAY_REMOVE(name, x, y)	name##_SPLAY_REMOVE(x, y)
    280          1.1  christos #define SPLAY_FIND(name, x, y)		name##_SPLAY_FIND(x, y)
    281          1.1  christos #define SPLAY_NEXT(name, x, y)		name##_SPLAY_NEXT(x, y)
    282          1.1  christos #define SPLAY_MIN(name, x)		(SPLAY_EMPTY(x) ? NULL	\
    283          1.1  christos 					: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
    284          1.1  christos #define SPLAY_MAX(name, x)		(SPLAY_EMPTY(x) ? NULL	\
    285          1.1  christos 					: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
    286          1.1  christos 
    287          1.1  christos #define SPLAY_FOREACH(x, name, head)					\
    288          1.1  christos 	for ((x) = SPLAY_MIN(name, head);				\
    289          1.1  christos 	     (x) != NULL;						\
    290          1.1  christos 	     (x) = SPLAY_NEXT(name, head, x))
    291          1.1  christos 
    292          1.1  christos /* Macros that define a red-back tree */
    293          1.1  christos #define RB_HEAD(name, type)						\
    294          1.1  christos struct name {								\
    295          1.1  christos 	struct type *rbh_root; /* root of the tree */			\
    296          1.1  christos }
    297          1.1  christos 
    298          1.1  christos #define RB_INITIALIZER(root)						\
    299          1.1  christos 	{ NULL }
    300          1.1  christos 
    301          1.1  christos #define RB_INIT(root) do {						\
    302          1.1  christos 	(root)->rbh_root = NULL;					\
    303          1.1  christos } while (0)
    304          1.1  christos 
    305          1.1  christos #define RB_BLACK	0
    306          1.1  christos #define RB_RED		1
    307          1.1  christos #define RB_ENTRY(type)							\
    308          1.1  christos struct {								\
    309          1.1  christos 	struct type *rbe_left;		/* left element */		\
    310          1.1  christos 	struct type *rbe_right;		/* right element */		\
    311          1.1  christos 	struct type *rbe_parent;	/* parent element */		\
    312          1.1  christos 	int rbe_color;			/* node color */		\
    313          1.1  christos }
    314          1.1  christos 
    315          1.1  christos #define RB_LEFT(elm, field)		(elm)->field.rbe_left
    316          1.1  christos #define RB_RIGHT(elm, field)		(elm)->field.rbe_right
    317          1.1  christos #define RB_PARENT(elm, field)		(elm)->field.rbe_parent
    318          1.1  christos #define RB_COLOR(elm, field)		(elm)->field.rbe_color
    319          1.1  christos #define RB_ROOT(head)			(head)->rbh_root
    320          1.1  christos #define RB_EMPTY(head)			(RB_ROOT(head) == NULL)
    321          1.1  christos 
    322          1.1  christos #define RB_SET(elm, parent, field) do {					\
    323          1.1  christos 	RB_PARENT(elm, field) = parent;					\
    324          1.1  christos 	RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;		\
    325          1.1  christos 	RB_COLOR(elm, field) = RB_RED;					\
    326          1.1  christos } while (0)
    327          1.1  christos 
    328          1.1  christos #define RB_SET_BLACKRED(black, red, field) do {				\
    329          1.1  christos 	RB_COLOR(black, field) = RB_BLACK;				\
    330          1.1  christos 	RB_COLOR(red, field) = RB_RED;					\
    331          1.1  christos } while (0)
    332          1.1  christos 
    333          1.1  christos #ifndef RB_AUGMENT
    334          1.1  christos #define RB_AUGMENT(x)
    335          1.1  christos #endif
    336          1.1  christos 
    337          1.1  christos #define RB_ROTATE_LEFT(head, elm, tmp, field) do {			\
    338          1.1  christos 	(tmp) = RB_RIGHT(elm, field);					\
    339          1.1  christos 	if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {		\
    340          1.1  christos 		RB_PARENT(RB_LEFT(tmp, field), field) = (elm);		\
    341          1.1  christos 	}								\
    342          1.1  christos 	RB_AUGMENT(elm);						\
    343          1.1  christos 	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {		\
    344          1.1  christos 		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
    345          1.1  christos 			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
    346          1.1  christos 		else							\
    347          1.1  christos 			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
    348          1.1  christos 	} else								\
    349          1.1  christos 		(head)->rbh_root = (tmp);				\
    350          1.1  christos 	RB_LEFT(tmp, field) = (elm);					\
    351          1.1  christos 	RB_PARENT(elm, field) = (tmp);					\
    352          1.1  christos 	RB_AUGMENT(tmp);						\
    353          1.1  christos 	if ((RB_PARENT(tmp, field)))					\
    354          1.1  christos 		RB_AUGMENT(RB_PARENT(tmp, field));			\
    355          1.1  christos } while (0)
    356          1.1  christos 
    357          1.1  christos #define RB_ROTATE_RIGHT(head, elm, tmp, field) do {			\
    358          1.1  christos 	(tmp) = RB_LEFT(elm, field);					\
    359          1.1  christos 	if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {		\
    360          1.1  christos 		RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);		\
    361          1.1  christos 	}								\
    362          1.1  christos 	RB_AUGMENT(elm);						\
    363          1.1  christos 	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {		\
    364          1.1  christos 		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
    365          1.1  christos 			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
    366          1.1  christos 		else							\
    367          1.1  christos 			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
    368          1.1  christos 	} else								\
    369          1.1  christos 		(head)->rbh_root = (tmp);				\
    370          1.1  christos 	RB_RIGHT(tmp, field) = (elm);					\
    371          1.1  christos 	RB_PARENT(elm, field) = (tmp);					\
    372          1.1  christos 	RB_AUGMENT(tmp);						\
    373          1.1  christos 	if ((RB_PARENT(tmp, field)))					\
    374          1.1  christos 		RB_AUGMENT(RB_PARENT(tmp, field));			\
    375          1.1  christos } while (0)
    376          1.1  christos 
    377          1.1  christos /* Generates prototypes and inline functions */
    378          1.1  christos #define RB_PROTOTYPE(name, type, field, cmp)				\
    379          1.1  christos void name##_RB_INSERT_COLOR(struct name *, struct type *);	\
    380          1.1  christos void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
    381          1.1  christos struct type *name##_RB_REMOVE(struct name *, struct type *);		\
    382          1.1  christos struct type *name##_RB_INSERT(struct name *, struct type *);		\
    383          1.1  christos struct type *name##_RB_FIND(struct name *, struct type *);		\
    384          1.1  christos struct type *name##_RB_NEXT(struct type *);				\
    385          1.1  christos struct type *name##_RB_MINMAX(struct name *, int);			\
    386          1.1  christos 									\
    387          1.1  christos 
    388          1.1  christos /* Main rb operation.
    389          1.1  christos  * Moves node close to the key of elm to top
    390          1.1  christos  */
    391          1.1  christos #define RB_GENERATE(name, type, field, cmp)				\
    392          1.1  christos void									\
    393          1.1  christos name##_RB_INSERT_COLOR(struct name *head, struct type *elm)		\
    394          1.1  christos {									\
    395          1.1  christos 	struct type *parent, *gparent, *tmp;				\
    396          1.1  christos 	while ((parent = RB_PARENT(elm, field)) &&			\
    397          1.1  christos 	    RB_COLOR(parent, field) == RB_RED) {			\
    398          1.1  christos 		gparent = RB_PARENT(parent, field);			\
    399          1.1  christos 		if (parent == RB_LEFT(gparent, field)) {		\
    400          1.1  christos 			tmp = RB_RIGHT(gparent, field);			\
    401          1.1  christos 			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
    402          1.1  christos 				RB_COLOR(tmp, field) = RB_BLACK;	\
    403          1.1  christos 				RB_SET_BLACKRED(parent, gparent, field);\
    404          1.1  christos 				elm = gparent;				\
    405          1.1  christos 				continue;				\
    406          1.1  christos 			}						\
    407          1.1  christos 			if (RB_RIGHT(parent, field) == elm) {		\
    408          1.1  christos 				RB_ROTATE_LEFT(head, parent, tmp, field);\
    409          1.1  christos 				tmp = parent;				\
    410          1.1  christos 				parent = elm;				\
    411          1.1  christos 				elm = tmp;				\
    412          1.1  christos 			}						\
    413          1.1  christos 			RB_SET_BLACKRED(parent, gparent, field);	\
    414          1.1  christos 			RB_ROTATE_RIGHT(head, gparent, tmp, field);	\
    415          1.1  christos 		} else {						\
    416          1.1  christos 			tmp = RB_LEFT(gparent, field);			\
    417          1.1  christos 			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
    418          1.1  christos 				RB_COLOR(tmp, field) = RB_BLACK;	\
    419          1.1  christos 				RB_SET_BLACKRED(parent, gparent, field);\
    420          1.1  christos 				elm = gparent;				\
    421          1.1  christos 				continue;				\
    422          1.1  christos 			}						\
    423          1.1  christos 			if (RB_LEFT(parent, field) == elm) {		\
    424          1.1  christos 				RB_ROTATE_RIGHT(head, parent, tmp, field);\
    425          1.1  christos 				tmp = parent;				\
    426          1.1  christos 				parent = elm;				\
    427          1.1  christos 				elm = tmp;				\
    428          1.1  christos 			}						\
    429          1.1  christos 			RB_SET_BLACKRED(parent, gparent, field);	\
    430          1.1  christos 			RB_ROTATE_LEFT(head, gparent, tmp, field);	\
    431          1.1  christos 		}							\
    432          1.1  christos 	}								\
    433          1.1  christos 	RB_COLOR(head->rbh_root, field) = RB_BLACK;			\
    434          1.1  christos }									\
    435          1.1  christos 									\
    436          1.1  christos void									\
    437          1.1  christos name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
    438          1.1  christos {									\
    439          1.1  christos 	struct type *tmp;						\
    440          1.1  christos 	while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&	\
    441          1.1  christos 	    elm != RB_ROOT(head)) {					\
    442          1.1  christos 		if (RB_LEFT(parent, field) == elm) {			\
    443          1.1  christos 			tmp = RB_RIGHT(parent, field);			\
    444          1.1  christos 			if (RB_COLOR(tmp, field) == RB_RED) {		\
    445          1.1  christos 				RB_SET_BLACKRED(tmp, parent, field);	\
    446          1.1  christos 				RB_ROTATE_LEFT(head, parent, tmp, field);\
    447          1.1  christos 				tmp = RB_RIGHT(parent, field);		\
    448          1.1  christos 			}						\
    449          1.1  christos 			if ((RB_LEFT(tmp, field) == NULL ||		\
    450          1.1  christos 			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
    451          1.1  christos 			    (RB_RIGHT(tmp, field) == NULL ||		\
    452          1.1  christos 			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
    453          1.1  christos 				RB_COLOR(tmp, field) = RB_RED;		\
    454          1.1  christos 				elm = parent;				\
    455          1.1  christos 				parent = RB_PARENT(elm, field);		\
    456          1.1  christos 			} else {					\
    457          1.1  christos 				if (RB_RIGHT(tmp, field) == NULL ||	\
    458          1.1  christos 				    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
    459          1.1  christos 					struct type *oleft;		\
    460          1.1  christos 					if ((oleft = RB_LEFT(tmp, field)))\
    461          1.1  christos 						RB_COLOR(oleft, field) = RB_BLACK;\
    462          1.1  christos 					RB_COLOR(tmp, field) = RB_RED;	\
    463          1.1  christos 					RB_ROTATE_RIGHT(head, tmp, oleft, field);\
    464          1.1  christos 					tmp = RB_RIGHT(parent, field);	\
    465          1.1  christos 				}					\
    466          1.1  christos 				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
    467          1.1  christos 				RB_COLOR(parent, field) = RB_BLACK;	\
    468          1.1  christos 				if (RB_RIGHT(tmp, field))		\
    469          1.1  christos 					RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
    470          1.1  christos 				RB_ROTATE_LEFT(head, parent, tmp, field);\
    471          1.1  christos 				elm = RB_ROOT(head);			\
    472          1.1  christos 				break;					\
    473          1.1  christos 			}						\
    474          1.1  christos 		} else {						\
    475          1.1  christos 			tmp = RB_LEFT(parent, field);			\
    476          1.1  christos 			if (RB_COLOR(tmp, field) == RB_RED) {		\
    477          1.1  christos 				RB_SET_BLACKRED(tmp, parent, field);	\
    478          1.1  christos 				RB_ROTATE_RIGHT(head, parent, tmp, field);\
    479          1.1  christos 				tmp = RB_LEFT(parent, field);		\
    480          1.1  christos 			}						\
    481          1.1  christos 			if ((RB_LEFT(tmp, field) == NULL ||		\
    482          1.1  christos 			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
    483          1.1  christos 			    (RB_RIGHT(tmp, field) == NULL ||		\
    484          1.1  christos 			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
    485          1.1  christos 				RB_COLOR(tmp, field) = RB_RED;		\
    486          1.1  christos 				elm = parent;				\
    487          1.1  christos 				parent = RB_PARENT(elm, field);		\
    488          1.1  christos 			} else {					\
    489          1.1  christos 				if (RB_LEFT(tmp, field) == NULL ||	\
    490          1.1  christos 				    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
    491          1.1  christos 					struct type *oright;		\
    492          1.1  christos 					if ((oright = RB_RIGHT(tmp, field)))\
    493          1.1  christos 						RB_COLOR(oright, field) = RB_BLACK;\
    494          1.1  christos 					RB_COLOR(tmp, field) = RB_RED;	\
    495          1.1  christos 					RB_ROTATE_LEFT(head, tmp, oright, field);\
    496          1.1  christos 					tmp = RB_LEFT(parent, field);	\
    497          1.1  christos 				}					\
    498          1.1  christos 				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
    499          1.1  christos 				RB_COLOR(parent, field) = RB_BLACK;	\
    500          1.1  christos 				if (RB_LEFT(tmp, field))		\
    501          1.1  christos 					RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
    502          1.1  christos 				RB_ROTATE_RIGHT(head, parent, tmp, field);\
    503          1.1  christos 				elm = RB_ROOT(head);			\
    504          1.1  christos 				break;					\
    505          1.1  christos 			}						\
    506          1.1  christos 		}							\
    507          1.1  christos 	}								\
    508          1.1  christos 	if (elm)							\
    509          1.1  christos 		RB_COLOR(elm, field) = RB_BLACK;			\
    510          1.1  christos }									\
    511          1.1  christos 									\
    512          1.1  christos struct type *								\
    513          1.1  christos name##_RB_REMOVE(struct name *head, struct type *elm)			\
    514          1.1  christos {									\
    515          1.1  christos 	struct type *child, *parent, *old = elm;			\
    516          1.1  christos 	int color;							\
    517          1.1  christos 	if (RB_LEFT(elm, field) == NULL)				\
    518          1.1  christos 		child = RB_RIGHT(elm, field);				\
    519          1.1  christos 	else if (RB_RIGHT(elm, field) == NULL)				\
    520          1.1  christos 		child = RB_LEFT(elm, field);				\
    521          1.1  christos 	else {								\
    522          1.1  christos 		struct type *left;					\
    523          1.1  christos 		elm = RB_RIGHT(elm, field);				\
    524          1.1  christos 		while ((left = RB_LEFT(elm, field)))			\
    525          1.1  christos 			elm = left;					\
    526          1.1  christos 		child = RB_RIGHT(elm, field);				\
    527          1.1  christos 		parent = RB_PARENT(elm, field);				\
    528          1.1  christos 		color = RB_COLOR(elm, field);				\
    529          1.1  christos 		if (child)						\
    530          1.1  christos 			RB_PARENT(child, field) = parent;		\
    531          1.1  christos 		if (parent) {						\
    532          1.1  christos 			if (RB_LEFT(parent, field) == elm)		\
    533          1.1  christos 				RB_LEFT(parent, field) = child;		\
    534          1.1  christos 			else						\
    535          1.1  christos 				RB_RIGHT(parent, field) = child;	\
    536          1.1  christos 			RB_AUGMENT(parent);				\
    537          1.1  christos 		} else							\
    538          1.1  christos 			RB_ROOT(head) = child;				\
    539          1.1  christos 		if (RB_PARENT(elm, field) == old)			\
    540          1.1  christos 			parent = elm;					\
    541          1.1  christos 		(elm)->field = (old)->field;				\
    542          1.1  christos 		if (RB_PARENT(old, field)) {				\
    543          1.1  christos 			if (RB_LEFT(RB_PARENT(old, field), field) == old)\
    544          1.1  christos 				RB_LEFT(RB_PARENT(old, field), field) = elm;\
    545          1.1  christos 			else						\
    546          1.1  christos 				RB_RIGHT(RB_PARENT(old, field), field) = elm;\
    547          1.1  christos 			RB_AUGMENT(RB_PARENT(old, field));		\
    548          1.1  christos 		} else							\
    549          1.1  christos 			RB_ROOT(head) = elm;				\
    550          1.1  christos 		RB_PARENT(RB_LEFT(old, field), field) = elm;		\
    551          1.1  christos 		if (RB_RIGHT(old, field))				\
    552          1.1  christos 			RB_PARENT(RB_RIGHT(old, field), field) = elm;	\
    553          1.1  christos 		if (parent) {						\
    554          1.1  christos 			left = parent;					\
    555          1.1  christos 			do {						\
    556          1.1  christos 				RB_AUGMENT(left);			\
    557          1.1  christos 			} while ((left = RB_PARENT(left, field)));	\
    558          1.1  christos 		}							\
    559          1.1  christos 		goto color;						\
    560          1.1  christos 	}								\
    561          1.1  christos 	parent = RB_PARENT(elm, field);					\
    562          1.1  christos 	color = RB_COLOR(elm, field);					\
    563          1.1  christos 	if (child)							\
    564          1.1  christos 		RB_PARENT(child, field) = parent;			\
    565          1.1  christos 	if (parent) {							\
    566          1.1  christos 		if (RB_LEFT(parent, field) == elm)			\
    567          1.1  christos 			RB_LEFT(parent, field) = child;			\
    568          1.1  christos 		else							\
    569          1.1  christos 			RB_RIGHT(parent, field) = child;		\
    570          1.1  christos 		RB_AUGMENT(parent);					\
    571          1.1  christos 	} else								\
    572          1.1  christos 		RB_ROOT(head) = child;					\
    573          1.1  christos color:									\
    574          1.1  christos 	if (color == RB_BLACK)						\
    575          1.1  christos 		name##_RB_REMOVE_COLOR(head, parent, child);		\
    576          1.1  christos 	return (old);							\
    577          1.1  christos }									\
    578          1.1  christos 									\
    579          1.1  christos /* Inserts a node into the RB tree */					\
    580          1.1  christos struct type *								\
    581          1.1  christos name##_RB_INSERT(struct name *head, struct type *elm)			\
    582          1.1  christos {									\
    583          1.1  christos 	struct type *tmp;						\
    584          1.1  christos 	struct type *parent = NULL;					\
    585          1.1  christos 	int comp = 0;							\
    586          1.1  christos 	tmp = RB_ROOT(head);						\
    587          1.1  christos 	while (tmp) {							\
    588          1.1  christos 		parent = tmp;						\
    589          1.1  christos 		comp = (cmp)(elm, parent);				\
    590          1.1  christos 		if (comp < 0)						\
    591          1.1  christos 			tmp = RB_LEFT(tmp, field);			\
    592          1.1  christos 		else if (comp > 0)					\
    593          1.1  christos 			tmp = RB_RIGHT(tmp, field);			\
    594          1.1  christos 		else							\
    595          1.1  christos 			return (tmp);					\
    596          1.1  christos 	}								\
    597          1.1  christos 	RB_SET(elm, parent, field);					\
    598          1.1  christos 	if (parent != NULL) {						\
    599          1.1  christos 		if (comp < 0)						\
    600          1.1  christos 			RB_LEFT(parent, field) = elm;			\
    601          1.1  christos 		else							\
    602          1.1  christos 			RB_RIGHT(parent, field) = elm;			\
    603          1.1  christos 		RB_AUGMENT(parent);					\
    604          1.1  christos 	} else								\
    605          1.1  christos 		RB_ROOT(head) = elm;					\
    606          1.1  christos 	name##_RB_INSERT_COLOR(head, elm);				\
    607          1.1  christos 	return (NULL);							\
    608          1.1  christos }									\
    609          1.1  christos 									\
    610          1.1  christos /* Finds the node with the same key as elm */				\
    611          1.1  christos struct type *								\
    612          1.1  christos name##_RB_FIND(struct name *head, struct type *elm)			\
    613          1.1  christos {									\
    614          1.1  christos 	struct type *tmp = RB_ROOT(head);				\
    615          1.1  christos 	int comp;							\
    616          1.1  christos 	while (tmp) {							\
    617          1.1  christos 		comp = cmp(elm, tmp);					\
    618          1.1  christos 		if (comp < 0)						\
    619          1.1  christos 			tmp = RB_LEFT(tmp, field);			\
    620          1.1  christos 		else if (comp > 0)					\
    621          1.1  christos 			tmp = RB_RIGHT(tmp, field);			\
    622          1.1  christos 		else							\
    623          1.1  christos 			return (tmp);					\
    624          1.1  christos 	}								\
    625          1.1  christos 	return (NULL);							\
    626          1.1  christos }									\
    627          1.1  christos 									\
    628          1.1  christos struct type *								\
    629          1.1  christos name##_RB_NEXT(struct type *elm)					\
    630          1.1  christos {									\
    631          1.1  christos 	if (RB_RIGHT(elm, field)) {					\
    632          1.1  christos 		elm = RB_RIGHT(elm, field);				\
    633          1.1  christos 		while (RB_LEFT(elm, field))				\
    634          1.1  christos 			elm = RB_LEFT(elm, field);			\
    635          1.1  christos 	} else {							\
    636          1.1  christos 		if (RB_PARENT(elm, field) &&				\
    637          1.1  christos 		    (elm == RB_LEFT(RB_PARENT(elm, field), field)))	\
    638          1.1  christos 			elm = RB_PARENT(elm, field);			\
    639          1.1  christos 		else {							\
    640          1.1  christos 			while (RB_PARENT(elm, field) &&			\
    641          1.1  christos 			    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
    642          1.1  christos 				elm = RB_PARENT(elm, field);		\
    643          1.1  christos 			elm = RB_PARENT(elm, field);			\
    644          1.1  christos 		}							\
    645          1.1  christos 	}								\
    646          1.1  christos 	return (elm);							\
    647          1.1  christos }									\
    648          1.1  christos 									\
    649          1.1  christos struct type *								\
    650          1.1  christos name##_RB_MINMAX(struct name *head, int val)				\
    651          1.1  christos {									\
    652          1.1  christos 	struct type *tmp = RB_ROOT(head);				\
    653          1.1  christos 	struct type *parent = NULL;					\
    654          1.1  christos 	while (tmp) {							\
    655          1.1  christos 		parent = tmp;						\
    656          1.1  christos 		if (val < 0)						\
    657          1.1  christos 			tmp = RB_LEFT(tmp, field);			\
    658          1.1  christos 		else							\
    659          1.1  christos 			tmp = RB_RIGHT(tmp, field);			\
    660          1.1  christos 	}								\
    661          1.1  christos 	return (parent);						\
    662          1.1  christos }
    663          1.1  christos 
    664          1.1  christos #define RB_NEGINF	-1
    665          1.1  christos #define RB_INF	1
    666          1.1  christos 
    667          1.1  christos #define RB_INSERT(name, x, y)	name##_RB_INSERT(x, y)
    668          1.1  christos #define RB_REMOVE(name, x, y)	name##_RB_REMOVE(x, y)
    669          1.1  christos #define RB_FIND(name, x, y)	name##_RB_FIND(x, y)
    670          1.1  christos #define RB_NEXT(name, x, y)	name##_RB_NEXT(y)
    671          1.1  christos #define RB_MIN(name, x)		name##_RB_MINMAX(x, RB_NEGINF)
    672          1.1  christos #define RB_MAX(name, x)		name##_RB_MINMAX(x, RB_INF)
    673          1.1  christos 
    674          1.1  christos #define RB_FOREACH(x, name, head)					\
    675          1.1  christos 	for ((x) = RB_MIN(name, head);					\
    676          1.1  christos 	     (x) != NULL;						\
    677          1.1  christos 	     (x) = name##_RB_NEXT(x))
    678          1.1  christos 
    679          1.1  christos #endif	/* _SYS_TREE_H_ */
    680