1/* 2 * Copyright © 2017 Jason Ekstrand 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 */ 22 23#ifndef RB_TREE_H 24#define RB_TREE_H 25 26#include <stdbool.h> 27#include <stddef.h> 28#include <stdint.h> 29#include <stdlib.h> 30 31#ifdef __cplusplus 32extern "C" { 33#endif 34 35/** A red-black tree node 36 * 37 * This struct represents a node in the red-black tree. This struct should 38 * be embedded as a member in whatever structure you wish to put in the 39 * tree. 40 */ 41struct rb_node { 42 /** Parent and color of this node 43 * 44 * The least significant bit represents the color and is est to 1 for 45 * black and 0 for red. The other bits are the pointer to the parent 46 * and that pointer can be retrieved by masking off the bottom bit and 47 * casting to a pointer. 48 */ 49 uintptr_t parent; 50 51 /** Left child of this node, null for a leaf */ 52 struct rb_node *left; 53 54 /** Right child of this node, null for a leaf */ 55 struct rb_node *right; 56}; 57 58/** Return the parent node of the given node or NULL if it is the root */ 59static inline struct rb_node * 60rb_node_parent(struct rb_node *n) 61{ 62 return (struct rb_node *)(n->parent & ~(uintptr_t)1); 63} 64 65/** A red-black tree 66 * 67 * This struct represents the red-black tree itself. It is just a pointer 68 * to the root node with no other metadata. 69 */ 70struct rb_tree { 71 struct rb_node *root; 72}; 73 74/** Initialize a red-black tree */ 75void rb_tree_init(struct rb_tree *T); 76 77/** Returns true if the red-black tree is empty */ 78static inline bool 79rb_tree_is_empty(const struct rb_tree *T) 80{ 81 return T->root == NULL; 82} 83 84/** Retrieve the data structure containing a node 85 * 86 * \param type The type of the containing data structure 87 * 88 * \param node A pointer to a rb_node 89 * 90 * \param field The rb_node field in the containing data structure 91 */ 92#define rb_node_data(type, node, field) \ 93 ((type *)(((char *)(node)) - offsetof(type, field))) 94 95/** Insert a node into a tree at a particular location 96 * 97 * This function should probably not be used directly as it relies on the 98 * caller to ensure that the parent node is correct. Use rb_tree_insert 99 * instead. 100 * 101 * \param T The red-black tree into which to insert the new node 102 * 103 * \param parent The node in the tree that will be the parent of the 104 * newly inserted node 105 * 106 * \param node The node to insert 107 * 108 * \param insert_left If true, the new node will be the left child of 109 * \p parent, otherwise it will be the right child 110 */ 111void rb_tree_insert_at(struct rb_tree *T, struct rb_node *parent, 112 struct rb_node *node, bool insert_left); 113 114/** Insert a node into a tree 115 * 116 * \param T The red-black tree into which to insert the new node 117 * 118 * \param node The node to insert 119 * 120 * \param cmp A comparison function to use to order the nodes. 121 */ 122static inline void 123rb_tree_insert(struct rb_tree *T, struct rb_node *node, 124 int (*cmp)(const struct rb_node *, const struct rb_node *)) 125{ 126 /* This function is declared inline in the hopes that the compiler can 127 * optimize away the comparison function pointer call. 128 */ 129 struct rb_node *y = NULL; 130 struct rb_node *x = T->root; 131 bool left = false; 132 while (x != NULL) { 133 y = x; 134 left = cmp(x, node) < 0; 135 if (left) 136 x = x->left; 137 else 138 x = x->right; 139 } 140 141 rb_tree_insert_at(T, y, node, left); 142} 143 144/** Remove a node from a tree 145 * 146 * \param T The red-black tree from which to remove the node 147 * 148 * \param node The node to remove 149 */ 150void rb_tree_remove(struct rb_tree *T, struct rb_node *z); 151 152/** Search the tree for a node 153 * 154 * If a node with a matching key exists, the first matching node found will 155 * be returned. If no matching node exists, NULL is returned. 156 * 157 * \param T The red-black tree to search 158 * 159 * \param key The key to search for 160 * 161 * \param cmp A comparison function to use to order the nodes 162 */ 163static inline struct rb_node * 164rb_tree_search(struct rb_tree *T, const void *key, 165 int (*cmp)(const struct rb_node *, const void *)) 166{ 167 /* This function is declared inline in the hopes that the compiler can 168 * optimize away the comparison function pointer call. 169 */ 170 struct rb_node *x = T->root; 171 while (x != NULL) { 172 int c = cmp(x, key); 173 if (c < 0) 174 x = x->left; 175 else if (c > 0) 176 x = x->right; 177 else 178 return x; 179 } 180 181 return x; 182} 183 184/** Sloppily search the tree for a node 185 * 186 * This function searches the tree for a given node. If a node with a 187 * matching key exists, that first matching node found will be returned. 188 * If no node with an exactly matching key exists, the node returned will 189 * be either the right-most node comparing less than \p key or the 190 * right-most node comparing greater than \p key. If the tree is empty, 191 * NULL is returned. 192 * 193 * \param T The red-black tree to search 194 * 195 * \param key The key to search for 196 * 197 * \param cmp A comparison function to use to order the nodes 198 */ 199static inline struct rb_node * 200rb_tree_search_sloppy(struct rb_tree *T, const void *key, 201 int (*cmp)(const struct rb_node *, const void *)) 202{ 203 /* This function is declared inline in the hopes that the compiler can 204 * optimize away the comparison function pointer call. 205 */ 206 struct rb_node *y = NULL; 207 struct rb_node *x = T->root; 208 while (x != NULL) { 209 y = x; 210 int c = cmp(x, key); 211 if (c < 0) 212 x = x->left; 213 else if (c > 0) 214 x = x->right; 215 else 216 return x; 217 } 218 219 return y; 220} 221 222/** Get the first (left-most) node in the tree or NULL */ 223struct rb_node *rb_tree_first(struct rb_tree *T); 224 225/** Get the last (right-most) node in the tree or NULL */ 226struct rb_node *rb_tree_last(struct rb_tree *T); 227 228/** Get the next node (to the right) in the tree or NULL */ 229struct rb_node *rb_node_next(struct rb_node *node); 230 231/** Get the next previous (to the left) in the tree or NULL */ 232struct rb_node *rb_node_prev(struct rb_node *node); 233 234#define rb_node_next_or_null(n) ((n) == NULL ? NULL : rb_node_next(n)) 235#define rb_node_prev_or_null(n) ((n) == NULL ? NULL : rb_node_prev(n)) 236 237/** Iterate over the nodes in the tree 238 * 239 * \param type The type of the containing data structure 240 * 241 * \param node The variable name for current node in the iteration; 242 * this will be declared as a pointer to \p type 243 * 244 * \param T The red-black tree 245 * 246 * \param field The rb_node field in containing data structure 247 */ 248#define rb_tree_foreach(type, iter, T, field) \ 249 for (type *iter, *__node = (type *)rb_tree_first(T); \ 250 __node != NULL && \ 251 (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 252 __node = (type *)rb_node_next((struct rb_node *)__node)) 253 254/** Iterate over the nodes in the tree, allowing the current node to be freed 255 * 256 * \param type The type of the containing data structure 257 * 258 * \param node The variable name for current node in the iteration; 259 * this will be declared as a pointer to \p type 260 * 261 * \param T The red-black tree 262 * 263 * \param field The rb_node field in containing data structure 264 */ 265#define rb_tree_foreach_safe(type, iter, T, field) \ 266 for (type *iter, \ 267 *__node = (type *)rb_tree_first(T), \ 268 *__next = (type *)rb_node_next_or_null((struct rb_node *)__node); \ 269 __node != NULL && \ 270 (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 271 __node = __next, \ 272 __next = (type *)rb_node_next_or_null((struct rb_node *)__node)) 273 274/** Iterate over the nodes in the tree in reverse 275 * 276 * \param type The type of the containing data structure 277 * 278 * \param node The variable name for current node in the iteration; 279 * this will be declared as a pointer to \p type 280 * 281 * \param T The red-black tree 282 * 283 * \param field The rb_node field in containing data structure 284 */ 285#define rb_tree_foreach_rev(type, iter, T, field) \ 286 for (type *iter, *__node = (type *)rb_tree_last(T); \ 287 __node != NULL && \ 288 (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 289 __node = (type *)rb_node_prev((struct rb_node *)__node)) 290 291/** Iterate over the nodes in the tree in reverse, allowing the current node to be freed 292 * 293 * \param type The type of the containing data structure 294 * 295 * \param node The variable name for current node in the iteration; 296 * this will be declared as a pointer to \p type 297 * 298 * \param T The red-black tree 299 * 300 * \param field The rb_node field in containing data structure 301 */ 302#define rb_tree_foreach_rev_safe(type, iter, T, field) \ 303 for (type *iter, \ 304 *__node = (type *)rb_tree_last(T), \ 305 *__prev = (type *)rb_node_prev_or_null((struct rb_node *)__node); \ 306 __node != NULL && \ 307 (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 308 __node = __prev, \ 309 __prev = (type *)rb_node_prev_or_null((struct rb_node *)__node)) 310 311/** Validate a red-black tree 312 * 313 * This function walks the tree and validates that this is a valid red- 314 * black tree. If anything is wrong, it will assert-fail. 315 */ 316void rb_tree_validate(struct rb_tree *T); 317 318#ifdef __cplusplus 319} /* extern C */ 320#endif 321 322#endif /* RB_TREE_H */ 323