Пример #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;
}
Пример #2
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;
}