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