]> git.saurik.com Git - redis.git/blob - deps/jemalloc.orig/include/jemalloc/internal/rb.h
Jemalloc updated to 3.0.0.
[redis.git] / deps / jemalloc.orig / include / jemalloc / internal / rb.h
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: head/lib/libc/stdlib/rb.h 204493 2010-02-28 22:57:13Z jasone $");
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 *extree);
227 * Description: Initialize a red-black tree structure.
228 * Args:
229 * extree: Pointer to an uninitialized red-black tree object.
230 *
231 * static ex_node_t *
232 * ex_first(ex_t *extree);
233 * static ex_node_t *
234 * ex_last(ex_t *extree);
235 * Description: Get the first/last node in extree.
236 * Args:
237 * extree: Pointer to an initialized red-black tree object.
238 * Ret: First/last node in extree, or NULL if extree is empty.
239 *
240 * static ex_node_t *
241 * ex_next(ex_t *extree, ex_node_t *node);
242 * static ex_node_t *
243 * ex_prev(ex_t *extree, ex_node_t *node);
244 * Description: Get node's successor/predecessor.
245 * Args:
246 * extree: Pointer to an initialized red-black tree object.
247 * node : A node in extree.
248 * Ret: node's successor/predecessor in extree, or NULL if node is
249 * last/first.
250 *
251 * static ex_node_t *
252 * ex_search(ex_t *extree, ex_node_t *key);
253 * Description: Search for node that matches key.
254 * Args:
255 * extree: Pointer to an initialized red-black tree object.
256 * key : Search key.
257 * Ret: Node in extree that matches key, or NULL if no match.
258 *
259 * static ex_node_t *
260 * ex_nsearch(ex_t *extree, ex_node_t *key);
261 * static ex_node_t *
262 * ex_psearch(ex_t *extree, 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 extree.
266 * Args:
267 * extree: Pointer to an initialized red-black tree object.
268 * key : Search key.
269 * Ret: Node in extree that matches key, or if no match, hypothetical
270 * node's successor/predecessor (NULL if no successor/predecessor).
271 *
272 * static void
273 * ex_insert(ex_t *extree, ex_node_t *node);
274 * Description: Insert node into extree.
275 * Args:
276 * extree: Pointer to an initialized red-black tree object.
277 * node : Node to be inserted into extree.
278 *
279 * static void
280 * ex_remove(ex_t *extree, ex_node_t *node);
281 * Description: Remove node from extree.
282 * Args:
283 * extree: Pointer to an initialized red-black tree object.
284 * node : Node in extree to be removed.
285 *
286 * static ex_node_t *
287 * ex_iter(ex_t *extree, 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 *extree, ex_node_t *start, ex_node *(*cb)(ex_t *,
291 * ex_node_t *, void *), void *arg);
292 * Description: Iterate forward/backward over extree, starting at node.
293 * If extree is modified, iteration must be immediately
294 * terminated by the callback function that causes the
295 * modification.
296 * Args:
297 * extree: 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 extree.
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_ */