Blame gfs2/include/osi_tree.h

Packit 6ef888
#ifndef __OSI_RBTREE_DOT_H__
Packit 6ef888
#define __OSI_RBTREE_DOT_H__
Packit 6ef888
Packit 6ef888
#include <stdlib.h>
Packit 6ef888
#include <stddef.h>
Packit 6ef888
#include <assert.h>
Packit 6ef888
Packit 6ef888
/* Adapted from the kernel's rbtree.c */
Packit 6ef888
struct osi_node {
Packit 6ef888
	unsigned long  osi_parent_color;
Packit 6ef888
#define	OSI_RED		0
Packit 6ef888
#define	OSI_BLACK	1
Packit 6ef888
	struct osi_node *osi_left;
Packit 6ef888
	struct osi_node *osi_right;
Packit 6ef888
};
Packit 6ef888
Packit 6ef888
#define osi_parent(r)   ((struct osi_node *)((r)->osi_parent_color & ~3))
Packit 6ef888
#define osi_color(r)   ((r)->osi_parent_color & 1)
Packit 6ef888
#define osi_is_red(r)   (!osi_color(r))
Packit 6ef888
#define osi_is_black(r) osi_color(r)
Packit 6ef888
#define osi_set_red(r)  do { (r)->osi_parent_color &= ~1; } while (0)
Packit 6ef888
#define osi_set_black(r)  do { (r)->osi_parent_color |= 1; } while (0)
Packit 6ef888
#define OSI_EMPTY_NODE(node) (osi_parent(node) == node)
Packit 6ef888
Packit 6ef888
struct osi_root
Packit 6ef888
{
Packit 6ef888
	struct osi_node *osi_node;
Packit 6ef888
};
Packit 6ef888
Packit 6ef888
#define OSI_EMPTY_ROOT(root)  ((root)->osi_node == NULL)
Packit 6ef888
Packit 6ef888
static inline void osi_set_parent(struct osi_node *rb, struct osi_node *p)
Packit 6ef888
{
Packit 6ef888
        rb->osi_parent_color = (rb->osi_parent_color & 3) | (unsigned long)p;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void osi_set_color(struct osi_node *rb, int color)
Packit 6ef888
{
Packit 6ef888
	rb->osi_parent_color = (rb->osi_parent_color & ~1) | color;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void osi_link_node(struct osi_node *node,
Packit 6ef888
				 struct osi_node *parent,
Packit 6ef888
				 struct osi_node **osi_link)
Packit 6ef888
{
Packit 6ef888
	node->osi_parent_color = (unsigned long )parent;
Packit 6ef888
	node->osi_left = node->osi_right = NULL;
Packit 6ef888
Packit 6ef888
	*osi_link = node;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void __osi_rotate_left(struct osi_node *node,
Packit 6ef888
				     struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *right = node->osi_right;
Packit 6ef888
	struct osi_node *parent = osi_parent(node);
Packit 6ef888
Packit 6ef888
	if ((node->osi_right = right->osi_left))
Packit 6ef888
		osi_set_parent(right->osi_left, node);
Packit 6ef888
	right->osi_left = node;
Packit 6ef888
Packit 6ef888
	osi_set_parent(right, parent);
Packit 6ef888
Packit 6ef888
	if (parent) {
Packit 6ef888
		if (node == parent->osi_left)
Packit 6ef888
			parent->osi_left = right;
Packit 6ef888
		else
Packit 6ef888
			parent->osi_right = right;
Packit 6ef888
	}
Packit 6ef888
	else
Packit 6ef888
		root->osi_node = right;
Packit 6ef888
	osi_set_parent(node, right);
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void __osi_rotate_right(struct osi_node *node,
Packit 6ef888
				      struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *left = node->osi_left;
Packit 6ef888
	struct osi_node *parent = osi_parent(node);
Packit 6ef888
Packit 6ef888
	if ((node->osi_left = left->osi_right))
Packit 6ef888
		osi_set_parent(left->osi_right, node);
Packit 6ef888
	left->osi_right = node;
Packit 6ef888
Packit 6ef888
	osi_set_parent(left, parent);
Packit 6ef888
Packit 6ef888
	if (parent) {
Packit 6ef888
		if (node == parent->osi_right)
Packit 6ef888
			parent->osi_right = left;
Packit 6ef888
		else
Packit 6ef888
			parent->osi_left = left;
Packit 6ef888
	} else
Packit 6ef888
		root->osi_node = left;
Packit 6ef888
	osi_set_parent(node, left);
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void osi_insert_color(struct osi_node *node,
Packit 6ef888
				    struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *parent, *gparent;
Packit 6ef888
Packit 6ef888
	while ((parent = osi_parent(node)) && osi_is_red(parent)) {
Packit 6ef888
		gparent = osi_parent(parent);
Packit 6ef888
Packit 6ef888
		if (parent == gparent->osi_left) {
Packit 6ef888
			{
Packit 6ef888
				register struct osi_node *uncle = gparent->osi_right;
Packit 6ef888
				if (uncle && osi_is_red(uncle)) {
Packit 6ef888
					osi_set_black(uncle);
Packit 6ef888
					osi_set_black(parent);
Packit 6ef888
					osi_set_red(gparent);
Packit 6ef888
					node = gparent;
Packit 6ef888
					continue;
Packit 6ef888
				}
Packit 6ef888
			}
Packit 6ef888
Packit 6ef888
			if (parent->osi_right == node) {
Packit 6ef888
				register struct osi_node *tmp;
Packit 6ef888
Packit 6ef888
				__osi_rotate_left(parent, root);
Packit 6ef888
				tmp = parent;
Packit 6ef888
				parent = node;
Packit 6ef888
				node = tmp;
Packit 6ef888
			}
Packit 6ef888
Packit 6ef888
			osi_set_black(parent);
Packit 6ef888
			osi_set_red(gparent);
Packit 6ef888
			__osi_rotate_right(gparent, root);
Packit 6ef888
		} else {
Packit 6ef888
			{
Packit 6ef888
				register struct osi_node *uncle = gparent->osi_left;
Packit 6ef888
				if (uncle && osi_is_red(uncle)) {
Packit 6ef888
					osi_set_black(uncle);
Packit 6ef888
					osi_set_black(parent);
Packit 6ef888
					osi_set_red(gparent);
Packit 6ef888
					node = gparent;
Packit 6ef888
					continue;
Packit 6ef888
				}
Packit 6ef888
			}
Packit 6ef888
Packit 6ef888
			if (parent->osi_left == node) {
Packit 6ef888
				register struct osi_node *tmp;
Packit 6ef888
				__osi_rotate_right(parent, root);
Packit 6ef888
				tmp = parent;
Packit 6ef888
				parent = node;
Packit 6ef888
				node = tmp;
Packit 6ef888
			}
Packit 6ef888
Packit 6ef888
			osi_set_black(parent);
Packit 6ef888
			osi_set_red(gparent);
Packit 6ef888
			__osi_rotate_left(gparent, root);
Packit 6ef888
		}
Packit 6ef888
	}
Packit 6ef888
Packit 6ef888
	osi_set_black(root->osi_node);
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void __osi_erase_color(struct osi_node *node,
Packit 6ef888
				     struct osi_node *parent,
Packit 6ef888
				     struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *other;
Packit 6ef888
Packit 6ef888
	while ((!node || osi_is_black(node)) && node != root->osi_node) {
Packit 6ef888
		if (parent->osi_left == node) {
Packit 6ef888
			other = parent->osi_right;
Packit 6ef888
			if (osi_is_red(other)) {
Packit 6ef888
				osi_set_black(other);
Packit 6ef888
				osi_set_red(parent);
Packit 6ef888
				__osi_rotate_left(parent, root);
Packit 6ef888
				other = parent->osi_right;
Packit 6ef888
			}
Packit 6ef888
			if ((!other->osi_left || osi_is_black(other->osi_left)) &&
Packit 6ef888
			    (!other->osi_right || osi_is_black(other->osi_right)))
Packit 6ef888
			{
Packit 6ef888
				osi_set_red(other);
Packit 6ef888
				node = parent;
Packit 6ef888
				parent = osi_parent(node);
Packit 6ef888
			} else {
Packit 6ef888
				if (!other->osi_right || osi_is_black(other->osi_right))
Packit 6ef888
				{
Packit 6ef888
					struct osi_node *o_left;
Packit 6ef888
					if ((o_left = other->osi_left))
Packit 6ef888
						osi_set_black(o_left);
Packit 6ef888
					osi_set_red(other);
Packit 6ef888
					__osi_rotate_right(other, root);
Packit 6ef888
					other = parent->osi_right;
Packit 6ef888
				}
Packit 6ef888
				osi_set_color(other, osi_color(parent));
Packit 6ef888
				osi_set_black(parent);
Packit 6ef888
				if (other->osi_right)
Packit 6ef888
					osi_set_black(other->osi_right);
Packit 6ef888
				__osi_rotate_left(parent, root);
Packit 6ef888
				node = root->osi_node;
Packit 6ef888
				break;
Packit 6ef888
			}
Packit 6ef888
		} else {
Packit 6ef888
			other = parent->osi_left;
Packit 6ef888
			if (osi_is_red(other)) {
Packit 6ef888
				osi_set_black(other);
Packit 6ef888
				osi_set_red(parent);
Packit 6ef888
				__osi_rotate_right(parent, root);
Packit 6ef888
				other = parent->osi_left;
Packit 6ef888
			}
Packit 6ef888
			if ((!other->osi_left || osi_is_black(other->osi_left)) &&
Packit 6ef888
			    (!other->osi_right || osi_is_black(other->osi_right)))
Packit 6ef888
			{
Packit 6ef888
				osi_set_red(other);
Packit 6ef888
				node = parent;
Packit 6ef888
				parent = osi_parent(node);
Packit 6ef888
			} else {
Packit 6ef888
				if (!other->osi_left || osi_is_black(other->osi_left))
Packit 6ef888
				{
Packit 6ef888
					register struct osi_node *o_right;
Packit 6ef888
					if ((o_right = other->osi_right))
Packit 6ef888
						osi_set_black(o_right);
Packit 6ef888
					osi_set_red(other);
Packit 6ef888
					__osi_rotate_left(other, root);
Packit 6ef888
					other = parent->osi_left;
Packit 6ef888
				}
Packit 6ef888
				osi_set_color(other, osi_color(parent));
Packit 6ef888
				osi_set_black(parent);
Packit 6ef888
				if (other->osi_left)
Packit 6ef888
					osi_set_black(other->osi_left);
Packit 6ef888
				__osi_rotate_right(parent, root);
Packit 6ef888
				node = root->osi_node;
Packit 6ef888
				break;
Packit 6ef888
			}
Packit 6ef888
		}
Packit 6ef888
	}
Packit 6ef888
	if (node)
Packit 6ef888
		osi_set_black(node);
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void osi_erase(struct osi_node *node, struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *child, *parent;
Packit 6ef888
	int color;
Packit 6ef888
Packit 6ef888
	if (!node->osi_left)
Packit 6ef888
		child = node->osi_right;
Packit 6ef888
	else if (!node->osi_right)
Packit 6ef888
		child = node->osi_left;
Packit 6ef888
	else {
Packit 6ef888
		struct osi_node *old = node, *left;
Packit 6ef888
Packit 6ef888
		node = node->osi_right;
Packit 6ef888
		while ((left = node->osi_left) != NULL)
Packit 6ef888
			node = left;
Packit 6ef888
Packit 6ef888
		if (osi_parent(old)) {
Packit 6ef888
			if (osi_parent(old)->osi_left == old)
Packit 6ef888
				osi_parent(old)->osi_left = node;
Packit 6ef888
			else
Packit 6ef888
				osi_parent(old)->osi_right = node;
Packit 6ef888
		} else
Packit 6ef888
			root->osi_node = node;
Packit 6ef888
Packit 6ef888
		child = node->osi_right;
Packit 6ef888
		parent = osi_parent(node);
Packit 6ef888
		color = osi_color(node);
Packit 6ef888
Packit 6ef888
		if (parent == old) {
Packit 6ef888
			parent = node;
Packit 6ef888
		} else {
Packit 6ef888
			if (child)
Packit 6ef888
				osi_set_parent(child, parent);
Packit 6ef888
			parent->osi_left = child;
Packit 6ef888
Packit 6ef888
			node->osi_right = old->osi_right;
Packit 6ef888
			osi_set_parent(old->osi_right, node);
Packit 6ef888
		}
Packit 6ef888
Packit 6ef888
		node->osi_parent_color = old->osi_parent_color;
Packit 6ef888
		node->osi_left = old->osi_left;
Packit 6ef888
		osi_set_parent(old->osi_left, node);
Packit 6ef888
Packit 6ef888
		goto color;
Packit 6ef888
	}
Packit 6ef888
Packit 6ef888
	parent = osi_parent(node);
Packit 6ef888
	color = osi_color(node);
Packit 6ef888
Packit 6ef888
	if (child)
Packit 6ef888
		osi_set_parent(child, parent);
Packit 6ef888
	if (parent)
Packit 6ef888
	{
Packit 6ef888
		if (parent->osi_left == node)
Packit 6ef888
			parent->osi_left = child;
Packit 6ef888
		else
Packit 6ef888
			parent->osi_right = child;
Packit 6ef888
	}
Packit 6ef888
	else
Packit 6ef888
		root->osi_node = child;
Packit 6ef888
Packit 6ef888
 color:
Packit 6ef888
	if (color == OSI_BLACK)
Packit 6ef888
		__osi_erase_color(child, parent, root);
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
/*
Packit 6ef888
 * This function returns the first node (in sort order) of the tree.
Packit 6ef888
 */
Packit 6ef888
static inline struct osi_node *osi_first(struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node	*n;
Packit 6ef888
Packit 6ef888
	n = root->osi_node;
Packit 6ef888
	if (!n)
Packit 6ef888
		return NULL;
Packit 6ef888
	while (n->osi_left)
Packit 6ef888
		n = n->osi_left;
Packit 6ef888
	return n;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline struct osi_node *osi_last(struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node	*n;
Packit 6ef888
Packit 6ef888
	n = root->osi_node;
Packit 6ef888
	if (!n)
Packit 6ef888
		return NULL;
Packit 6ef888
	while (n->osi_right)
Packit 6ef888
		n = n->osi_right;
Packit 6ef888
	return n;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline struct osi_node *osi_next(struct osi_node *node)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *parent;
Packit 6ef888
Packit 6ef888
	if (OSI_EMPTY_NODE(node))
Packit 6ef888
		return NULL;
Packit 6ef888
Packit 6ef888
	/* If we have a right-hand child, go down and then left as far
Packit 6ef888
	   as we can. */
Packit 6ef888
	if (node->osi_right) {
Packit 6ef888
		node = node->osi_right;
Packit 6ef888
		while (node->osi_left)
Packit 6ef888
			node=node->osi_left;
Packit 6ef888
		return node;
Packit 6ef888
	}
Packit 6ef888
Packit 6ef888
	/* No right-hand children.  Everything down and left is
Packit 6ef888
	   smaller than us, so any 'next' node must be in the general
Packit 6ef888
	   direction of our parent. Go up the tree; any time the
Packit 6ef888
	   ancestor is a right-hand child of its parent, keep going
Packit 6ef888
	   up. First time it's a left-hand child of its parent, said
Packit 6ef888
	   parent is our 'next' node. */
Packit 6ef888
	while ((parent = osi_parent(node)) && node == parent->osi_right)
Packit 6ef888
		node = parent;
Packit 6ef888
Packit 6ef888
	return parent;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline struct osi_node *osi_prev(struct osi_node *node)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *parent;
Packit 6ef888
Packit 6ef888
	if (OSI_EMPTY_NODE(node))
Packit 6ef888
		return NULL;
Packit 6ef888
Packit 6ef888
	/* If we have a left-hand child, go down and then right as far
Packit 6ef888
	   as we can. */
Packit 6ef888
	if (node->osi_left) {
Packit 6ef888
		node = node->osi_left;
Packit 6ef888
		while (node->osi_right)
Packit 6ef888
			node=node->osi_right;
Packit 6ef888
		return node;
Packit 6ef888
	}
Packit 6ef888
Packit 6ef888
	/* No left-hand children. Go up till we find an ancestor which
Packit 6ef888
	   is a right-hand child of its parent */
Packit 6ef888
	while ((parent = osi_parent(node)) && node == parent->osi_left)
Packit 6ef888
		node = parent;
Packit 6ef888
Packit 6ef888
	return parent;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
static inline void osi_replace_node(struct osi_node *victim,
Packit 6ef888
				    struct osi_node *new,
Packit 6ef888
				    struct osi_root *root)
Packit 6ef888
{
Packit 6ef888
	struct osi_node *parent = osi_parent(victim);
Packit 6ef888
Packit 6ef888
	/* Set the surrounding nodes to point to the replacement */
Packit 6ef888
	if (parent) {
Packit 6ef888
		if (victim == parent->osi_left)
Packit 6ef888
			parent->osi_left = new;
Packit 6ef888
		else
Packit 6ef888
			parent->osi_right = new;
Packit 6ef888
	} else {
Packit 6ef888
		root->osi_node = new;
Packit 6ef888
	}
Packit 6ef888
	if (victim->osi_left)
Packit 6ef888
		osi_set_parent(victim->osi_left, new);
Packit 6ef888
	if (victim->osi_right)
Packit 6ef888
		osi_set_parent(victim->osi_right, new);
Packit 6ef888
Packit 6ef888
	/* Copy the pointers/colour from the victim to the replacement */
Packit 6ef888
	*new = *victim;
Packit 6ef888
}
Packit 6ef888
Packit 6ef888
#endif