/* 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; }
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; }