101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2017 Jason Ekstrand 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice shall be included in 1201e04c3fSmrg * all copies or substantial portions of the Software. 1301e04c3fSmrg * 1401e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1501e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1601e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1701e04c3fSmrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1801e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1901e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2001e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2101e04c3fSmrg */ 2201e04c3fSmrg 2301e04c3fSmrg#ifndef RB_TREE_H 2401e04c3fSmrg#define RB_TREE_H 2501e04c3fSmrg 2601e04c3fSmrg#include <stdbool.h> 2701e04c3fSmrg#include <stddef.h> 2801e04c3fSmrg#include <stdint.h> 2901e04c3fSmrg#include <stdlib.h> 3001e04c3fSmrg 3101e04c3fSmrg/** A red-black tree node 3201e04c3fSmrg * 3301e04c3fSmrg * This struct represents a node in the red-black tree. This struct should 3401e04c3fSmrg * be embedded as a member in whatever structure you wish to put in the 3501e04c3fSmrg * tree. 3601e04c3fSmrg */ 3701e04c3fSmrgstruct rb_node { 3801e04c3fSmrg /** Parent and color of this node 3901e04c3fSmrg * 4001e04c3fSmrg * The least significant bit represents the color and is est to 1 for 4101e04c3fSmrg * black and 0 for red. The other bits are the pointer to the parent 4201e04c3fSmrg * and that pointer can be retrieved by masking off the bottom bit and 4301e04c3fSmrg * casting to a pointer. 4401e04c3fSmrg */ 4501e04c3fSmrg uintptr_t parent; 4601e04c3fSmrg 4701e04c3fSmrg /** Left child of this node, null for a leaf */ 4801e04c3fSmrg struct rb_node *left; 4901e04c3fSmrg 5001e04c3fSmrg /** Right child of this node, null for a leaf */ 5101e04c3fSmrg struct rb_node *right; 5201e04c3fSmrg}; 5301e04c3fSmrg 5401e04c3fSmrg/** Return the parent node of the given node or NULL if it is the root */ 5501e04c3fSmrgstatic inline struct rb_node * 5601e04c3fSmrgrb_node_parent(struct rb_node *n) 5701e04c3fSmrg{ 5801e04c3fSmrg return (struct rb_node *)(n->parent & ~(uintptr_t)1); 5901e04c3fSmrg} 6001e04c3fSmrg 6101e04c3fSmrg/** A red-black tree 6201e04c3fSmrg * 6301e04c3fSmrg * This struct represents the red-black tree itself. It is just a pointer 6401e04c3fSmrg * to the root node with no other metadata. 6501e04c3fSmrg */ 6601e04c3fSmrgstruct rb_tree { 6701e04c3fSmrg struct rb_node *root; 6801e04c3fSmrg}; 6901e04c3fSmrg 7001e04c3fSmrg/** Initialize a red-black tree */ 7101e04c3fSmrgvoid rb_tree_init(struct rb_tree *T); 7201e04c3fSmrg 7301e04c3fSmrg/** Returns true if the red-black tree is empty */ 7401e04c3fSmrgstatic inline bool 7501e04c3fSmrgrb_tree_is_empty(const struct rb_tree *T) 7601e04c3fSmrg{ 7701e04c3fSmrg return T->root == NULL; 7801e04c3fSmrg} 7901e04c3fSmrg 8001e04c3fSmrg/** Retrieve the data structure containing a node 8101e04c3fSmrg * 8201e04c3fSmrg * \param type The type of the containing data structure 8301e04c3fSmrg * 8401e04c3fSmrg * \param node A pointer to a rb_node 8501e04c3fSmrg * 8601e04c3fSmrg * \param field The rb_node field in the containing data structure 8701e04c3fSmrg */ 8801e04c3fSmrg#define rb_node_data(type, node, field) \ 8901e04c3fSmrg ((type *)(((char *)(node)) - offsetof(type, field))) 9001e04c3fSmrg 9101e04c3fSmrg/** Insert a node into a tree at a particular location 9201e04c3fSmrg * 9301e04c3fSmrg * This function should probably not be used directly as it relies on the 9401e04c3fSmrg * caller to ensure that the parent node is correct. Use rb_tree_insert 9501e04c3fSmrg * instead. 9601e04c3fSmrg * 9701e04c3fSmrg * \param T The red-black tree into which to insert the new node 9801e04c3fSmrg * 9901e04c3fSmrg * \param parent The node in the tree that will be the parent of the 10001e04c3fSmrg * newly inserted node 10101e04c3fSmrg * 10201e04c3fSmrg * \param node The node to insert 10301e04c3fSmrg * 10401e04c3fSmrg * \param insert_left If true, the new node will be the left child of 10501e04c3fSmrg * \p parent, otherwise it will be the right child 10601e04c3fSmrg */ 10701e04c3fSmrgvoid rb_tree_insert_at(struct rb_tree *T, struct rb_node *parent, 10801e04c3fSmrg struct rb_node *node, bool insert_left); 10901e04c3fSmrg 11001e04c3fSmrg/** Insert a node into a tree 11101e04c3fSmrg * 11201e04c3fSmrg * \param T The red-black tree into which to insert the new node 11301e04c3fSmrg * 11401e04c3fSmrg * \param node The node to insert 11501e04c3fSmrg * 11601e04c3fSmrg * \param cmp A comparison function to use to order the nodes. 11701e04c3fSmrg */ 11801e04c3fSmrgstatic inline void 11901e04c3fSmrgrb_tree_insert(struct rb_tree *T, struct rb_node *node, 12001e04c3fSmrg int (*cmp)(const struct rb_node *, const struct rb_node *)) 12101e04c3fSmrg{ 12201e04c3fSmrg /* This function is declared inline in the hopes that the compiler can 12301e04c3fSmrg * optimize away the comparison function pointer call. 12401e04c3fSmrg */ 12501e04c3fSmrg struct rb_node *y = NULL; 12601e04c3fSmrg struct rb_node *x = T->root; 12701e04c3fSmrg bool left = false; 12801e04c3fSmrg while (x != NULL) { 12901e04c3fSmrg y = x; 1307ec681f3Smrg left = cmp(x, node) < 0; 13101e04c3fSmrg if (left) 13201e04c3fSmrg x = x->left; 13301e04c3fSmrg else 13401e04c3fSmrg x = x->right; 13501e04c3fSmrg } 13601e04c3fSmrg 13701e04c3fSmrg rb_tree_insert_at(T, y, node, left); 13801e04c3fSmrg} 13901e04c3fSmrg 14001e04c3fSmrg/** Remove a node from a tree 14101e04c3fSmrg * 14201e04c3fSmrg * \param T The red-black tree from which to remove the node 14301e04c3fSmrg * 14401e04c3fSmrg * \param node The node to remove 14501e04c3fSmrg */ 14601e04c3fSmrgvoid rb_tree_remove(struct rb_tree *T, struct rb_node *z); 14701e04c3fSmrg 14801e04c3fSmrg/** Search the tree for a node 14901e04c3fSmrg * 15001e04c3fSmrg * If a node with a matching key exists, the first matching node found will 15101e04c3fSmrg * be returned. If no matching node exists, NULL is returned. 15201e04c3fSmrg * 15301e04c3fSmrg * \param T The red-black tree to search 15401e04c3fSmrg * 15501e04c3fSmrg * \param key The key to search for 15601e04c3fSmrg * 15701e04c3fSmrg * \param cmp A comparison function to use to order the nodes 15801e04c3fSmrg */ 15901e04c3fSmrgstatic inline struct rb_node * 16001e04c3fSmrgrb_tree_search(struct rb_tree *T, const void *key, 16101e04c3fSmrg int (*cmp)(const struct rb_node *, const void *)) 16201e04c3fSmrg{ 16301e04c3fSmrg /* This function is declared inline in the hopes that the compiler can 16401e04c3fSmrg * optimize away the comparison function pointer call. 16501e04c3fSmrg */ 16601e04c3fSmrg struct rb_node *x = T->root; 16701e04c3fSmrg while (x != NULL) { 16801e04c3fSmrg int c = cmp(x, key); 16901e04c3fSmrg if (c < 0) 17001e04c3fSmrg x = x->left; 1717ec681f3Smrg else if (c > 0) 1727ec681f3Smrg x = x->right; 17301e04c3fSmrg else 17401e04c3fSmrg return x; 17501e04c3fSmrg } 17601e04c3fSmrg 17701e04c3fSmrg return x; 17801e04c3fSmrg} 17901e04c3fSmrg 18001e04c3fSmrg/** Sloppily search the tree for a node 18101e04c3fSmrg * 18201e04c3fSmrg * This function searches the tree for a given node. If a node with a 18301e04c3fSmrg * matching key exists, that first matching node found will be returned. 18401e04c3fSmrg * If no node with an exactly matching key exists, the node returned will 18501e04c3fSmrg * be either the right-most node comparing less than \p key or the 18601e04c3fSmrg * right-most node comparing greater than \p key. If the tree is empty, 18701e04c3fSmrg * NULL is returned. 18801e04c3fSmrg * 18901e04c3fSmrg * \param T The red-black tree to search 19001e04c3fSmrg * 19101e04c3fSmrg * \param key The key to search for 19201e04c3fSmrg * 19301e04c3fSmrg * \param cmp A comparison function to use to order the nodes 19401e04c3fSmrg */ 19501e04c3fSmrgstatic inline struct rb_node * 19601e04c3fSmrgrb_tree_search_sloppy(struct rb_tree *T, const void *key, 19701e04c3fSmrg int (*cmp)(const struct rb_node *, const void *)) 19801e04c3fSmrg{ 19901e04c3fSmrg /* This function is declared inline in the hopes that the compiler can 20001e04c3fSmrg * optimize away the comparison function pointer call. 20101e04c3fSmrg */ 20201e04c3fSmrg struct rb_node *y = NULL; 20301e04c3fSmrg struct rb_node *x = T->root; 20401e04c3fSmrg while (x != NULL) { 20501e04c3fSmrg y = x; 20601e04c3fSmrg int c = cmp(x, key); 20701e04c3fSmrg if (c < 0) 20801e04c3fSmrg x = x->left; 2097ec681f3Smrg else if (c > 0) 2107ec681f3Smrg x = x->right; 21101e04c3fSmrg else 21201e04c3fSmrg return x; 21301e04c3fSmrg } 21401e04c3fSmrg 21501e04c3fSmrg return y; 21601e04c3fSmrg} 21701e04c3fSmrg 21801e04c3fSmrg/** Get the first (left-most) node in the tree or NULL */ 21901e04c3fSmrgstruct rb_node *rb_tree_first(struct rb_tree *T); 22001e04c3fSmrg 22101e04c3fSmrg/** Get the last (right-most) node in the tree or NULL */ 22201e04c3fSmrgstruct rb_node *rb_tree_last(struct rb_tree *T); 22301e04c3fSmrg 22401e04c3fSmrg/** Get the next node (to the right) in the tree or NULL */ 22501e04c3fSmrgstruct rb_node *rb_node_next(struct rb_node *node); 22601e04c3fSmrg 22701e04c3fSmrg/** Get the next previous (to the left) in the tree or NULL */ 22801e04c3fSmrgstruct rb_node *rb_node_prev(struct rb_node *node); 22901e04c3fSmrg 2307ec681f3Smrg#define rb_node_next_or_null(n) ((n) == NULL ? NULL : rb_node_next(n)) 2317ec681f3Smrg#define rb_node_prev_or_null(n) ((n) == NULL ? NULL : rb_node_prev(n)) 23201e04c3fSmrg 23301e04c3fSmrg/** Iterate over the nodes in the tree 23401e04c3fSmrg * 23501e04c3fSmrg * \param type The type of the containing data structure 23601e04c3fSmrg * 23701e04c3fSmrg * \param node The variable name for current node in the iteration; 23801e04c3fSmrg * this will be declared as a pointer to \p type 23901e04c3fSmrg * 24001e04c3fSmrg * \param T The red-black tree 24101e04c3fSmrg * 24201e04c3fSmrg * \param field The rb_node field in containing data structure 24301e04c3fSmrg */ 2447ec681f3Smrg#define rb_tree_foreach(type, iter, T, field) \ 2457ec681f3Smrg for (type *iter, *__node = (type *)rb_tree_first(T); \ 2467ec681f3Smrg __node != NULL && \ 2477ec681f3Smrg (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 2487ec681f3Smrg __node = (type *)rb_node_next((struct rb_node *)__node)) 24901e04c3fSmrg 25001e04c3fSmrg/** Iterate over the nodes in the tree, allowing the current node to be freed 25101e04c3fSmrg * 25201e04c3fSmrg * \param type The type of the containing data structure 25301e04c3fSmrg * 25401e04c3fSmrg * \param node The variable name for current node in the iteration; 25501e04c3fSmrg * this will be declared as a pointer to \p type 25601e04c3fSmrg * 25701e04c3fSmrg * \param T The red-black tree 25801e04c3fSmrg * 25901e04c3fSmrg * \param field The rb_node field in containing data structure 26001e04c3fSmrg */ 2617ec681f3Smrg#define rb_tree_foreach_safe(type, iter, T, field) \ 2627ec681f3Smrg for (type *iter, \ 2637ec681f3Smrg *__node = (type *)rb_tree_first(T), \ 2647ec681f3Smrg *__next = (type *)rb_node_next_or_null((struct rb_node *)__node); \ 2657ec681f3Smrg __node != NULL && \ 2667ec681f3Smrg (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 2677ec681f3Smrg __node = __next, \ 2687ec681f3Smrg __next = (type *)rb_node_next_or_null((struct rb_node *)__node)) 26901e04c3fSmrg 27001e04c3fSmrg/** Iterate over the nodes in the tree in reverse 27101e04c3fSmrg * 27201e04c3fSmrg * \param type The type of the containing data structure 27301e04c3fSmrg * 27401e04c3fSmrg * \param node The variable name for current node in the iteration; 27501e04c3fSmrg * this will be declared as a pointer to \p type 27601e04c3fSmrg * 27701e04c3fSmrg * \param T The red-black tree 27801e04c3fSmrg * 27901e04c3fSmrg * \param field The rb_node field in containing data structure 28001e04c3fSmrg */ 2817ec681f3Smrg#define rb_tree_foreach_rev(type, iter, T, field) \ 2827ec681f3Smrg for (type *iter, *__node = (type *)rb_tree_last(T); \ 2837ec681f3Smrg __node != NULL && \ 2847ec681f3Smrg (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 2857ec681f3Smrg __node = (type *)rb_node_prev((struct rb_node *)__node)) 28601e04c3fSmrg 28701e04c3fSmrg/** Iterate over the nodes in the tree in reverse, allowing the current node to be freed 28801e04c3fSmrg * 28901e04c3fSmrg * \param type The type of the containing data structure 29001e04c3fSmrg * 29101e04c3fSmrg * \param node The variable name for current node in the iteration; 29201e04c3fSmrg * this will be declared as a pointer to \p type 29301e04c3fSmrg * 29401e04c3fSmrg * \param T The red-black tree 29501e04c3fSmrg * 29601e04c3fSmrg * \param field The rb_node field in containing data structure 29701e04c3fSmrg */ 2987ec681f3Smrg#define rb_tree_foreach_rev_safe(type, iter, T, field) \ 2997ec681f3Smrg for (type *iter, \ 3007ec681f3Smrg *__node = (type *)rb_tree_last(T), \ 3017ec681f3Smrg *__prev = (type *)rb_node_prev_or_null((struct rb_node *)__node); \ 3027ec681f3Smrg __node != NULL && \ 3037ec681f3Smrg (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ 3047ec681f3Smrg __node = __prev, \ 3057ec681f3Smrg __prev = (type *)rb_node_prev_or_null((struct rb_node *)__node)) 30601e04c3fSmrg 30701e04c3fSmrg/** Validate a red-black tree 30801e04c3fSmrg * 30901e04c3fSmrg * This function walks the tree and validates that this is a valid red- 31001e04c3fSmrg * black tree. If anything is wrong, it will assert-fail. 31101e04c3fSmrg */ 31201e04c3fSmrgvoid rb_tree_validate(struct rb_tree *T); 31301e04c3fSmrg 31401e04c3fSmrg#endif /* RB_TREE_H */ 315