1 /*-
2  *******************************************************************************
3  *
4  * cpp macro implementation of left-leaning 2-3 red-black trees.  Parent
5  * pointers are not used, and color bits are stored in the least significant
6  * bit of right-child pointers (if RB_COMPACT is defined), thus making node
7  * linkage as compact as is possible for red-black trees.
8  *
9  * Usage:
10  *
11  *   #include <stdint.h>
12  *   #include <stdbool.h>
13  *   #define NDEBUG // (Optional, see assert(3).)
14  *   #include <assert.h>
15  *   #define RB_COMPACT // (Optional, embed color bits in right-child pointers.)
16  *   #include <rb.h>
17  *   ...
18  *
19  *******************************************************************************
20  */
21 
22 #ifndef RB_H_
23 #define	RB_H_
24 
25 #if 0
26 __FBSDID("$FreeBSD$");
27 #endif
28 
29 #ifdef RB_COMPACT
30 /* Node structure. */
31 #define	rb_node(a_type)							\
32 struct {								\
33     a_type *rbn_left;							\
34     a_type *rbn_right_red;						\
35 }
36 #else
37 #define	rb_node(a_type)							\
38 struct {								\
39     a_type *rbn_left;							\
40     a_type *rbn_right;							\
41     bool rbn_red;							\
42 }
43 #endif
44 
45 /* Root structure. */
46 #define	rb_tree(a_type)							\
47 struct {								\
48     a_type *rbt_root;							\
49     a_type rbt_nil;							\
50 }
51 
52 /* Left accessors. */
53 #define	rbtn_left_get(a_type, a_field, a_node)				\
54     ((a_node)->a_field.rbn_left)
55 #define	rbtn_left_set(a_type, a_field, a_node, a_left) do {		\
56     (a_node)->a_field.rbn_left = a_left;				\
57 } while (0)
58 
59 #ifdef RB_COMPACT
60 /* Right accessors. */
61 #define	rbtn_right_get(a_type, a_field, a_node)				\
62     ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red)		\
63       & ((ssize_t)-2)))
64 #define	rbtn_right_set(a_type, a_field, a_node, a_right) do {		\
65     (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right)	\
66       | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1)));	\
67 } while (0)
68 
69 /* Color accessors. */
70 #define	rbtn_red_get(a_type, a_field, a_node)				\
71     ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red)		\
72       & ((size_t)1)))
73 #define	rbtn_color_set(a_type, a_field, a_node, a_red) do {		\
74     (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t)		\
75       (a_node)->a_field.rbn_right_red) & ((ssize_t)-2))			\
76       | ((ssize_t)a_red));						\
77 } while (0)
78 #define	rbtn_red_set(a_type, a_field, a_node) do {			\
79     (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t)		\
80       (a_node)->a_field.rbn_right_red) | ((size_t)1));			\
81 } while (0)
82 #define	rbtn_black_set(a_type, a_field, a_node) do {			\
83     (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t)		\
84       (a_node)->a_field.rbn_right_red) & ((ssize_t)-2));		\
85 } while (0)
86 #else
87 /* Right accessors. */
88 #define	rbtn_right_get(a_type, a_field, a_node)				\
89     ((a_node)->a_field.rbn_right)
90 #define	rbtn_right_set(a_type, a_field, a_node, a_right) do {		\
91     (a_node)->a_field.rbn_right = a_right;				\
92 } while (0)
93 
94 /* Color accessors. */
95 #define	rbtn_red_get(a_type, a_field, a_node)				\
96     ((a_node)->a_field.rbn_red)
97 #define	rbtn_color_set(a_type, a_field, a_node, a_red) do {		\
98     (a_node)->a_field.rbn_red = (a_red);				\
99 } while (0)
100 #define	rbtn_red_set(a_type, a_field, a_node) do {			\
101     (a_node)->a_field.rbn_red = true;					\
102 } while (0)
103 #define	rbtn_black_set(a_type, a_field, a_node) do {			\
104     (a_node)->a_field.rbn_red = false;					\
105 } while (0)
106 #endif
107 
108 /* Node initializer. */
109 #define	rbt_node_new(a_type, a_field, a_rbt, a_node) do {		\
110     rbtn_left_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil);	\
111     rbtn_right_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil);	\
112     rbtn_red_set(a_type, a_field, (a_node));				\
113 } while (0)
114 
115 /* Tree initializer. */
116 #define	rb_new(a_type, a_field, a_rbt) do {				\
117     (a_rbt)->rbt_root = &(a_rbt)->rbt_nil;				\
118     rbt_node_new(a_type, a_field, a_rbt, &(a_rbt)->rbt_nil);		\
119     rbtn_black_set(a_type, a_field, &(a_rbt)->rbt_nil);			\
120 } while (0)
121 
122 /* Internal utility macros. */
123 #define	rbtn_first(a_type, a_field, a_rbt, a_root, r_node) do {		\
124     (r_node) = (a_root);						\
125     if ((r_node) != &(a_rbt)->rbt_nil) {				\
126 	for (;								\
127 	  rbtn_left_get(a_type, a_field, (r_node)) != &(a_rbt)->rbt_nil;\
128 	  (r_node) = rbtn_left_get(a_type, a_field, (r_node))) {	\
129 	}								\
130     }									\
131 } while (0)
132 
133 #define	rbtn_last(a_type, a_field, a_rbt, a_root, r_node) do {		\
134     (r_node) = (a_root);						\
135     if ((r_node) != &(a_rbt)->rbt_nil) {				\
136 	for (; rbtn_right_get(a_type, a_field, (r_node)) !=		\
137 	  &(a_rbt)->rbt_nil; (r_node) = rbtn_right_get(a_type, a_field,	\
138 	  (r_node))) {							\
139 	}								\
140     }									\
141 } while (0)
142 
143 #define	rbtn_rotate_left(a_type, a_field, a_node, r_node) do {		\
144     (r_node) = rbtn_right_get(a_type, a_field, (a_node));		\
145     rbtn_right_set(a_type, a_field, (a_node),				\
146       rbtn_left_get(a_type, a_field, (r_node)));			\
147     rbtn_left_set(a_type, a_field, (r_node), (a_node));			\
148 } while (0)
149 
150 #define	rbtn_rotate_right(a_type, a_field, a_node, r_node) do {		\
151     (r_node) = rbtn_left_get(a_type, a_field, (a_node));		\
152     rbtn_left_set(a_type, a_field, (a_node),				\
153       rbtn_right_get(a_type, a_field, (r_node)));			\
154     rbtn_right_set(a_type, a_field, (r_node), (a_node));		\
155 } while (0)
156 
157 /*
158  * The rb_proto() macro generates function prototypes that correspond to the
159  * functions generated by an equivalently parameterized call to rb_gen().
160  */
161 
162 #define	rb_proto(a_attr, a_prefix, a_rbt_type, a_type)			\
163 a_attr void								\
164 a_prefix##new(a_rbt_type *rbtree);					\
165 a_attr a_type *								\
166 a_prefix##first(a_rbt_type *rbtree);					\
167 a_attr a_type *								\
168 a_prefix##last(a_rbt_type *rbtree);					\
169 a_attr a_type *								\
170 a_prefix##next(a_rbt_type *rbtree, a_type *node);			\
171 a_attr a_type *								\
172 a_prefix##prev(a_rbt_type *rbtree, a_type *node);			\
173 a_attr a_type *								\
174 a_prefix##search(a_rbt_type *rbtree, a_type *key);			\
175 a_attr a_type *								\
176 a_prefix##nsearch(a_rbt_type *rbtree, a_type *key);			\
177 a_attr a_type *								\
178 a_prefix##psearch(a_rbt_type *rbtree, a_type *key);			\
179 a_attr void								\
180 a_prefix##insert(a_rbt_type *rbtree, a_type *node);			\
181 a_attr void								\
182 a_prefix##remove(a_rbt_type *rbtree, a_type *node);			\
183 a_attr a_type *								\
184 a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)(	\
185   a_rbt_type *, a_type *, void *), void *arg);				\
186 a_attr a_type *								\
187 a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start,		\
188   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg);
189 
190 /*
191  * The rb_gen() macro generates a type-specific red-black tree implementation,
192  * based on the above cpp macros.
193  *
194  * Arguments:
195  *
196  *   a_attr    : Function attribute for generated functions (ex: static).
197  *   a_prefix  : Prefix for generated functions (ex: ex_).
198  *   a_rb_type : Type for red-black tree data structure (ex: ex_t).
199  *   a_type    : Type for red-black tree node data structure (ex: ex_node_t).
200  *   a_field   : Name of red-black tree node linkage (ex: ex_link).
201  *   a_cmp     : Node comparison function name, with the following prototype:
202  *                 int (a_cmp *)(a_type *a_node, a_type *a_other);
203  *                                       ^^^^^^
204  *                                    or a_key
205  *               Interpretation of comparision function return values:
206  *                 -1 : a_node <  a_other
207  *                  0 : a_node == a_other
208  *                  1 : a_node >  a_other
209  *               In all cases, the a_node or a_key macro argument is the first
210  *               argument to the comparison function, which makes it possible
211  *               to write comparison functions that treat the first argument
212  *               specially.
213  *
214  * Assuming the following setup:
215  *
216  *   typedef struct ex_node_s ex_node_t;
217  *   struct ex_node_s {
218  *       rb_node(ex_node_t) ex_link;
219  *   };
220  *   typedef rb_tree(ex_node_t) ex_t;
221  *   rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp)
222  *
223  * The following API is generated:
224  *
225  *   static void
226  *   ex_new(ex_t *tree);
227  *       Description: Initialize a red-black tree structure.
228  *       Args:
229  *         tree: Pointer to an uninitialized red-black tree object.
230  *
231  *   static ex_node_t *
232  *   ex_first(ex_t *tree);
233  *   static ex_node_t *
234  *   ex_last(ex_t *tree);
235  *       Description: Get the first/last node in tree.
236  *       Args:
237  *         tree: Pointer to an initialized red-black tree object.
238  *       Ret: First/last node in tree, or NULL if tree is empty.
239  *
240  *   static ex_node_t *
241  *   ex_next(ex_t *tree, ex_node_t *node);
242  *   static ex_node_t *
243  *   ex_prev(ex_t *tree, ex_node_t *node);
244  *       Description: Get node's successor/predecessor.
245  *       Args:
246  *         tree: Pointer to an initialized red-black tree object.
247  *         node: A node in tree.
248  *       Ret: node's successor/predecessor in tree, or NULL if node is
249  *            last/first.
250  *
251  *   static ex_node_t *
252  *   ex_search(ex_t *tree, ex_node_t *key);
253  *       Description: Search for node that matches key.
254  *       Args:
255  *         tree: Pointer to an initialized red-black tree object.
256  *         key : Search key.
257  *       Ret: Node in tree that matches key, or NULL if no match.
258  *
259  *   static ex_node_t *
260  *   ex_nsearch(ex_t *tree, ex_node_t *key);
261  *   static ex_node_t *
262  *   ex_psearch(ex_t *tree, ex_node_t *key);
263  *       Description: Search for node that matches key.  If no match is found,
264  *                    return what would be key's successor/predecessor, were
265  *                    key in tree.
266  *       Args:
267  *         tree: Pointer to an initialized red-black tree object.
268  *         key : Search key.
269  *       Ret: Node in tree that matches key, or if no match, hypothetical node's
270  *            successor/predecessor (NULL if no successor/predecessor).
271  *
272  *   static void
273  *   ex_insert(ex_t *tree, ex_node_t *node);
274  *       Description: Insert node into tree.
275  *       Args:
276  *         tree: Pointer to an initialized red-black tree object.
277  *         node: Node to be inserted into tree.
278  *
279  *   static void
280  *   ex_remove(ex_t *tree, ex_node_t *node);
281  *       Description: Remove node from tree.
282  *       Args:
283  *         tree: Pointer to an initialized red-black tree object.
284  *         node: Node in tree to be removed.
285  *
286  *   static ex_node_t *
287  *   ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *,
288  *     ex_node_t *, void *), void *arg);
289  *   static ex_node_t *
290  *   ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *,
291  *     ex_node_t *, void *), void *arg);
292  *       Description: Iterate forward/backward over tree, starting at node.  If
293  *                    tree is modified, iteration must be immediately
294  *                    terminated by the callback function that causes the
295  *                    modification.
296  *       Args:
297  *         tree : Pointer to an initialized red-black tree object.
298  *         start: Node at which to start iteration, or NULL to start at
299  *                first/last node.
300  *         cb   : Callback function, which is called for each node during
301  *                iteration.  Under normal circumstances the callback function
302  *                should return NULL, which causes iteration to continue.  If a
303  *                callback function returns non-NULL, iteration is immediately
304  *                terminated and the non-NULL return value is returned by the
305  *                iterator.  This is useful for re-starting iteration after
306  *                modifying tree.
307  *         arg  : Opaque pointer passed to cb().
308  *       Ret: NULL if iteration completed, or the non-NULL callback return value
309  *            that caused termination of the iteration.
310  */
311 #define	rb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp)	\
312 a_attr void								\
313 a_prefix##new(a_rbt_type *rbtree) {					\
314     rb_new(a_type, a_field, rbtree);					\
315 }									\
316 a_attr a_type *								\
317 a_prefix##first(a_rbt_type *rbtree) {					\
318     a_type *ret;							\
319     rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret);		\
320     if (ret == &rbtree->rbt_nil) {					\
321 	ret = NULL;							\
322     }									\
323     return (ret);							\
324 }									\
325 a_attr a_type *								\
326 a_prefix##last(a_rbt_type *rbtree) {					\
327     a_type *ret;							\
328     rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret);		\
329     if (ret == &rbtree->rbt_nil) {					\
330 	ret = NULL;							\
331     }									\
332     return (ret);							\
333 }									\
334 a_attr a_type *								\
335 a_prefix##next(a_rbt_type *rbtree, a_type *node) {			\
336     a_type *ret;							\
337     if (rbtn_right_get(a_type, a_field, node) != &rbtree->rbt_nil) {	\
338 	rbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type,	\
339 	  a_field, node), ret);						\
340     } else {								\
341 	a_type *tnode = rbtree->rbt_root;				\
342 	assert(tnode != &rbtree->rbt_nil);				\
343 	ret = &rbtree->rbt_nil;						\
344 	while (true) {							\
345 	    int cmp = (a_cmp)(node, tnode);				\
346 	    if (cmp < 0) {						\
347 		ret = tnode;						\
348 		tnode = rbtn_left_get(a_type, a_field, tnode);		\
349 	    } else if (cmp > 0) {					\
350 		tnode = rbtn_right_get(a_type, a_field, tnode);		\
351 	    } else {							\
352 		break;							\
353 	    }								\
354 	    assert(tnode != &rbtree->rbt_nil);				\
355 	}								\
356     }									\
357     if (ret == &rbtree->rbt_nil) {					\
358 	ret = (NULL);							\
359     }									\
360     return (ret);							\
361 }									\
362 a_attr a_type *								\
363 a_prefix##prev(a_rbt_type *rbtree, a_type *node) {			\
364     a_type *ret;							\
365     if (rbtn_left_get(a_type, a_field, node) != &rbtree->rbt_nil) {	\
366 	rbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type,	\
367 	  a_field, node), ret);						\
368     } else {								\
369 	a_type *tnode = rbtree->rbt_root;				\
370 	assert(tnode != &rbtree->rbt_nil);				\
371 	ret = &rbtree->rbt_nil;						\
372 	while (true) {							\
373 	    int cmp = (a_cmp)(node, tnode);				\
374 	    if (cmp < 0) {						\
375 		tnode = rbtn_left_get(a_type, a_field, tnode);		\
376 	    } else if (cmp > 0) {					\
377 		ret = tnode;						\
378 		tnode = rbtn_right_get(a_type, a_field, tnode);		\
379 	    } else {							\
380 		break;							\
381 	    }								\
382 	    assert(tnode != &rbtree->rbt_nil);				\
383 	}								\
384     }									\
385     if (ret == &rbtree->rbt_nil) {					\
386 	ret = (NULL);							\
387     }									\
388     return (ret);							\
389 }									\
390 a_attr a_type *								\
391 a_prefix##search(a_rbt_type *rbtree, a_type *key) {			\
392     a_type *ret;							\
393     int cmp;								\
394     ret = rbtree->rbt_root;						\
395     while (ret != &rbtree->rbt_nil					\
396       && (cmp = (a_cmp)(key, ret)) != 0) {				\
397 	if (cmp < 0) {							\
398 	    ret = rbtn_left_get(a_type, a_field, ret);			\
399 	} else {							\
400 	    ret = rbtn_right_get(a_type, a_field, ret);			\
401 	}								\
402     }									\
403     if (ret == &rbtree->rbt_nil) {					\
404 	ret = (NULL);							\
405     }									\
406     return (ret);							\
407 }									\
408 a_attr a_type *								\
409 a_prefix##nsearch(a_rbt_type *rbtree, a_type *key) {			\
410     a_type *ret;							\
411     a_type *tnode = rbtree->rbt_root;					\
412     ret = &rbtree->rbt_nil;						\
413     while (tnode != &rbtree->rbt_nil) {					\
414 	int cmp = (a_cmp)(key, tnode);					\
415 	if (cmp < 0) {							\
416 	    ret = tnode;						\
417 	    tnode = rbtn_left_get(a_type, a_field, tnode);		\
418 	} else if (cmp > 0) {						\
419 	    tnode = rbtn_right_get(a_type, a_field, tnode);		\
420 	} else {							\
421 	    ret = tnode;						\
422 	    break;							\
423 	}								\
424     }									\
425     if (ret == &rbtree->rbt_nil) {					\
426 	ret = (NULL);							\
427     }									\
428     return (ret);							\
429 }									\
430 a_attr a_type *								\
431 a_prefix##psearch(a_rbt_type *rbtree, a_type *key) {			\
432     a_type *ret;							\
433     a_type *tnode = rbtree->rbt_root;					\
434     ret = &rbtree->rbt_nil;						\
435     while (tnode != &rbtree->rbt_nil) {					\
436 	int cmp = (a_cmp)(key, tnode);					\
437 	if (cmp < 0) {							\
438 	    tnode = rbtn_left_get(a_type, a_field, tnode);		\
439 	} else if (cmp > 0) {						\
440 	    ret = tnode;						\
441 	    tnode = rbtn_right_get(a_type, a_field, tnode);		\
442 	} else {							\
443 	    ret = tnode;						\
444 	    break;							\
445 	}								\
446     }									\
447     if (ret == &rbtree->rbt_nil) {					\
448 	ret = (NULL);							\
449     }									\
450     return (ret);							\
451 }									\
452 a_attr void								\
453 a_prefix##insert(a_rbt_type *rbtree, a_type *node) {			\
454     struct {								\
455 	a_type *node;							\
456 	int cmp;							\
457     } path[sizeof(void *) << 4], *pathp;				\
458     rbt_node_new(a_type, a_field, rbtree, node);			\
459     /* Wind. */								\
460     path->node = rbtree->rbt_root;					\
461     for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) {	\
462 	int cmp = pathp->cmp = a_cmp(node, pathp->node);		\
463 	assert(cmp != 0);						\
464 	if (cmp < 0) {							\
465 	    pathp[1].node = rbtn_left_get(a_type, a_field,		\
466 	      pathp->node);						\
467 	} else {							\
468 	    pathp[1].node = rbtn_right_get(a_type, a_field,		\
469 	      pathp->node);						\
470 	}								\
471     }									\
472     pathp->node = node;							\
473     /* Unwind. */							\
474     for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) {	\
475 	a_type *cnode = pathp->node;					\
476 	if (pathp->cmp < 0) {						\
477 	    a_type *left = pathp[1].node;				\
478 	    rbtn_left_set(a_type, a_field, cnode, left);		\
479 	    if (rbtn_red_get(a_type, a_field, left)) {			\
480 		a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
481 		if (rbtn_red_get(a_type, a_field, leftleft)) {		\
482 		    /* Fix up 4-node. */				\
483 		    a_type *tnode;					\
484 		    rbtn_black_set(a_type, a_field, leftleft);		\
485 		    rbtn_rotate_right(a_type, a_field, cnode, tnode);	\
486 		    cnode = tnode;					\
487 		}							\
488 	    } else {							\
489 		return;							\
490 	    }								\
491 	} else {							\
492 	    a_type *right = pathp[1].node;				\
493 	    rbtn_right_set(a_type, a_field, cnode, right);		\
494 	    if (rbtn_red_get(a_type, a_field, right)) {			\
495 		a_type *left = rbtn_left_get(a_type, a_field, cnode);	\
496 		if (rbtn_red_get(a_type, a_field, left)) {		\
497 		    /* Split 4-node. */					\
498 		    rbtn_black_set(a_type, a_field, left);		\
499 		    rbtn_black_set(a_type, a_field, right);		\
500 		    rbtn_red_set(a_type, a_field, cnode);		\
501 		} else {						\
502 		    /* Lean left. */					\
503 		    a_type *tnode;					\
504 		    bool tred = rbtn_red_get(a_type, a_field, cnode);	\
505 		    rbtn_rotate_left(a_type, a_field, cnode, tnode);	\
506 		    rbtn_color_set(a_type, a_field, tnode, tred);	\
507 		    rbtn_red_set(a_type, a_field, cnode);		\
508 		    cnode = tnode;					\
509 		}							\
510 	    } else {							\
511 		return;							\
512 	    }								\
513 	}								\
514 	pathp->node = cnode;						\
515     }									\
516     /* Set root, and make it black. */					\
517     rbtree->rbt_root = path->node;					\
518     rbtn_black_set(a_type, a_field, rbtree->rbt_root);			\
519 }									\
520 a_attr void								\
521 a_prefix##remove(a_rbt_type *rbtree, a_type *node) {			\
522     struct {								\
523 	a_type *node;							\
524 	int cmp;							\
525     } *pathp, *nodep, path[sizeof(void *) << 4];			\
526     /* Wind. */								\
527     nodep = NULL; /* Silence compiler warning. */			\
528     path->node = rbtree->rbt_root;					\
529     for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) {	\
530 	int cmp = pathp->cmp = a_cmp(node, pathp->node);		\
531 	if (cmp < 0) {							\
532 	    pathp[1].node = rbtn_left_get(a_type, a_field,		\
533 	      pathp->node);						\
534 	} else {							\
535 	    pathp[1].node = rbtn_right_get(a_type, a_field,		\
536 	      pathp->node);						\
537 	    if (cmp == 0) {						\
538 	        /* Find node's successor, in preparation for swap. */	\
539 		pathp->cmp = 1;						\
540 		nodep = pathp;						\
541 		for (pathp++; pathp->node != &rbtree->rbt_nil;		\
542 		  pathp++) {						\
543 		    pathp->cmp = -1;					\
544 		    pathp[1].node = rbtn_left_get(a_type, a_field,	\
545 		      pathp->node);					\
546 		}							\
547 		break;							\
548 	    }								\
549 	}								\
550     }									\
551     assert(nodep->node == node);					\
552     pathp--;								\
553     if (pathp->node != node) {						\
554 	/* Swap node with its successor. */				\
555 	bool tred = rbtn_red_get(a_type, a_field, pathp->node);		\
556 	rbtn_color_set(a_type, a_field, pathp->node,			\
557 	  rbtn_red_get(a_type, a_field, node));				\
558 	rbtn_left_set(a_type, a_field, pathp->node,			\
559 	  rbtn_left_get(a_type, a_field, node));			\
560 	/* If node's successor is its right child, the following code */\
561 	/* will do the wrong thing for the right child pointer.       */\
562 	/* However, it doesn't matter, because the pointer will be    */\
563 	/* properly set when the successor is pruned.                 */\
564 	rbtn_right_set(a_type, a_field, pathp->node,			\
565 	  rbtn_right_get(a_type, a_field, node));			\
566 	rbtn_color_set(a_type, a_field, node, tred);			\
567 	/* The pruned leaf node's child pointers are never accessed   */\
568 	/* again, so don't bother setting them to nil.                */\
569 	nodep->node = pathp->node;					\
570 	pathp->node = node;						\
571 	if (nodep == path) {						\
572 	    rbtree->rbt_root = nodep->node;				\
573 	} else {							\
574 	    if (nodep[-1].cmp < 0) {					\
575 		rbtn_left_set(a_type, a_field, nodep[-1].node,		\
576 		  nodep->node);						\
577 	    } else {							\
578 		rbtn_right_set(a_type, a_field, nodep[-1].node,		\
579 		  nodep->node);						\
580 	    }								\
581 	}								\
582     } else {								\
583 	a_type *left = rbtn_left_get(a_type, a_field, node);		\
584 	if (left != &rbtree->rbt_nil) {					\
585 	    /* node has no successor, but it has a left child.        */\
586 	    /* Splice node out, without losing the left child.        */\
587 	    assert(rbtn_red_get(a_type, a_field, node) == false);	\
588 	    assert(rbtn_red_get(a_type, a_field, left));		\
589 	    rbtn_black_set(a_type, a_field, left);			\
590 	    if (pathp == path) {					\
591 		rbtree->rbt_root = left;				\
592 	    } else {							\
593 		if (pathp[-1].cmp < 0) {				\
594 		    rbtn_left_set(a_type, a_field, pathp[-1].node,	\
595 		      left);						\
596 		} else {						\
597 		    rbtn_right_set(a_type, a_field, pathp[-1].node,	\
598 		      left);						\
599 		}							\
600 	    }								\
601 	    return;							\
602 	} else if (pathp == path) {					\
603 	    /* The tree only contained one node. */			\
604 	    rbtree->rbt_root = &rbtree->rbt_nil;			\
605 	    return;							\
606 	}								\
607     }									\
608     if (rbtn_red_get(a_type, a_field, pathp->node)) {			\
609 	/* Prune red node, which requires no fixup. */			\
610 	assert(pathp[-1].cmp < 0);					\
611 	rbtn_left_set(a_type, a_field, pathp[-1].node,			\
612 	  &rbtree->rbt_nil);						\
613 	return;								\
614     }									\
615     /* The node to be pruned is black, so unwind until balance is     */\
616     /* restored.                                                      */\
617     pathp->node = &rbtree->rbt_nil;					\
618     for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) {	\
619 	assert(pathp->cmp != 0);					\
620 	if (pathp->cmp < 0) {						\
621 	    rbtn_left_set(a_type, a_field, pathp->node,			\
622 	      pathp[1].node);						\
623 	    assert(rbtn_red_get(a_type, a_field, pathp[1].node)		\
624 	      == false);						\
625 	    if (rbtn_red_get(a_type, a_field, pathp->node)) {		\
626 		a_type *right = rbtn_right_get(a_type, a_field,		\
627 		  pathp->node);						\
628 		a_type *rightleft = rbtn_left_get(a_type, a_field,	\
629 		  right);						\
630 		a_type *tnode;						\
631 		if (rbtn_red_get(a_type, a_field, rightleft)) {		\
632 		    /* In the following diagrams, ||, //, and \\      */\
633 		    /* indicate the path to the removed node.         */\
634 		    /*                                                */\
635 		    /*      ||                                        */\
636 		    /*    pathp(r)                                    */\
637 		    /*  //        \                                   */\
638 		    /* (b)        (b)                                 */\
639 		    /*           /                                    */\
640 		    /*          (r)                                   */\
641 		    /*                                                */\
642 		    rbtn_black_set(a_type, a_field, pathp->node);	\
643 		    rbtn_rotate_right(a_type, a_field, right, tnode);	\
644 		    rbtn_right_set(a_type, a_field, pathp->node, tnode);\
645 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
646 		      tnode);						\
647 		} else {						\
648 		    /*      ||                                        */\
649 		    /*    pathp(r)                                    */\
650 		    /*  //        \                                   */\
651 		    /* (b)        (b)                                 */\
652 		    /*           /                                    */\
653 		    /*          (b)                                   */\
654 		    /*                                                */\
655 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
656 		      tnode);						\
657 		}							\
658 		/* Balance restored, but rotation modified subtree    */\
659 		/* root.                                              */\
660 		assert((uintptr_t)pathp > (uintptr_t)path);		\
661 		if (pathp[-1].cmp < 0) {				\
662 		    rbtn_left_set(a_type, a_field, pathp[-1].node,	\
663 		      tnode);						\
664 		} else {						\
665 		    rbtn_right_set(a_type, a_field, pathp[-1].node,	\
666 		      tnode);						\
667 		}							\
668 		return;							\
669 	    } else {							\
670 		a_type *right = rbtn_right_get(a_type, a_field,		\
671 		  pathp->node);						\
672 		a_type *rightleft = rbtn_left_get(a_type, a_field,	\
673 		  right);						\
674 		if (rbtn_red_get(a_type, a_field, rightleft)) {		\
675 		    /*      ||                                        */\
676 		    /*    pathp(b)                                    */\
677 		    /*  //        \                                   */\
678 		    /* (b)        (b)                                 */\
679 		    /*           /                                    */\
680 		    /*          (r)                                   */\
681 		    a_type *tnode;					\
682 		    rbtn_black_set(a_type, a_field, rightleft);		\
683 		    rbtn_rotate_right(a_type, a_field, right, tnode);	\
684 		    rbtn_right_set(a_type, a_field, pathp->node, tnode);\
685 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
686 		      tnode);						\
687 		    /* Balance restored, but rotation modified        */\
688 		    /* subree root, which may actually be the tree    */\
689 		    /* root.                                          */\
690 		    if (pathp == path) {				\
691 			/* Set root. */					\
692 			rbtree->rbt_root = tnode;			\
693 		    } else {						\
694 			if (pathp[-1].cmp < 0) {			\
695 			    rbtn_left_set(a_type, a_field,		\
696 			      pathp[-1].node, tnode);			\
697 			} else {					\
698 			    rbtn_right_set(a_type, a_field,		\
699 			      pathp[-1].node, tnode);			\
700 			}						\
701 		    }							\
702 		    return;						\
703 		} else {						\
704 		    /*      ||                                        */\
705 		    /*    pathp(b)                                    */\
706 		    /*  //        \                                   */\
707 		    /* (b)        (b)                                 */\
708 		    /*           /                                    */\
709 		    /*          (b)                                   */\
710 		    a_type *tnode;					\
711 		    rbtn_red_set(a_type, a_field, pathp->node);		\
712 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
713 		      tnode);						\
714 		    pathp->node = tnode;				\
715 		}							\
716 	    }								\
717 	} else {							\
718 	    a_type *left;						\
719 	    rbtn_right_set(a_type, a_field, pathp->node,		\
720 	      pathp[1].node);						\
721 	    left = rbtn_left_get(a_type, a_field, pathp->node);		\
722 	    if (rbtn_red_get(a_type, a_field, left)) {			\
723 		a_type *tnode;						\
724 		a_type *leftright = rbtn_right_get(a_type, a_field,	\
725 		  left);						\
726 		a_type *leftrightleft = rbtn_left_get(a_type, a_field,	\
727 		  leftright);						\
728 		if (rbtn_red_get(a_type, a_field, leftrightleft)) {	\
729 		    /*      ||                                        */\
730 		    /*    pathp(b)                                    */\
731 		    /*   /        \\                                  */\
732 		    /* (r)        (b)                                 */\
733 		    /*   \                                            */\
734 		    /*   (b)                                          */\
735 		    /*   /                                            */\
736 		    /* (r)                                            */\
737 		    a_type *unode;					\
738 		    rbtn_black_set(a_type, a_field, leftrightleft);	\
739 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
740 		      unode);						\
741 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
742 		      tnode);						\
743 		    rbtn_right_set(a_type, a_field, unode, tnode);	\
744 		    rbtn_rotate_left(a_type, a_field, unode, tnode);	\
745 		} else {						\
746 		    /*      ||                                        */\
747 		    /*    pathp(b)                                    */\
748 		    /*   /        \\                                  */\
749 		    /* (r)        (b)                                 */\
750 		    /*   \                                            */\
751 		    /*   (b)                                          */\
752 		    /*   /                                            */\
753 		    /* (b)                                            */\
754 		    assert(leftright != &rbtree->rbt_nil);		\
755 		    rbtn_red_set(a_type, a_field, leftright);		\
756 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
757 		      tnode);						\
758 		    rbtn_black_set(a_type, a_field, tnode);		\
759 		}							\
760 		/* Balance restored, but rotation modified subtree    */\
761 		/* root, which may actually be the tree root.         */\
762 		if (pathp == path) {					\
763 		    /* Set root. */					\
764 		    rbtree->rbt_root = tnode;				\
765 		} else {						\
766 		    if (pathp[-1].cmp < 0) {				\
767 			rbtn_left_set(a_type, a_field, pathp[-1].node,	\
768 			  tnode);					\
769 		    } else {						\
770 			rbtn_right_set(a_type, a_field, pathp[-1].node,	\
771 			  tnode);					\
772 		    }							\
773 		}							\
774 		return;							\
775 	    } else if (rbtn_red_get(a_type, a_field, pathp->node)) {	\
776 		a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
777 		if (rbtn_red_get(a_type, a_field, leftleft)) {		\
778 		    /*        ||                                      */\
779 		    /*      pathp(r)                                  */\
780 		    /*     /        \\                                */\
781 		    /*   (b)        (b)                               */\
782 		    /*   /                                            */\
783 		    /* (r)                                            */\
784 		    a_type *tnode;					\
785 		    rbtn_black_set(a_type, a_field, pathp->node);	\
786 		    rbtn_red_set(a_type, a_field, left);		\
787 		    rbtn_black_set(a_type, a_field, leftleft);		\
788 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
789 		      tnode);						\
790 		    /* Balance restored, but rotation modified        */\
791 		    /* subtree root.                                  */\
792 		    assert((uintptr_t)pathp > (uintptr_t)path);		\
793 		    if (pathp[-1].cmp < 0) {				\
794 			rbtn_left_set(a_type, a_field, pathp[-1].node,	\
795 			  tnode);					\
796 		    } else {						\
797 			rbtn_right_set(a_type, a_field, pathp[-1].node,	\
798 			  tnode);					\
799 		    }							\
800 		    return;						\
801 		} else {						\
802 		    /*        ||                                      */\
803 		    /*      pathp(r)                                  */\
804 		    /*     /        \\                                */\
805 		    /*   (b)        (b)                               */\
806 		    /*   /                                            */\
807 		    /* (b)                                            */\
808 		    rbtn_red_set(a_type, a_field, left);		\
809 		    rbtn_black_set(a_type, a_field, pathp->node);	\
810 		    /* Balance restored. */				\
811 		    return;						\
812 		}							\
813 	    } else {							\
814 		a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
815 		if (rbtn_red_get(a_type, a_field, leftleft)) {		\
816 		    /*               ||                               */\
817 		    /*             pathp(b)                           */\
818 		    /*            /        \\                         */\
819 		    /*          (b)        (b)                        */\
820 		    /*          /                                     */\
821 		    /*        (r)                                     */\
822 		    a_type *tnode;					\
823 		    rbtn_black_set(a_type, a_field, leftleft);		\
824 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
825 		      tnode);						\
826 		    /* Balance restored, but rotation modified        */\
827 		    /* subtree root, which may actually be the tree   */\
828 		    /* root.                                          */\
829 		    if (pathp == path) {				\
830 			/* Set root. */					\
831 			rbtree->rbt_root = tnode;			\
832 		    } else {						\
833 			if (pathp[-1].cmp < 0) {			\
834 			    rbtn_left_set(a_type, a_field,		\
835 			      pathp[-1].node, tnode);			\
836 			} else {					\
837 			    rbtn_right_set(a_type, a_field,		\
838 			      pathp[-1].node, tnode);			\
839 			}						\
840 		    }							\
841 		    return;						\
842 		} else {						\
843 		    /*               ||                               */\
844 		    /*             pathp(b)                           */\
845 		    /*            /        \\                         */\
846 		    /*          (b)        (b)                        */\
847 		    /*          /                                     */\
848 		    /*        (b)                                     */\
849 		    rbtn_red_set(a_type, a_field, left);		\
850 		}							\
851 	    }								\
852 	}								\
853     }									\
854     /* Set root. */							\
855     rbtree->rbt_root = path->node;					\
856     assert(rbtn_red_get(a_type, a_field, rbtree->rbt_root) == false);	\
857 }									\
858 a_attr a_type *								\
859 a_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node,		\
860   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
861     if (node == &rbtree->rbt_nil) {					\
862 	return (&rbtree->rbt_nil);					\
863     } else {								\
864 	a_type *ret;							\
865 	if ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type,	\
866 	  a_field, node), cb, arg)) != &rbtree->rbt_nil			\
867 	  || (ret = cb(rbtree, node, arg)) != NULL) {			\
868 	    return (ret);						\
869 	}								\
870 	return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,	\
871 	  a_field, node), cb, arg));					\
872     }									\
873 }									\
874 a_attr a_type *								\
875 a_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node,	\
876   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
877     int cmp = a_cmp(start, node);					\
878     if (cmp < 0) {							\
879 	a_type *ret;							\
880 	if ((ret = a_prefix##iter_start(rbtree, start,			\
881 	  rbtn_left_get(a_type, a_field, node), cb, arg)) !=		\
882 	  &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) {	\
883 	    return (ret);						\
884 	}								\
885 	return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,	\
886 	  a_field, node), cb, arg));					\
887     } else if (cmp > 0) {						\
888 	return (a_prefix##iter_start(rbtree, start,			\
889 	  rbtn_right_get(a_type, a_field, node), cb, arg));		\
890     } else {								\
891 	a_type *ret;							\
892 	if ((ret = cb(rbtree, node, arg)) != NULL) {			\
893 	    return (ret);						\
894 	}								\
895 	return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,	\
896 	  a_field, node), cb, arg));					\
897     }									\
898 }									\
899 a_attr a_type *								\
900 a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)(	\
901   a_rbt_type *, a_type *, void *), void *arg) {				\
902     a_type *ret;							\
903     if (start != NULL) {						\
904 	ret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root,	\
905 	  cb, arg);							\
906     } else {								\
907 	ret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\
908     }									\
909     if (ret == &rbtree->rbt_nil) {					\
910 	ret = NULL;							\
911     }									\
912     return (ret);							\
913 }									\
914 a_attr a_type *								\
915 a_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node,	\
916   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
917     if (node == &rbtree->rbt_nil) {					\
918 	return (&rbtree->rbt_nil);					\
919     } else {								\
920 	a_type *ret;							\
921 	if ((ret = a_prefix##reverse_iter_recurse(rbtree,		\
922 	  rbtn_right_get(a_type, a_field, node), cb, arg)) !=		\
923 	  &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) {	\
924 	    return (ret);						\
925 	}								\
926 	return (a_prefix##reverse_iter_recurse(rbtree,			\
927 	  rbtn_left_get(a_type, a_field, node), cb, arg));		\
928     }									\
929 }									\
930 a_attr a_type *								\
931 a_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start,		\
932   a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *),		\
933   void *arg) {								\
934     int cmp = a_cmp(start, node);					\
935     if (cmp > 0) {							\
936 	a_type *ret;							\
937 	if ((ret = a_prefix##reverse_iter_start(rbtree, start,		\
938 	  rbtn_right_get(a_type, a_field, node), cb, arg)) !=		\
939 	  &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) {	\
940 	    return (ret);						\
941 	}								\
942 	return (a_prefix##reverse_iter_recurse(rbtree,			\
943 	  rbtn_left_get(a_type, a_field, node), cb, arg));		\
944     } else if (cmp < 0) {						\
945 	return (a_prefix##reverse_iter_start(rbtree, start,		\
946 	  rbtn_left_get(a_type, a_field, node), cb, arg));		\
947     } else {								\
948 	a_type *ret;							\
949 	if ((ret = cb(rbtree, node, arg)) != NULL) {			\
950 	    return (ret);						\
951 	}								\
952 	return (a_prefix##reverse_iter_recurse(rbtree,			\
953 	  rbtn_left_get(a_type, a_field, node), cb, arg));		\
954     }									\
955 }									\
956 a_attr a_type *								\
957 a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start,		\
958   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
959     a_type *ret;							\
960     if (start != NULL) {						\
961 	ret = a_prefix##reverse_iter_start(rbtree, start,		\
962 	  rbtree->rbt_root, cb, arg);					\
963     } else {								\
964 	ret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root,	\
965 	  cb, arg);							\
966     }									\
967     if (ret == &rbtree->rbt_nil) {					\
968 	ret = NULL;							\
969     }									\
970     return (ret);							\
971 }
972 
973 #endif /* RB_H_ */
974