summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_rbtree.h
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
committerIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
commit16cbf3c076a0aca6d47adaf3f719493674cf2363 (patch)
treee6530480020f62a2bdbf249988ec3e2a751d3927 /src/nxt_rbtree.h
downloadunit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz
unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2
Initial version.
Diffstat (limited to 'src/nxt_rbtree.h')
-rw-r--r--src/nxt_rbtree.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/nxt_rbtree.h b/src/nxt_rbtree.h
new file mode 100644
index 00000000..63b759fb
--- /dev/null
+++ b/src/nxt_rbtree.h
@@ -0,0 +1,120 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) NGINX, Inc.
+ */
+
+#ifndef _NXT_RBTREE_H_INCLUDED_
+#define _NXT_RBTREE_H_INCLUDED_
+
+
+typedef struct nxt_rbtree_node_s nxt_rbtree_node_t;
+
+struct nxt_rbtree_node_s {
+ nxt_rbtree_node_t *left;
+ nxt_rbtree_node_t *right;
+ nxt_rbtree_node_t *parent;
+
+ uint8_t color;
+ uint8_t spare;
+};
+
+
+typedef struct {
+ nxt_rbtree_node_t *left;
+ nxt_rbtree_node_t *right;
+ nxt_rbtree_node_t *parent;
+} nxt_rbtree_part_t;
+
+
+#define NXT_RBTREE_NODE(node) \
+ nxt_rbtree_part_t node; \
+ uint8_t color
+
+
+#define NXT_RBTREE_NODE_INIT { NULL, NULL, NULL }, 0
+
+
+typedef struct {
+ nxt_rbtree_node_t sentinel;
+} nxt_rbtree_t;
+
+
+typedef void (*nxt_rbtree_insert_t)(nxt_rbtree_node_t *root,
+ nxt_rbtree_node_t *node, nxt_rbtree_node_t *sentinel);
+
+typedef nxt_int_t (*nxt_rbtree_compare_t)(nxt_rbtree_node_t *node1,
+ nxt_rbtree_node_t *node2);
+
+
+#define \
+nxt_rbtree_root(tree) \
+ ((tree)->sentinel.left)
+
+
+#define nxt_rbtree_sentinel(tree) \
+ (&(tree)->sentinel)
+
+
+#define nxt_rbtree_is_empty(tree) \
+ (nxt_rbtree_root(tree) == nxt_rbtree_sentinel(tree))
+
+
+#define nxt_rbtree_min(tree) \
+ nxt_rbtree_branch_min(tree, &(tree)->sentinel)
+
+
+nxt_inline nxt_rbtree_node_t *
+nxt_rbtree_branch_min(nxt_rbtree_t *tree, nxt_rbtree_node_t *node)
+{
+ while (node->left != nxt_rbtree_sentinel(tree)) {
+ node = node->left;
+ }
+
+ return node;
+}
+
+
+#define nxt_rbtree_is_there_successor(tree, node) \
+ ((node) != nxt_rbtree_sentinel(tree))
+
+
+nxt_inline nxt_rbtree_node_t *
+nxt_rbtree_node_successor(nxt_rbtree_t *tree, nxt_rbtree_node_t *node)
+{
+ nxt_rbtree_node_t *parent;
+
+ if (node->right != nxt_rbtree_sentinel(tree)) {
+ return nxt_rbtree_branch_min(tree, node->right);
+ }
+
+ for ( ;; ) {
+ parent = node->parent;
+
+ /*
+ * Explicit test for a root node is not required here, because
+ * the root node is always the left child of the sentinel.
+ */
+ if (node == parent->left) {
+ return parent;
+ }
+
+ node = parent;
+ }
+}
+
+
+NXT_EXPORT void nxt_rbtree_init(nxt_rbtree_t *tree,
+ nxt_rbtree_compare_t compare, nxt_rbtree_insert_t insert);
+NXT_EXPORT void nxt_rbtree_insert(nxt_rbtree_t *tree, nxt_rbtree_part_t *node);
+NXT_EXPORT nxt_rbtree_node_t *nxt_rbtree_find(nxt_rbtree_t *tree,
+ nxt_rbtree_part_t *node);
+NXT_EXPORT nxt_rbtree_node_t *nxt_rbtree_find_less_or_equal(nxt_rbtree_t *tree,
+ nxt_rbtree_part_t *node);
+NXT_EXPORT nxt_rbtree_node_t *
+ nxt_rbtree_find_greater_or_equal(nxt_rbtree_t *tree,
+ nxt_rbtree_part_t *node);
+NXT_EXPORT void nxt_rbtree_delete(nxt_rbtree_t *tree, nxt_rbtree_part_t *node);
+
+
+#endif /* _NXT_RBTREE_H_INCLUDED_ */