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