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