Пример #1
0
/*
 * Operations INSERT and DELETE, when run on a tree with n keys,
 * take O(logN) time.Because they modify the tree, the result
 * may violate the red-black properties.To restore these properties,
 * we must change the colors of some of the nodes in the tree
 * and also change the pointer structure.
 */
static void interval_insert_color(struct interval_node *node,
				  struct interval_node **root)
{
	struct interval_node *parent, *gparent;

	while ((parent = node->in_parent) && node_is_red(parent)) {
		gparent = parent->in_parent;
		/* Parent is RED, so gparent must not be NULL */
		if (node_is_left_child(parent)) {
			struct interval_node *uncle;

			uncle = gparent->in_right;
			if (uncle && node_is_red(uncle)) {
				uncle->in_color = INTERVAL_BLACK;
				parent->in_color = INTERVAL_BLACK;
				gparent->in_color = INTERVAL_RED;
				node = gparent;
				continue;
			}

			if (parent->in_right == node) {
				__rotate_left(parent, root);
				interval_swap(node, parent);
			}

			parent->in_color = INTERVAL_BLACK;
			gparent->in_color = INTERVAL_RED;
			__rotate_right(gparent, root);
		} else {
			struct interval_node *uncle;

			uncle = gparent->in_left;
			if (uncle && node_is_red(uncle)) {
				uncle->in_color = INTERVAL_BLACK;
				parent->in_color = INTERVAL_BLACK;
				gparent->in_color = INTERVAL_RED;
				node = gparent;
				continue;
			}

			if (node_is_left_child(node)) {
				__rotate_right(parent, root);
				interval_swap(node, parent);
			}

			parent->in_color = INTERVAL_BLACK;
			gparent->in_color = INTERVAL_RED;
			__rotate_left(gparent, root);
		}
	}

	(*root)->in_color = INTERVAL_BLACK;
}
Пример #2
0
/* The left rotation "pivots" around the link from node to node->right, and
 * - node will be linked to node->right's left child, and
 * - node->right's left child will be linked to node's right child.
 */
static void __rotate_left(struct interval_node *node,
			  struct interval_node **root)
{
	struct interval_node *right = node->in_right;
	struct interval_node *parent = node->in_parent;

	node->in_right = right->in_left;
	if (node->in_right)
		right->in_left->in_parent = node;

	right->in_left = node;
	right->in_parent = parent;
	if (parent) {
		if (node_is_left_child(node))
			parent->in_left = right;
		else
			parent->in_right = right;
	} else {
		*root = right;
	}
	node->in_parent = right;

	/* update max_high for node and right */
	__rotate_change_maxhigh(node, right);
}
Пример #3
0
static struct interval_node *interval_prev(struct interval_node *node)
{
	if (!node)
		return NULL;

	if (node->in_left)
		return interval_last(node->in_left);

	while (node->in_parent && node_is_left_child(node))
		node = node->in_parent;

	return node->in_parent;
}
Пример #4
0
static struct interval_node *interval_prev(struct interval_node *node)
{
        ENTRY;

        if (!node)
                RETURN(NULL);

        if (node->in_left)
                RETURN(interval_last(node->in_left));

        while (node->in_parent && node_is_left_child(node))
                node = node->in_parent;

        RETURN(node->in_parent);
}
Пример #5
0
void interval_erase(struct interval_node *node,
		    struct interval_node **root)
{
	struct interval_node *child, *parent;
	int color;

	LASSERT(interval_is_intree(node));
	node->in_intree = 0;
	if (!node->in_left) {
		child = node->in_right;
	} else if (!node->in_right) {
		child = node->in_left;
	} else { /* Both left and right child are not NULL */
		struct interval_node *old = node;

		node = interval_next(node);
		child = node->in_right;
		parent = node->in_parent;
		color = node->in_color;

		if (child)
			child->in_parent = parent;
		if (parent == old)
			parent->in_right = child;
		else
			parent->in_left = child;

		node->in_color = old->in_color;
		node->in_right = old->in_right;
		node->in_left = old->in_left;
		node->in_parent = old->in_parent;

		if (old->in_parent) {
			if (node_is_left_child(old))
				old->in_parent->in_left = node;
			else
				old->in_parent->in_right = node;
		} else {
			*root = node;
		}

		old->in_left->in_parent = node;
		if (old->in_right)
			old->in_right->in_parent = node;
		update_maxhigh(child ? : parent, node->in_max_high);
		update_maxhigh(node, old->in_max_high);
		if (parent == old)
			parent = node;
		goto color;
	}
	parent = node->in_parent;
	color = node->in_color;

	if (child)
		child->in_parent = parent;
	if (parent) {
		if (node_is_left_child(node))
			parent->in_left = child;
		else
			parent->in_right = child;
	} else {
		*root = child;
	}

	update_maxhigh(child ? : parent, node->in_max_high);

color:
	if (color == INTERVAL_BLACK)
		interval_erase_color(child, parent, root);
}