void _rb_insert_fix(struct rb_node *node) { struct rb_node *parent = node->rb_parent, *uncle; while(parent && (!parent->color)){ //parent.color = 0 red if(parent == parent->rb_parent->rb_left){ uncle = parent->rb_parent->rb_right; if(uncle && (!uncle->color)){ parent->color = uncle->color = 1; parent->rb_parent->color = 0; node = parent->rb_parent; parent = node->rb_parent; continue; }else{ //uncle is black 1 if(node == parent->rb_left){ parent->color = 1; parent->rb_parent->color = 0; _rb_rotate_right(parent->rb_parent); break; }else{ _rb_rotate_left(parent); node = parent; parent = node->rb_parent; continue; } } }else{ uncle = parent->rb_parent->rb_left; if(uncle && (!uncle->color)){ parent->color = uncle->color = 1; parent->rb_parent->color = 0; node = parent->rb_parent; parent = node->rb_parent; continue; }else{ if(node == parent->rb_right){ parent->color = 1; parent->rb_parent->color = 0; _rb_rotate_left(parent->rb_parent); break; }else{ _rb_rotate_right(parent); node = parent; parent = node->rb_parent; continue; } } } } }
/* * delete fix */ void _rb_del_fix(struct rb_node *node, struct rb_node *pa) { struct rb_node *parent = pa; while( (!node || node->color) && node != this_rb->root){ if(node == parent->rb_left){ struct rb_node *bro = parent->rb_right; if(bro && 0 == bro->color){//bro is not NULL bro->color = 1; parent->color = 0; _rb_rotate_left(parent); bro = parent->rb_right;//continue } if((!bro->rb_left || bro->rb_left->color) && (!bro->rb_right || bro->rb_right->color)){ bro->color = 0; node = parent; parent = node->rb_parent; }else{//one red in two of bro's childs if(!bro->rb_right || bro->rb_right->color){// if(bro->rb_left) bro->rb_left->color = 1; bro->color = 0; _rb_rotate_right(bro); bro = parent->rb_right; } bro->color = parent->color; parent->color = 1; if(bro->rb_right) bro->rb_right->color = 1; _rb_rotate_left(parent); node = this_rb->root; } }else{ struct rb_node *bro = parent->rb_left; if(bro && 0 == bro->color){ bro->color = 1; parent->color = 0; _rb_rotate_right(parent); bro = parent->rb_left; } if((!bro->rb_left || bro->rb_left->color) && (!bro->rb_right || bro->rb_right->color)){ bro->color = 0; node = parent; parent = node->rb_parent; }else{ if(!bro->rb_left || bro->rb_left->color){ if(bro->rb_right) bro->rb_right->color = 1; bro->color = 0; _rb_rotate_left(bro); bro = parent->rb_left; } bro->color = parent->color; parent->color = 1; if(bro->rb_left) bro->rb_left->color = 1; _rb_rotate_right(parent); node = this_rb->root; } } } if(node) node->color = 1; }
void rb_insert_color(struct rb_node *node, struct rb_root *root) { struct rb_node *parent, *gparent; while ((parent = rb_parent(node)) && rb_is_red(parent)) { gparent = rb_parent(parent); if (parent == gparent->rb_left) { { register struct rb_node *uncle = gparent->rb_right; if (uncle && rb_is_red(uncle)) { rb_set_black(uncle); rb_set_black(parent); rb_set_red(gparent); node = gparent; continue; } } if (parent->rb_right == node) { register struct rb_node *tmp; _rb_rotate_left(parent, root); tmp = parent; parent = node; node = tmp; } rb_set_black(parent); rb_set_red(gparent); _rb_rotate_right(gparent, root); } else { { register struct rb_node *uncle = gparent->rb_left; if (uncle && rb_is_red(uncle)) { rb_set_black(uncle); rb_set_black(parent); rb_set_red(gparent); node = gparent; continue; } } if (parent->rb_left == node) { register struct rb_node *tmp; _rb_rotate_right(parent, root); tmp = parent; parent = node; node = tmp; } rb_set_black(parent); rb_set_red(gparent); _rb_rotate_left(gparent, root); } } rb_set_black(root->rb_node); }
static void _rb_erase_color(struct rb_node *node, struct rb_node *parent, struct rb_root *root) { struct rb_node *other; while ((!node || rb_is_black(node)) && node != root->rb_node) { if (parent->rb_left == node) { other = parent->rb_right; if (rb_is_red(other)) { rb_set_black(other); rb_set_red(parent); _rb_rotate_left(parent, root); other = parent->rb_right; } if ((!other->rb_left || rb_is_black(other->rb_left)) && (!other->rb_right || rb_is_black(other->rb_right))) { rb_set_red(other); node = parent; parent = rb_parent(node); } else { if (!other->rb_right || rb_is_black(other->rb_right)) { rb_set_black(other->rb_left); rb_set_red(other); _rb_rotate_right(other, root); other = parent->rb_right; } rb_set_color(other, rb_color(parent)); rb_set_black(parent); rb_set_black(other->rb_right); _rb_rotate_left(parent, root); node = root->rb_node; break; } } else { other = parent->rb_left; if (rb_is_red(other)) { rb_set_black(other); rb_set_red(parent); _rb_rotate_right(parent, root); other = parent->rb_left; } if ((!other->rb_left || rb_is_black(other->rb_left)) && (!other->rb_right || rb_is_black(other->rb_right))) { rb_set_red(other); node = parent; parent = rb_parent(node); } else { if (!other->rb_left || rb_is_black(other->rb_left)) { rb_set_black(other->rb_right); rb_set_red(other); _rb_rotate_left(other, root); other = parent->rb_left; } rb_set_color(other, rb_color(parent)); rb_set_black(parent); rb_set_black(other->rb_left); _rb_rotate_right(parent, root); node = root->rb_node; break; } } } if (node) rb_set_black(node); }