summaryrefslogtreecommitdiff
path: root/debian/patches/0010-librbtree-add-a-red-black-tree-implementation.patch
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-05-22 08:23:16 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-05-22 08:23:16 +0200
commit78acdaa8fc996dbf70d23d69aea9f81499290c26 (patch)
tree9013f4a1894213f748a6e31a18a0340d6ee3fefc /debian/patches/0010-librbtree-add-a-red-black-tree-implementation.patch
parentbd64a35db772d27e33b6cb1b50446b865b1c837e (diff)
add patch series
Diffstat (limited to 'debian/patches/0010-librbtree-add-a-red-black-tree-implementation.patch')
-rw-r--r--debian/patches/0010-librbtree-add-a-red-black-tree-implementation.patch1181
1 files changed, 1181 insertions, 0 deletions
diff --git a/debian/patches/0010-librbtree-add-a-red-black-tree-implementation.patch b/debian/patches/0010-librbtree-add-a-red-black-tree-implementation.patch
new file mode 100644
index 00000000..b34df7bb
--- /dev/null
+++ b/debian/patches/0010-librbtree-add-a-red-black-tree-implementation.patch
@@ -0,0 +1,1181 @@
+From 07e6865e754ab651465651c5d9bff7d5c504b447 Mon Sep 17 00:00:00 2001
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Fri, 16 May 2014 20:21:48 +0200
+Subject: [PATCH 10/27] librbtree: add a red-black tree implementation
+
+Red-black trees offer search, insert, and delete operations with worst
+case runtime in O(log n). They are also very space efficient.
+
+This is an verbatim copy from git://git.sceen.net/rbraun/librbraun.git
+as of 45fef4ad. Only macros.h has been slightly amended. This file
+defines two macros, which are also defined in cthreads.h. Undefine
+the macros first to work around this problem.
+
+* librbtree/Makefile: New file.
+* librbtree/rbtree.c: Likewise.
+* librbtree/rbtree.h: Likewise.
+* librbtree/rbtree_i.h: Likewise.
+* librbtree/macros.h: Likewise. Also, undefine MACRO_{BEGIN,END}.
+* Makefile (lib-subdirs): Add librbtree.
+---
+ Makefile | 3 +
+ librbtree/Makefile | 27 +++
+ librbtree/macros.h | 70 ++++++++
+ librbtree/rbtree.c | 498 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ librbtree/rbtree.h | 310 ++++++++++++++++++++++++++++++++
+ librbtree/rbtree_i.h | 196 ++++++++++++++++++++
+ 6 files changed, 1104 insertions(+)
+ create mode 100644 librbtree/Makefile
+ create mode 100644 librbtree/macros.h
+ create mode 100644 librbtree/rbtree.c
+ create mode 100644 librbtree/rbtree.h
+ create mode 100644 librbtree/rbtree_i.h
+
+diff --git a/Makefile b/Makefile
+index 106f2f6..8a0be83 100644
+--- a/Makefile
++++ b/Makefile
+@@ -46,6 +46,9 @@ endif
+ # Other directories
+ other-subdirs = hurd doc config release include
+
++# XXX
++lib-subdirs += librbtree
++
+ # All the subdirectories together
+ subdirs = $(lib-subdirs) $(prog-subdirs) $(other-subdirs)
+
+diff --git a/librbtree/Makefile b/librbtree/Makefile
+new file mode 100644
+index 0000000..0f33358
+--- /dev/null
++++ b/librbtree/Makefile
+@@ -0,0 +1,27 @@
++# Copyright (C) 2014 Free Software Foundation, Inc.
++#
++# This file is part of the GNU Hurd.
++#
++# The GNU Hurd is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public License as
++# published by the Free Software Foundation; either version 2, or (at
++# your option) any later version.
++#
++# The GNU Hurd is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.
++
++dir := librbtree
++makemode := library
++
++libname := librbtree
++SRCS = rbtree.c
++installhdrs = rbtree.h rbtree_i.h macros.h
++
++OBJS = $(SRCS:.c=.o)
++
++include ../Makeconf
+diff --git a/librbtree/macros.h b/librbtree/macros.h
+new file mode 100644
+index 0000000..f0960a3
+--- /dev/null
++++ b/librbtree/macros.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2009, 2010 Richard Braun.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *
++ * Helper macros.
++ */
++
++#ifndef _MACROS_H
++#define _MACROS_H
++
++#include <stddef.h>
++
++#undef MACRO_BEGIN
++#undef MACRO_END
++#define MACRO_BEGIN ({
++#define MACRO_END })
++
++#define XQUOTE(x) #x
++#define QUOTE(x) XQUOTE(x)
++
++#define STRLEN(x) (sizeof(x) - 1)
++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
++
++#define MIN(a, b) ((a) < (b) ? (a) : (b))
++#define MAX(a, b) ((a) > (b) ? (a) : (b))
++
++#define P2ALIGNED(x, a) (((x) & ((a) - 1)) == 0)
++#define ISP2(x) P2ALIGNED(x, x)
++#define P2ALIGN(x, a) ((x) & -(a))
++#define P2ROUND(x, a) (-(-(x) & -(a)))
++#define P2END(x, a) (-(~(x) & -(a)))
++
++#define structof(ptr, type, member) \
++ ((type *)((char *)(ptr) - offsetof(type, member)))
++
++#define alignof(x) __alignof__(x)
++
++#define likely(expr) __builtin_expect(!!(expr), 1)
++#define unlikely(expr) __builtin_expect(!!(expr), 0)
++
++#define barrier() asm volatile("" : : : "memory")
++
++#define __noreturn __attribute__((noreturn))
++#define __aligned(x) __attribute__((aligned(x)))
++
++#define __format_printf(fmt, args) \
++ __attribute__((format(printf, fmt, args)))
++
++#endif /* _MACROS_H */
+diff --git a/librbtree/rbtree.c b/librbtree/rbtree.c
+new file mode 100644
+index 0000000..969a18d
+--- /dev/null
++++ b/librbtree/rbtree.c
+@@ -0,0 +1,498 @@
++/*
++ * Copyright (c) 2010, 2012 Richard Braun.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <assert.h>
++#include <stddef.h>
++
++#include "macros.h"
++#include "rbtree.h"
++#include "rbtree_i.h"
++
++/*
++ * Return the index of a node in the children array of its parent.
++ *
++ * The parent parameter must not be NULL, and must be the parent of the
++ * given node.
++ */
++static inline int
++rbtree_node_index(const struct rbtree_node *node,
++ const struct rbtree_node *parent)
++{
++ assert(parent != NULL);
++ assert((node == NULL) || (rbtree_node_parent(node) == parent));
++
++ if (parent->children[RBTREE_LEFT] == node)
++ return RBTREE_LEFT;
++
++ assert(parent->children[RBTREE_RIGHT] == node);
++
++ return RBTREE_RIGHT;
++}
++
++/*
++ * Return the color of a node.
++ */
++static inline int
++rbtree_node_color(const struct rbtree_node *node)
++{
++ return node->parent & RBTREE_COLOR_MASK;
++}
++
++/*
++ * Return true if the node is red.
++ */
++static inline int
++rbtree_node_is_red(const struct rbtree_node *node)
++{
++ return rbtree_node_color(node) == RBTREE_COLOR_RED;
++}
++
++/*
++ * Return true if the node is black.
++ */
++static inline int
++rbtree_node_is_black(const struct rbtree_node *node)
++{
++ return rbtree_node_color(node) == RBTREE_COLOR_BLACK;
++}
++
++/*
++ * Set the parent of a node, retaining its current color.
++ */
++static inline void
++rbtree_node_set_parent(struct rbtree_node *node, struct rbtree_node *parent)
++{
++ assert(rbtree_node_check_alignment(node));
++ assert(rbtree_node_check_alignment(parent));
++
++ node->parent = (unsigned long)parent | (node->parent & RBTREE_COLOR_MASK);
++}
++
++/*
++ * Set the color of a node, retaining its current parent.
++ */
++static inline void
++rbtree_node_set_color(struct rbtree_node *node, int color)
++{
++ assert((color & ~RBTREE_COLOR_MASK) == 0);
++ node->parent = (node->parent & RBTREE_PARENT_MASK) | color;
++}
++
++/*
++ * Set the color of a node to red, retaining its current parent.
++ */
++static inline void
++rbtree_node_set_red(struct rbtree_node *node)
++{
++ rbtree_node_set_color(node, RBTREE_COLOR_RED);
++}
++
++/*
++ * Set the color of a node to black, retaining its current parent.
++ */
++static inline void
++rbtree_node_set_black(struct rbtree_node *node)
++{
++ rbtree_node_set_color(node, RBTREE_COLOR_BLACK);
++}
++
++/*
++ * Return the left-most deepest child node of the given node.
++ */
++static struct rbtree_node *
++rbtree_node_find_deepest(struct rbtree_node *node)
++{
++ struct rbtree_node *parent;
++
++ assert(node != NULL);
++
++ for (;;) {
++ parent = node;
++ node = node->children[RBTREE_LEFT];
++
++ if (node == NULL) {
++ node = parent->children[RBTREE_RIGHT];
++
++ if (node == NULL)
++ return parent;
++ }
++ }
++}
++
++/*
++ * Perform a tree rotation, rooted at the given node.
++ *
++ * The direction parameter defines the rotation direction and is either
++ * RBTREE_LEFT or RBTREE_RIGHT.
++ */
++static void
++rbtree_rotate(struct rbtree *tree, struct rbtree_node *node, int direction)
++{
++ struct rbtree_node *parent, *rnode;
++ int left, right;
++
++ left = direction;
++ right = 1 - left;
++ parent = rbtree_node_parent(node);
++ rnode = node->children[right];
++
++ node->children[right] = rnode->children[left];
++
++ if (rnode->children[left] != NULL)
++ rbtree_node_set_parent(rnode->children[left], node);
++
++ rnode->children[left] = node;
++ rbtree_node_set_parent(rnode, parent);
++
++ if (unlikely(parent == NULL))
++ tree->root = rnode;
++ else
++ parent->children[rbtree_node_index(node, parent)] = rnode;
++
++ rbtree_node_set_parent(node, rnode);
++}
++
++void
++rbtree_insert_rebalance(struct rbtree *tree, struct rbtree_node *parent,
++ int index, struct rbtree_node *node)
++{
++ struct rbtree_node *grand_parent, *uncle, *tmp;
++ int left, right;
++
++ assert(rbtree_node_check_alignment(parent));
++ assert(rbtree_node_check_alignment(node));
++
++ node->parent = (unsigned long)parent | RBTREE_COLOR_RED;
++ node->children[RBTREE_LEFT] = NULL;
++ node->children[RBTREE_RIGHT] = NULL;
++
++ if (unlikely(parent == NULL))
++ tree->root = node;
++ else
++ parent->children[index] = node;
++
++ for (;;) {
++ if (parent == NULL) {
++ rbtree_node_set_black(node);
++ break;
++ }
++
++ if (rbtree_node_is_black(parent))
++ break;
++
++ grand_parent = rbtree_node_parent(parent);
++ assert(grand_parent != NULL);
++
++ left = rbtree_node_index(parent, grand_parent);
++ right = 1 - left;
++
++ uncle = grand_parent->children[right];
++
++ /*
++ * Uncle is red. Flip colors and repeat at grand parent.
++ */
++ if ((uncle != NULL) && rbtree_node_is_red(uncle)) {
++ rbtree_node_set_black(uncle);
++ rbtree_node_set_black(parent);
++ rbtree_node_set_red(grand_parent);
++ node = grand_parent;
++ parent = rbtree_node_parent(node);
++ continue;
++ }
++
++ /*
++ * Node is the right child of its parent. Rotate left at parent.
++ */
++ if (parent->children[right] == node) {
++ rbtree_rotate(tree, parent, left);
++ tmp = node;
++ node = parent;
++ parent = tmp;
++ }
++
++ /*
++ * Node is the left child of its parent. Handle colors, rotate right
++ * at grand parent, and leave.
++ */
++ rbtree_node_set_black(parent);
++ rbtree_node_set_red(grand_parent);
++ rbtree_rotate(tree, grand_parent, right);
++ break;
++ }
++
++ assert(rbtree_node_is_black(tree->root));
++}
++
++void
++rbtree_remove(struct rbtree *tree, struct rbtree_node *node)
++{
++ struct rbtree_node *child, *parent, *brother;
++ int color, left, right;
++
++ if (node->children[RBTREE_LEFT] == NULL)
++ child = node->children[RBTREE_RIGHT];
++ else if (node->children[RBTREE_RIGHT] == NULL)
++ child = node->children[RBTREE_LEFT];
++ else {
++ struct rbtree_node *successor;
++
++ /*
++ * Two-children case: replace the node with its successor.
++ */
++
++ successor = node->children[RBTREE_RIGHT];
++
++ while (successor->children[RBTREE_LEFT] != NULL)
++ successor = successor->children[RBTREE_LEFT];
++
++ color = rbtree_node_color(successor);
++ child = successor->children[RBTREE_RIGHT];
++ parent = rbtree_node_parent(node);
++
++ if (unlikely(parent == NULL))
++ tree->root = successor;
++ else
++ parent->children[rbtree_node_index(node, parent)] = successor;
++
++ parent = rbtree_node_parent(successor);
++
++ /*
++ * Set parent directly to keep the original color.
++ */
++ successor->parent = node->parent;
++ successor->children[RBTREE_LEFT] = node->children[RBTREE_LEFT];
++ rbtree_node_set_parent(successor->children[RBTREE_LEFT], successor);
++
++ if (node == parent)
++ parent = successor;
++ else {
++ successor->children[RBTREE_RIGHT] = node->children[RBTREE_RIGHT];
++ rbtree_node_set_parent(successor->children[RBTREE_RIGHT],
++ successor);
++ parent->children[RBTREE_LEFT] = child;
++
++ if (child != NULL)
++ rbtree_node_set_parent(child, parent);
++ }
++
++ goto update_color;
++ }
++
++ /*
++ * Node has at most one child.
++ */
++
++ color = rbtree_node_color(node);
++ parent = rbtree_node_parent(node);
++
++ if (child != NULL)
++ rbtree_node_set_parent(child, parent);
++
++ if (unlikely(parent == NULL))
++ tree->root = child;
++ else
++ parent->children[rbtree_node_index(node, parent)] = child;
++
++ /*
++ * The node has been removed, update the colors. The child pointer can
++ * be NULL, in which case it is considered a black leaf.
++ */
++update_color:
++ if (color == RBTREE_COLOR_RED)
++ return;
++
++ for (;;) {
++ if ((child != NULL) && rbtree_node_is_red(child)) {
++ rbtree_node_set_black(child);
++ break;
++ }
++
++ if (parent == NULL)
++ break;
++
++ left = rbtree_node_index(child, parent);
++ right = 1 - left;
++
++ brother = parent->children[right];
++
++ /*
++ * Brother is red. Recolor and rotate left at parent so that brother
++ * becomes black.
++ */
++ if (rbtree_node_is_red(brother)) {
++ rbtree_node_set_black(brother);
++ rbtree_node_set_red(parent);
++ rbtree_rotate(tree, parent, left);
++ brother = parent->children[right];
++ }
++
++ /*
++ * Brother has no red child. Recolor and repeat at parent.
++ */
++ if (((brother->children[RBTREE_LEFT] == NULL)
++ || rbtree_node_is_black(brother->children[RBTREE_LEFT]))
++ && ((brother->children[RBTREE_RIGHT] == NULL)
++ || rbtree_node_is_black(brother->children[RBTREE_RIGHT]))) {
++ rbtree_node_set_red(brother);
++ child = parent;
++ parent = rbtree_node_parent(child);
++ continue;
++ }
++
++ /*
++ * Brother's right child is black. Recolor and rotate right at brother.
++ */
++ if ((brother->children[right] == NULL)
++ || rbtree_node_is_black(brother->children[right])) {
++ rbtree_node_set_black(brother->children[left]);
++ rbtree_node_set_red(brother);
++ rbtree_rotate(tree, brother, right);
++ brother = parent->children[right];
++ }
++
++ /*
++ * Brother's left child is black. Exchange parent and brother colors
++ * (we already know brother is black), set brother's right child black,
++ * rotate left at parent and leave.
++ */
++ rbtree_node_set_color(brother, rbtree_node_color(parent));
++ rbtree_node_set_black(parent);
++ rbtree_node_set_black(brother->children[right]);
++ rbtree_rotate(tree, parent, left);
++ break;
++ }
++
++ assert((tree->root == NULL) || rbtree_node_is_black(tree->root));
++}
++
++struct rbtree_node *
++rbtree_nearest(struct rbtree_node *parent, int index, int direction)
++{
++ assert(rbtree_check_index(direction));
++
++ if (parent == NULL)
++ return NULL;
++
++ assert(rbtree_check_index(index));
++
++ if (index != direction)
++ return parent;
++
++ return rbtree_walk(parent, direction);
++}
++
++struct rbtree_node *
++rbtree_firstlast(const struct rbtree *tree, int direction)
++{
++ struct rbtree_node *prev, *cur;
++
++ assert(rbtree_check_index(direction));
++
++ prev = NULL;
++
++ for (cur = tree->root; cur != NULL; cur = cur->children[direction])
++ prev = cur;
++
++ return prev;
++}
++
++struct rbtree_node *
++rbtree_walk(struct rbtree_node *node, int direction)
++{
++ int left, right;
++
++ assert(rbtree_check_index(direction));
++
++ left = direction;
++ right = 1 - left;
++
++ if (node == NULL)
++ return NULL;
++
++ if (node->children[left] != NULL) {
++ node = node->children[left];
++
++ while (node->children[right] != NULL)
++ node = node->children[right];
++ } else {
++ struct rbtree_node *parent;
++ int index;
++
++ for (;;) {
++ parent = rbtree_node_parent(node);
++
++ if (parent == NULL)
++ return NULL;
++
++ index = rbtree_node_index(node, parent);
++ node = parent;
++
++ if (index == right)
++ break;
++ }
++ }
++
++ return node;
++}
++
++struct rbtree_node *
++rbtree_postwalk_deepest(const struct rbtree *tree)
++{
++ struct rbtree_node *node;
++
++ node = tree->root;
++
++ if (node == NULL)
++ return NULL;
++
++ return rbtree_node_find_deepest(node);
++}
++
++struct rbtree_node *
++rbtree_postwalk_unlink(struct rbtree_node *node)
++{
++ struct rbtree_node *parent;
++ int index;
++
++ if (node == NULL)
++ return NULL;
++
++ assert(node->children[RBTREE_LEFT] == NULL);
++ assert(node->children[RBTREE_RIGHT] == NULL);
++
++ parent = rbtree_node_parent(node);
++
++ if (parent == NULL)
++ return NULL;
++
++ index = rbtree_node_index(node, parent);
++ parent->children[index] = NULL;
++ node = parent->children[RBTREE_RIGHT];
++
++ if (node == NULL)
++ return parent;
++
++ return rbtree_node_find_deepest(node);
++}
+diff --git a/librbtree/rbtree.h b/librbtree/rbtree.h
+new file mode 100644
+index 0000000..cbb519e
+--- /dev/null
++++ b/librbtree/rbtree.h
+@@ -0,0 +1,310 @@
++/*
++ * Copyright (c) 2010, 2011, 2012 Richard Braun.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *
++ * Red-black tree.
++ */
++
++#ifndef _RBTREE_H
++#define _RBTREE_H
++
++#include <assert.h>
++#include <stddef.h>
++
++#include "macros.h"
++
++/*
++ * Indexes of the left and right nodes in the children array of a node.
++ */
++#define RBTREE_LEFT 0
++#define RBTREE_RIGHT 1
++
++/*
++ * Red-black node.
++ */
++struct rbtree_node;
++
++/*
++ * Red-black tree.
++ */
++struct rbtree;
++
++/*
++ * Static tree initializer.
++ */
++#define RBTREE_INITIALIZER { NULL }
++
++#include "rbtree_i.h"
++
++/*
++ * Initialize a tree.
++ */
++static inline void
++rbtree_init(struct rbtree *tree)
++{
++ tree->root = NULL;
++}
++
++/*
++ * Initialize a node.
++ *
++ * A node is in no tree when its parent points to itself.
++ */
++static inline void
++rbtree_node_init(struct rbtree_node *node)
++{
++ assert(rbtree_node_check_alignment(node));
++
++ node->parent = (unsigned long)node | RBTREE_COLOR_RED;
++ node->children[RBTREE_LEFT] = NULL;
++ node->children[RBTREE_RIGHT] = NULL;
++}
++
++/*
++ * Return true if node is in no tree.
++ */
++static inline int
++rbtree_node_unlinked(const struct rbtree_node *node)
++{
++ return rbtree_node_parent(node) == node;
++}
++
++/*
++ * Macro that evaluates to the address of the structure containing the
++ * given node based on the given type and member.
++ */
++#define rbtree_entry(node, type, member) structof(node, type, member)
++
++/*
++ * Return true if tree is empty.
++ */
++static inline int
++rbtree_empty(const struct rbtree *tree)
++{
++ return tree->root == NULL;
++}
++
++/*
++ * Look up a node in a tree.
++ *
++ * Note that implementing the lookup algorithm as a macro gives two benefits:
++ * First, it avoids the overhead of a callback function. Next, the type of the
++ * cmp_fn parameter isn't rigid. The only guarantee offered by this
++ * implementation is that the key parameter is the first parameter given to
++ * cmp_fn. This way, users can pass only the value they need for comparison
++ * instead of e.g. allocating a full structure on the stack.
++ *
++ * See rbtree_insert().
++ */
++#define rbtree_lookup(tree, key, cmp_fn) \
++MACRO_BEGIN \
++ struct rbtree_node *___cur; \
++ int ___diff; \
++ \
++ ___cur = (tree)->root; \
++ \
++ while (___cur != NULL) { \
++ ___diff = cmp_fn(key, ___cur); \
++ \
++ if (___diff == 0) \
++ break; \
++ \
++ ___cur = ___cur->children[rbtree_d2i(___diff)]; \
++ } \
++ \
++ ___cur; \
++MACRO_END
++
++/*
++ * Look up a node or one of its nearest nodes in a tree.
++ *
++ * This macro essentially acts as rbtree_lookup() but if no entry matched
++ * the key, an additional step is performed to obtain the next or previous
++ * node, depending on the direction (left or right).
++ *
++ * The constraints that apply to the key parameter are the same as for
++ * rbtree_lookup().
++ */
++#define rbtree_lookup_nearest(tree, key, cmp_fn, dir) \
++MACRO_BEGIN \
++ struct rbtree_node *___cur, *___prev; \
++ int ___diff, ___index; \
++ \
++ ___prev = NULL; \
++ ___index = -1; \
++ ___cur = (tree)->root; \
++ \
++ while (___cur != NULL) { \
++ ___diff = cmp_fn(key, ___cur); \
++ \
++ if (___diff == 0) \
++ break; \
++ \
++ ___prev = ___cur; \
++ ___index = rbtree_d2i(___diff); \
++ ___cur = ___cur->children[___index]; \
++ } \
++ \
++ if (___cur == NULL) \
++ ___cur = rbtree_nearest(___prev, ___index, dir); \
++ \
++ ___cur; \
++MACRO_END
++
++/*
++ * Insert a node in a tree.
++ *
++ * This macro performs a standard lookup to obtain the insertion point of
++ * the given node in the tree (it is assumed that the inserted node never
++ * compares equal to any other entry in the tree) and links the node. It
++ * then checks red-black rules violations, and rebalances the tree if
++ * necessary.
++ *
++ * Unlike rbtree_lookup(), the cmp_fn parameter must compare two complete
++ * entries, so it is suggested to use two different comparison inline
++ * functions, such as myobj_cmp_lookup() and myobj_cmp_insert(). There is no
++ * guarantee about the order of the nodes given to the comparison function.
++ *
++ * See rbtree_lookup().
++ */
++#define rbtree_insert(tree, node, cmp_fn) \
++MACRO_BEGIN \
++ struct rbtree_node *___cur, *___prev; \
++ int ___diff, ___index; \
++ \
++ ___prev = NULL; \
++ ___index = -1; \
++ ___cur = (tree)->root; \
++ \
++ while (___cur != NULL) { \
++ ___diff = cmp_fn(node, ___cur); \
++ assert(___diff != 0); \
++ ___prev = ___cur; \
++ ___index = rbtree_d2i(___diff); \
++ ___cur = ___cur->children[___index]; \
++ } \
++ \
++ rbtree_insert_rebalance(tree, ___prev, ___index, node); \
++MACRO_END
++
++/*
++ * Look up a node/slot pair in a tree.
++ *
++ * This macro essentially acts as rbtree_lookup() but in addition to a node,
++ * it also returns a slot, which identifies an insertion point in the tree.
++ * If the returned node is NULL, the slot can be used by rbtree_insert_slot()
++ * to insert without the overhead of an additional lookup. The slot is a
++ * simple unsigned long integer.
++ *
++ * The constraints that apply to the key parameter are the same as for
++ * rbtree_lookup().
++ */
++#define rbtree_lookup_slot(tree, key, cmp_fn, slot) \
++MACRO_BEGIN \
++ struct rbtree_node *___cur, *___prev; \
++ int ___diff, ___index; \
++ \
++ ___prev = NULL; \
++ ___index = 0; \
++ ___cur = (tree)->root; \
++ \
++ while (___cur != NULL) { \
++ ___diff = cmp_fn(key, ___cur); \
++ \
++ if (___diff == 0) \
++ break; \
++ \
++ ___prev = ___cur; \
++ ___index = rbtree_d2i(___diff); \
++ ___cur = ___cur->children[___index]; \
++ } \
++ \
++ (slot) = rbtree_slot(___prev, ___index); \
++ ___cur; \
++MACRO_END
++
++/*
++ * Insert a node at an insertion point in a tree.
++ *
++ * This macro essentially acts as rbtree_insert() except that it doesn't
++ * obtain the insertion point with a standard lookup. The insertion point
++ * is obtained by calling rbtree_lookup_slot(). In addition, the new node
++ * must not compare equal to an existing node in the tree (i.e. the slot
++ * must denote a NULL node).
++ */
++static inline void
++rbtree_insert_slot(struct rbtree *tree, unsigned long slot,
++ struct rbtree_node *node)
++{
++ struct rbtree_node *parent;
++ int index;
++
++ parent = rbtree_slot_parent(slot);
++ index = rbtree_slot_index(slot);
++ rbtree_insert_rebalance(tree, parent, index, node);
++}
++
++/*
++ * Remove a node from a tree.
++ *
++ * After completion, the node is stale.
++ */
++void rbtree_remove(struct rbtree *tree, struct rbtree_node *node);
++
++/*
++ * Return the first node of a tree.
++ */
++#define rbtree_first(tree) rbtree_firstlast(tree, RBTREE_LEFT)
++
++/*
++ * Return the last node of a tree.
++ */
++#define rbtree_last(tree) rbtree_firstlast(tree, RBTREE_RIGHT)
++
++/*
++ * Return the node previous to the given node.
++ */
++#define rbtree_prev(node) rbtree_walk(node, RBTREE_LEFT)
++
++/*
++ * Return the node next to the given node.
++ */
++#define rbtree_next(node) rbtree_walk(node, RBTREE_RIGHT)
++
++/*
++ * Forge a loop to process all nodes of a tree, removing them when visited.
++ *
++ * This macro can only be used to destroy a tree, so that the resources used
++ * by the entries can be released by the user. It basically removes all nodes
++ * without doing any color checking.
++ *
++ * After completion, all nodes and the tree root member are stale.
++ */
++#define rbtree_for_each_remove(tree, node, tmp) \
++for (node = rbtree_postwalk_deepest(tree), \
++ tmp = rbtree_postwalk_unlink(node); \
++ node != NULL; \
++ node = tmp, tmp = rbtree_postwalk_unlink(node)) \
++
++#endif /* _RBTREE_H */
+diff --git a/librbtree/rbtree_i.h b/librbtree/rbtree_i.h
+new file mode 100644
+index 0000000..eb1619f
+--- /dev/null
++++ b/librbtree/rbtree_i.h
+@@ -0,0 +1,196 @@
++/*
++ * Copyright (c) 2010, 2011, 2012 Richard Braun.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#ifndef _RBTREE_I_H
++#define _RBTREE_I_H
++
++#include <assert.h>
++#include <stddef.h>
++
++#include "macros.h"
++
++/*
++ * Red-black node structure.
++ *
++ * To reduce the number of branches and the instruction cache footprint,
++ * the left and right child pointers are stored in an array, and the symmetry
++ * of most tree operations is exploited by using left/right variables when
++ * referring to children.
++ *
++ * In addition, this implementation assumes that all nodes are 4-byte aligned,
++ * so that the least significant bit of the parent member can be used to store
++ * the color of the node. This is true for all modern 32 and 64 bits
++ * architectures, as long as the nodes aren't embedded in structures with
++ * special alignment constraints such as member packing.
++ */
++struct rbtree_node {
++ unsigned long parent;
++ struct rbtree_node *children[2];
++};
++
++/*
++ * Red-black tree structure.
++ */
++struct rbtree {
++ struct rbtree_node *root;
++};
++
++/*
++ * Masks applied on the parent member of a node to obtain either the
++ * color or the parent address.
++ */
++#define RBTREE_COLOR_MASK 0x1UL
++#define RBTREE_PARENT_MASK (~0x3UL)
++
++/*
++ * Node colors.
++ */
++#define RBTREE_COLOR_RED 0
++#define RBTREE_COLOR_BLACK 1
++
++/*
++ * Masks applied on slots to obtain either the child index or the parent
++ * address.
++ */
++#define RBTREE_SLOT_INDEX_MASK 0x1UL
++#define RBTREE_SLOT_PARENT_MASK (~RBTREE_SLOT_INDEX_MASK)
++
++/*
++ * Return true if the given index is a valid child index.
++ */
++static inline int
++rbtree_check_index(int index)
++{
++ return index == (index & 1);
++}
++
++/*
++ * Convert the result of a comparison into an index in the children array
++ * (0 or 1).
++ *
++ * This function is mostly used when looking up a node.
++ */
++static inline int
++rbtree_d2i(int diff)
++{
++ return !(diff <= 0);
++}
++
++/*
++ * Return true if the given pointer is suitably aligned.
++ */
++static inline int
++rbtree_node_check_alignment(const struct rbtree_node *node)
++{
++ return ((unsigned long)node & (~RBTREE_PARENT_MASK)) == 0;
++}
++
++/*
++ * Return the parent of a node.
++ */
++static inline struct rbtree_node *
++rbtree_node_parent(const struct rbtree_node *node)
++{
++ return (struct rbtree_node *)(node->parent & RBTREE_PARENT_MASK);
++}
++
++/*
++ * Translate an insertion point into a slot.
++ */
++static inline unsigned long
++rbtree_slot(struct rbtree_node *parent, int index)
++{
++ assert(rbtree_node_check_alignment(parent));
++ assert(rbtree_check_index(index));
++ return (unsigned long)parent | index;
++}
++
++/*
++ * Extract the parent address from a slot.
++ */
++static inline struct rbtree_node *
++rbtree_slot_parent(unsigned long slot)
++{
++ return (struct rbtree_node *)(slot & RBTREE_SLOT_PARENT_MASK);
++}
++
++/*
++ * Extract the index from a slot.
++ */
++static inline int
++rbtree_slot_index(unsigned long slot)
++{
++ return slot & RBTREE_SLOT_INDEX_MASK;
++}
++
++/*
++ * Insert a node in a tree, rebalancing it if necessary.
++ *
++ * The index parameter is the index in the children array of the parent where
++ * the new node is to be inserted. It is ignored if the parent is NULL.
++ *
++ * This function is intended to be used by the rbtree_insert() macro only.
++ */
++void rbtree_insert_rebalance(struct rbtree *tree, struct rbtree_node *parent,
++ int index, struct rbtree_node *node);
++
++/*
++ * Return the previous or next node relative to a location in a tree.
++ *
++ * The parent and index parameters define the location, which can be empty.
++ * The direction parameter is either RBTREE_LEFT (to obtain the previous
++ * node) or RBTREE_RIGHT (to obtain the next one).
++ */
++struct rbtree_node * rbtree_nearest(struct rbtree_node *parent, int index,
++ int direction);
++
++/*
++ * Return the first or last node of a tree.
++ *
++ * The direction parameter is either RBTREE_LEFT (to obtain the first node)
++ * or RBTREE_RIGHT (to obtain the last one).
++ */
++struct rbtree_node * rbtree_firstlast(const struct rbtree *tree, int direction);
++
++/*
++ * Return the node next to, or previous to the given node.
++ *
++ * The direction parameter is either RBTREE_LEFT (to obtain the previous node)
++ * or RBTREE_RIGHT (to obtain the next one).
++ */
++struct rbtree_node * rbtree_walk(struct rbtree_node *node, int direction);
++
++/*
++ * Return the left-most deepest node of a tree, which is the starting point of
++ * the postorder traversal performed by rbtree_for_each_remove().
++ */
++struct rbtree_node * rbtree_postwalk_deepest(const struct rbtree *tree);
++
++/*
++ * Unlink a node from its tree and return the next (right) node in postorder.
++ */
++struct rbtree_node * rbtree_postwalk_unlink(struct rbtree_node *node);
++
++#endif /* _RBTREE_I_H */
+--
+2.0.0.rc2
+