Beispiel #1
0
/* Note args swapped to match Linux */
void rb_insert_color(struct rb_node *elm, struct rb_root *head)
{
	struct rb_node *parent, *gparent, *tmp;
	while ((parent = RB_PARENT(elm)) &&
	    RB_COLOR(parent) == RB_RED) {
		gparent = RB_PARENT(parent);
		if (parent == RB_LEFT(gparent)) {
			tmp = RB_RIGHT(gparent);
			if (tmp && RB_COLOR(tmp) == RB_RED) {
				RB_COLOR(tmp) = RB_BLACK;
				RB_SET_BLACKRED(parent, gparent);
				elm = gparent;
				continue;
			}
			if (RB_RIGHT(parent) == elm) {
				RB_ROTATE_LEFT(head, parent, tmp);
				tmp = parent;
				parent = elm;
				elm = tmp;
			}
			RB_SET_BLACKRED(parent, gparent);
			RB_ROTATE_RIGHT(head, gparent, tmp);
		} else {
			tmp = RB_LEFT(gparent);
			if (tmp && RB_COLOR(tmp) == RB_RED) {
				RB_COLOR(tmp) = RB_BLACK;
				RB_SET_BLACKRED(parent, gparent);
				elm = gparent;
				continue;
			}
			if (RB_LEFT(parent) == elm) {
				RB_ROTATE_RIGHT(head, parent, tmp);
				tmp = parent;
				parent = elm;
				elm = tmp;
			}
			RB_SET_BLACKRED(parent, gparent);
			RB_ROTATE_LEFT(head, gparent, tmp);
		}
	}
	RB_COLOR(head->rb_node) = RB_BLACK;
}
Beispiel #2
0
/* Note name changed. Guess why :) */
void rb_erase(struct rb_node *elm, struct rb_root *head) {
	struct rb_node *child, *parent, *old = elm;
	int color;
	if (RB_LEFT(elm) == NULL) {
		child = RB_RIGHT(elm);
	} else if (RB_RIGHT(elm) == NULL) {
		child = RB_LEFT(elm);
	} else {
		struct rb_node *left;
		elm = RB_RIGHT(elm);
		while ((left = RB_LEFT(elm))) {
			elm = left;
		}
		child = RB_RIGHT(elm);
		parent = RB_PARENT(elm);
		color = RB_COLOR(elm);
		if (child) {
			RB_PARENT(child) = parent;
		}
		if (parent) {
			if (RB_LEFT(parent) == elm) {
				RB_LEFT(parent) = child;
			} else {
				RB_RIGHT(parent) = child;
			}
			RB_AUGMENT(parent);
		} else {
			RB_HEAD(head) = child;
		}
		if (RB_PARENT(elm) == old) {
			parent = elm;
		}
		*(elm) = *(old);
		if (RB_PARENT(old)) {
			if (RB_LEFT(RB_PARENT(old)) == old) {
				RB_LEFT(RB_PARENT(old)) = elm;
			} else {
				RB_RIGHT(RB_PARENT(old)) = elm;
			}
			RB_AUGMENT(RB_PARENT(old));
		} else {
			RB_HEAD(head) = elm;
		}
		RB_PARENT(RB_LEFT(old)) = elm;
		if (RB_RIGHT(old)) {
			RB_PARENT(RB_RIGHT(old)) = elm;
		}
		if (parent) {
			left = parent;
			do {
				RB_AUGMENT(left);
			} while ((left = RB_PARENT(left)));
		}
		goto color;
	}
	parent = RB_PARENT(elm);
	color = RB_COLOR(elm);
	if (child) {
		RB_PARENT(child) = parent;
	}
	if (parent) {
		if (RB_LEFT(parent) == elm) {
			RB_LEFT(parent) = child;
		} else {
			RB_RIGHT(parent) = child;
		}
		RB_AUGMENT(parent);
	} else {
		RB_HEAD(head) = child;
	}
color:
	if (color == RB_BLACK) {
		rb_remove_color(head, parent, child);
	}
}
Beispiel #3
0
static void rb_remove_color(struct rb_root *head, struct rb_node *parent,
			    struct rb_node *elm) {
	struct rb_node *tmp;
	while ((elm == NULL || RB_COLOR(elm) == RB_BLACK) &&
	    elm != RB_HEAD(head)) {
		if (RB_LEFT(parent) == elm) {
			tmp = RB_RIGHT(parent);
			if (RB_COLOR(tmp) == RB_RED) {
				RB_SET_BLACKRED(tmp, parent);
				RB_ROTATE_LEFT(head, parent, tmp);
				tmp = RB_RIGHT(parent);
			}
			if ((RB_LEFT(tmp) == NULL ||
			    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
			    (RB_RIGHT(tmp) == NULL ||
			    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
				RB_COLOR(tmp) = RB_RED;
				elm = parent;
				parent = RB_PARENT(elm);
			} else {
				if (RB_RIGHT(tmp) == NULL ||
				    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK) {
					struct rb_node *oleft;
					if ((oleft = RB_LEFT(tmp)))
						RB_COLOR(oleft) = RB_BLACK;
					RB_COLOR(tmp) = RB_RED;
					RB_ROTATE_RIGHT(head, tmp, oleft);
					tmp = RB_RIGHT(parent);
				}
				RB_COLOR(tmp) = RB_COLOR(parent);
				RB_COLOR(parent) = RB_BLACK;
				if (RB_RIGHT(tmp))
					RB_COLOR(RB_RIGHT(tmp)) = RB_BLACK;
				RB_ROTATE_LEFT(head, parent, tmp);
				elm = RB_HEAD(head);
				break;
			}
		} else {
			tmp = RB_LEFT(parent);
			if (RB_COLOR(tmp) == RB_RED) {
				RB_SET_BLACKRED(tmp, parent);
				RB_ROTATE_RIGHT(head, parent, tmp);
				tmp = RB_LEFT(parent);
			}
			if ((RB_LEFT(tmp) == NULL ||
			    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
			    (RB_RIGHT(tmp) == NULL ||
			    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
				RB_COLOR(tmp) = RB_RED;
				elm = parent;
				parent = RB_PARENT(elm);
			} else {
				if (RB_LEFT(tmp) == NULL ||
				    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) {
					struct rb_node *oright;
					if ((oright = RB_RIGHT(tmp)))
						RB_COLOR(oright) = RB_BLACK;
					RB_COLOR(tmp) = RB_RED;
					RB_ROTATE_LEFT(head, tmp, oright);
					tmp = RB_LEFT(parent);
				}
				RB_COLOR(tmp) = RB_COLOR(parent);
				RB_COLOR(parent) = RB_BLACK;
				if (RB_LEFT(tmp))
					RB_COLOR(RB_LEFT(tmp)) = RB_BLACK;
				RB_ROTATE_RIGHT(head, parent, tmp);
				elm = RB_HEAD(head);
				break;
			}
		}
	}
	if (elm)
		RB_COLOR(elm) = RB_BLACK;
}