Blame rbtree.c

Packit c4abd9
/*
Packit c4abd9
  Red Black Trees
Packit c4abd9
  (C) 1999  Andrea Arcangeli <andrea@suse.de>
Packit c4abd9
  (C) 2002  David Woodhouse <dwmw2@infradead.org>
Packit c4abd9
  
Packit c4abd9
  This program is free software; you can redistribute it and/or modify
Packit c4abd9
  it under the terms of the GNU General Public License as published by
Packit c4abd9
  the Free Software Foundation; either version 2 of the License, or
Packit c4abd9
  (at your option) any later version.
Packit c4abd9
Packit c4abd9
  This program is distributed in the hope that it will be useful,
Packit c4abd9
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit c4abd9
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit c4abd9
  GNU General Public License for more details.
Packit c4abd9
Packit c4abd9
  You should have received a copy of the GNU General Public License
Packit c4abd9
  along with this program; if not, write to the Free Software
Packit c4abd9
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit c4abd9
Packit c4abd9
  linux/lib/rbtree.c
Packit c4abd9
*/
Packit c4abd9
Packit c4abd9
#include "rbtree.h"
Packit c4abd9
Packit c4abd9
static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *right = node->rb_right;
Packit c4abd9
	struct rb_node *parent = rb_parent(node);
Packit c4abd9
Packit c4abd9
	if ((node->rb_right = right->rb_left))
Packit c4abd9
		rb_set_parent(right->rb_left, node);
Packit c4abd9
	right->rb_left = node;
Packit c4abd9
Packit c4abd9
	rb_set_parent(right, parent);
Packit c4abd9
Packit c4abd9
	if (parent)
Packit c4abd9
	{
Packit c4abd9
		if (node == parent->rb_left)
Packit c4abd9
			parent->rb_left = right;
Packit c4abd9
		else
Packit c4abd9
			parent->rb_right = right;
Packit c4abd9
	}
Packit c4abd9
	else
Packit c4abd9
		root->rb_node = right;
Packit c4abd9
	rb_set_parent(node, right);
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *left = node->rb_left;
Packit c4abd9
	struct rb_node *parent = rb_parent(node);
Packit c4abd9
Packit c4abd9
	if ((node->rb_left = left->rb_right))
Packit c4abd9
		rb_set_parent(left->rb_right, node);
Packit c4abd9
	left->rb_right = node;
Packit c4abd9
Packit c4abd9
	rb_set_parent(left, parent);
Packit c4abd9
Packit c4abd9
	if (parent)
Packit c4abd9
	{
Packit c4abd9
		if (node == parent->rb_right)
Packit c4abd9
			parent->rb_right = left;
Packit c4abd9
		else
Packit c4abd9
			parent->rb_left = left;
Packit c4abd9
	}
Packit c4abd9
	else
Packit c4abd9
		root->rb_node = left;
Packit c4abd9
	rb_set_parent(node, left);
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
void rb_insert_color(struct rb_node *node, struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *parent, *gparent;
Packit c4abd9
Packit c4abd9
	while ((parent = rb_parent(node)) && rb_is_red(parent))
Packit c4abd9
	{
Packit c4abd9
		gparent = rb_parent(parent);
Packit c4abd9
Packit c4abd9
		if (parent == gparent->rb_left)
Packit c4abd9
		{
Packit c4abd9
			{
Packit c4abd9
				register struct rb_node *uncle = gparent->rb_right;
Packit c4abd9
				if (uncle && rb_is_red(uncle))
Packit c4abd9
				{
Packit c4abd9
					rb_set_black(uncle);
Packit c4abd9
					rb_set_black(parent);
Packit c4abd9
					rb_set_red(gparent);
Packit c4abd9
					node = gparent;
Packit c4abd9
					continue;
Packit c4abd9
				}
Packit c4abd9
			}
Packit c4abd9
Packit c4abd9
			if (parent->rb_right == node)
Packit c4abd9
			{
Packit c4abd9
				register struct rb_node *tmp;
Packit c4abd9
				__rb_rotate_left(parent, root);
Packit c4abd9
				tmp = parent;
Packit c4abd9
				parent = node;
Packit c4abd9
				node = tmp;
Packit c4abd9
			}
Packit c4abd9
Packit c4abd9
			rb_set_black(parent);
Packit c4abd9
			rb_set_red(gparent);
Packit c4abd9
			__rb_rotate_right(gparent, root);
Packit c4abd9
		} else {
Packit c4abd9
			{
Packit c4abd9
				register struct rb_node *uncle = gparent->rb_left;
Packit c4abd9
				if (uncle && rb_is_red(uncle))
Packit c4abd9
				{
Packit c4abd9
					rb_set_black(uncle);
Packit c4abd9
					rb_set_black(parent);
Packit c4abd9
					rb_set_red(gparent);
Packit c4abd9
					node = gparent;
Packit c4abd9
					continue;
Packit c4abd9
				}
Packit c4abd9
			}
Packit c4abd9
Packit c4abd9
			if (parent->rb_left == node)
Packit c4abd9
			{
Packit c4abd9
				register struct rb_node *tmp;
Packit c4abd9
				__rb_rotate_right(parent, root);
Packit c4abd9
				tmp = parent;
Packit c4abd9
				parent = node;
Packit c4abd9
				node = tmp;
Packit c4abd9
			}
Packit c4abd9
Packit c4abd9
			rb_set_black(parent);
Packit c4abd9
			rb_set_red(gparent);
Packit c4abd9
			__rb_rotate_left(gparent, root);
Packit c4abd9
		}
Packit c4abd9
	}
Packit c4abd9
Packit c4abd9
	rb_set_black(root->rb_node);
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
Packit c4abd9
			     struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *other;
Packit c4abd9
Packit c4abd9
	while ((!node || rb_is_black(node)) && node != root->rb_node)
Packit c4abd9
	{
Packit c4abd9
		if (parent->rb_left == node)
Packit c4abd9
		{
Packit c4abd9
			other = parent->rb_right;
Packit c4abd9
			if (rb_is_red(other))
Packit c4abd9
			{
Packit c4abd9
				rb_set_black(other);
Packit c4abd9
				rb_set_red(parent);
Packit c4abd9
				__rb_rotate_left(parent, root);
Packit c4abd9
				other = parent->rb_right;
Packit c4abd9
			}
Packit c4abd9
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
Packit c4abd9
			    (!other->rb_right || rb_is_black(other->rb_right)))
Packit c4abd9
			{
Packit c4abd9
				rb_set_red(other);
Packit c4abd9
				node = parent;
Packit c4abd9
				parent = rb_parent(node);
Packit c4abd9
			}
Packit c4abd9
			else
Packit c4abd9
			{
Packit c4abd9
				if (!other->rb_right || rb_is_black(other->rb_right))
Packit c4abd9
				{
Packit c4abd9
					struct rb_node *o_left;
Packit c4abd9
					if ((o_left = other->rb_left))
Packit c4abd9
						rb_set_black(o_left);
Packit c4abd9
					rb_set_red(other);
Packit c4abd9
					__rb_rotate_right(other, root);
Packit c4abd9
					other = parent->rb_right;
Packit c4abd9
				}
Packit c4abd9
				rb_set_color(other, rb_color(parent));
Packit c4abd9
				rb_set_black(parent);
Packit c4abd9
				if (other->rb_right)
Packit c4abd9
					rb_set_black(other->rb_right);
Packit c4abd9
				__rb_rotate_left(parent, root);
Packit c4abd9
				node = root->rb_node;
Packit c4abd9
				break;
Packit c4abd9
			}
Packit c4abd9
		}
Packit c4abd9
		else
Packit c4abd9
		{
Packit c4abd9
			other = parent->rb_left;
Packit c4abd9
			if (rb_is_red(other))
Packit c4abd9
			{
Packit c4abd9
				rb_set_black(other);
Packit c4abd9
				rb_set_red(parent);
Packit c4abd9
				__rb_rotate_right(parent, root);
Packit c4abd9
				other = parent->rb_left;
Packit c4abd9
			}
Packit c4abd9
			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
Packit c4abd9
			    (!other->rb_right || rb_is_black(other->rb_right)))
Packit c4abd9
			{
Packit c4abd9
				rb_set_red(other);
Packit c4abd9
				node = parent;
Packit c4abd9
				parent = rb_parent(node);
Packit c4abd9
			}
Packit c4abd9
			else
Packit c4abd9
			{
Packit c4abd9
				if (!other->rb_left || rb_is_black(other->rb_left))
Packit c4abd9
				{
Packit c4abd9
					register struct rb_node *o_right;
Packit c4abd9
					if ((o_right = other->rb_right))
Packit c4abd9
						rb_set_black(o_right);
Packit c4abd9
					rb_set_red(other);
Packit c4abd9
					__rb_rotate_left(other, root);
Packit c4abd9
					other = parent->rb_left;
Packit c4abd9
				}
Packit c4abd9
				rb_set_color(other, rb_color(parent));
Packit c4abd9
				rb_set_black(parent);
Packit c4abd9
				if (other->rb_left)
Packit c4abd9
					rb_set_black(other->rb_left);
Packit c4abd9
				__rb_rotate_right(parent, root);
Packit c4abd9
				node = root->rb_node;
Packit c4abd9
				break;
Packit c4abd9
			}
Packit c4abd9
		}
Packit c4abd9
	}
Packit c4abd9
	if (node)
Packit c4abd9
		rb_set_black(node);
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
void rb_erase(struct rb_node *node, struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *child, *parent;
Packit c4abd9
	int color;
Packit c4abd9
Packit c4abd9
	if (!node->rb_left)
Packit c4abd9
		child = node->rb_right;
Packit c4abd9
	else if (!node->rb_right)
Packit c4abd9
		child = node->rb_left;
Packit c4abd9
	else
Packit c4abd9
	{
Packit c4abd9
		struct rb_node *old = node, *left;
Packit c4abd9
Packit c4abd9
		node = node->rb_right;
Packit c4abd9
		while ((left = node->rb_left) != NULL)
Packit c4abd9
			node = left;
Packit c4abd9
		child = node->rb_right;
Packit c4abd9
		parent = rb_parent(node);
Packit c4abd9
		color = rb_color(node);
Packit c4abd9
Packit c4abd9
		if (child)
Packit c4abd9
			rb_set_parent(child, parent);
Packit c4abd9
		if (parent == old) {
Packit c4abd9
			parent->rb_right = child;
Packit c4abd9
			parent = node;
Packit c4abd9
		} else
Packit c4abd9
			parent->rb_left = child;
Packit c4abd9
Packit c4abd9
		node->rb_parent_color = old->rb_parent_color;
Packit c4abd9
		node->rb_right = old->rb_right;
Packit c4abd9
		node->rb_left = old->rb_left;
Packit c4abd9
Packit c4abd9
		if (rb_parent(old))
Packit c4abd9
		{
Packit c4abd9
			if (rb_parent(old)->rb_left == old)
Packit c4abd9
				rb_parent(old)->rb_left = node;
Packit c4abd9
			else
Packit c4abd9
				rb_parent(old)->rb_right = node;
Packit c4abd9
		} else
Packit c4abd9
			root->rb_node = node;
Packit c4abd9
Packit c4abd9
		rb_set_parent(old->rb_left, node);
Packit c4abd9
		if (old->rb_right)
Packit c4abd9
			rb_set_parent(old->rb_right, node);
Packit c4abd9
		goto color;
Packit c4abd9
	}
Packit c4abd9
Packit c4abd9
	parent = rb_parent(node);
Packit c4abd9
	color = rb_color(node);
Packit c4abd9
Packit c4abd9
	if (child)
Packit c4abd9
		rb_set_parent(child, parent);
Packit c4abd9
	if (parent)
Packit c4abd9
	{
Packit c4abd9
		if (parent->rb_left == node)
Packit c4abd9
			parent->rb_left = child;
Packit c4abd9
		else
Packit c4abd9
			parent->rb_right = child;
Packit c4abd9
	}
Packit c4abd9
	else
Packit c4abd9
		root->rb_node = child;
Packit c4abd9
Packit c4abd9
 color:
Packit c4abd9
	if (color == RB_BLACK)
Packit c4abd9
		__rb_erase_color(child, parent, root);
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
/*
Packit c4abd9
 * This function returns the first node (in sort order) of the tree.
Packit c4abd9
 */
Packit c4abd9
struct rb_node *rb_first(struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node	*n;
Packit c4abd9
Packit c4abd9
	n = root->rb_node;
Packit c4abd9
	if (!n)
Packit c4abd9
		return NULL;
Packit c4abd9
	while (n->rb_left)
Packit c4abd9
		n = n->rb_left;
Packit c4abd9
	return n;
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
struct rb_node *rb_last(struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node	*n;
Packit c4abd9
Packit c4abd9
	n = root->rb_node;
Packit c4abd9
	if (!n)
Packit c4abd9
		return NULL;
Packit c4abd9
	while (n->rb_right)
Packit c4abd9
		n = n->rb_right;
Packit c4abd9
	return n;
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
struct rb_node *rb_next(struct rb_node *node)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *parent;
Packit c4abd9
Packit c4abd9
	if (rb_parent(node) == node)
Packit c4abd9
		return NULL;
Packit c4abd9
Packit c4abd9
	/* If we have a right-hand child, go down and then left as far
Packit c4abd9
	   as we can. */
Packit c4abd9
	if (node->rb_right) {
Packit c4abd9
		node = node->rb_right; 
Packit c4abd9
		while (node->rb_left)
Packit c4abd9
			node=node->rb_left;
Packit c4abd9
		return node;
Packit c4abd9
	}
Packit c4abd9
Packit c4abd9
	/* No right-hand children.  Everything down and left is
Packit c4abd9
	   smaller than us, so any 'next' node must be in the general
Packit c4abd9
	   direction of our parent. Go up the tree; any time the
Packit c4abd9
	   ancestor is a right-hand child of its parent, keep going
Packit c4abd9
	   up. First time it's a left-hand child of its parent, said
Packit c4abd9
	   parent is our 'next' node. */
Packit c4abd9
	while ((parent = rb_parent(node)) && node == parent->rb_right)
Packit c4abd9
		node = parent;
Packit c4abd9
Packit c4abd9
	return parent;
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
struct rb_node *rb_prev(struct rb_node *node)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *parent;
Packit c4abd9
Packit c4abd9
	if (rb_parent(node) == node)
Packit c4abd9
		return NULL;
Packit c4abd9
Packit c4abd9
	/* If we have a left-hand child, go down and then right as far
Packit c4abd9
	   as we can. */
Packit c4abd9
	if (node->rb_left) {
Packit c4abd9
		node = node->rb_left; 
Packit c4abd9
		while (node->rb_right)
Packit c4abd9
			node=node->rb_right;
Packit c4abd9
		return node;
Packit c4abd9
	}
Packit c4abd9
Packit c4abd9
	/* No left-hand children. Go up till we find an ancestor which
Packit c4abd9
	   is a right-hand child of its parent */
Packit c4abd9
	while ((parent = rb_parent(node)) && node == parent->rb_left)
Packit c4abd9
		node = parent;
Packit c4abd9
Packit c4abd9
	return parent;
Packit c4abd9
}
Packit c4abd9
Packit c4abd9
void rb_replace_node(struct rb_node *victim, struct rb_node *new,
Packit c4abd9
		     struct rb_root *root)
Packit c4abd9
{
Packit c4abd9
	struct rb_node *parent = rb_parent(victim);
Packit c4abd9
Packit c4abd9
	/* Set the surrounding nodes to point to the replacement */
Packit c4abd9
	if (parent) {
Packit c4abd9
		if (victim == parent->rb_left)
Packit c4abd9
			parent->rb_left = new;
Packit c4abd9
		else
Packit c4abd9
			parent->rb_right = new;
Packit c4abd9
	} else {
Packit c4abd9
		root->rb_node = new;
Packit c4abd9
	}
Packit c4abd9
	if (victim->rb_left)
Packit c4abd9
		rb_set_parent(victim->rb_left, new);
Packit c4abd9
	if (victim->rb_right)
Packit c4abd9
		rb_set_parent(victim->rb_right, new);
Packit c4abd9
Packit c4abd9
	/* Copy the pointers/colour from the victim to the replacement */
Packit c4abd9
	*new = *victim;
Packit c4abd9
}