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