/** @brief Validate and fix-up tree properties for a new insert/colored node * * This routine checks and fixes the Red-Black Tree properties based on * @a the_node being just added to the tree. * * @note It does NOT disable interrupts to ensure the atomicity of the * append operation. */ static void _RBTree_Validate_insert( RBTree_Node *the_node ) { RBTree_Node *parent = _RBTree_Parent( the_node ); RBTree_Color parentcolor; RBTree_Node *grandparent = _RBTree_Parent_and_color( parent, &parentcolor ); /* note: the insert root case is handled already */ /* if the parent is black, nothing needs to be done * otherwise may need to loop a few times */ while ( parentcolor == RBT_RED ) { /* The root is black, so the grandparent must exist */ RBTree_Node *uncle = _RBTree_Sibling( parent, grandparent ); RBTree_Node *grandgrandparent = _RBTree_Parent( grandparent ); /* * If uncle exists and is red, repaint uncle/parent black and grandparent * red. */ if ( uncle != NULL && _RBTree_Color( uncle ) == RBT_RED ) { _RBTree_Set_parent_and_color( parent, grandparent, RBT_BLACK ); _RBTree_Set_parent_and_color( uncle, grandparent, RBT_BLACK ); _RBTree_Set_parent_and_color( grandparent, grandgrandparent, RBT_RED ); the_node = grandparent; parent = grandgrandparent; grandparent = _RBTree_Parent_and_color( parent, &parentcolor ); if ( grandparent == NULL ) break; } else { /* If uncle does not exist or is black */ RBTree_Direction dir = _RBTree_Direction( the_node, parent ); RBTree_Direction parentdir = _RBTree_Direction( parent, grandparent ); /* ensure node is on the same branch direction as parent */ if ( dir != parentdir ) { RBTree_Node *oldparent = parent; parent = the_node; the_node = oldparent; _RBTree_Rotate( oldparent, parentdir ); } _RBTree_Set_color( parent, RBT_BLACK ); _RBTree_Set_parent_and_color( grandparent, grandgrandparent, RBT_RED ); /* now rotate grandparent in the other branch direction (toward uncle) */ _RBTree_Rotate( grandparent, _RBTree_Opposite_direction( parentdir ) ); grandparent = _RBTree_Parent( parent ); break; } } if ( grandparent == NULL ) _RBTree_Set_parent_and_color( the_node, parent, RBT_BLACK ); }
/** @brief Validate and fix-up tree properties for a new insert/colored node * * This routine checks and fixes the Red-Black Tree properties based on * @a the_node being just added to the tree. * * @note It does NOT disable interrupts to ensure the atomicity of the * append operation. */ void _RBTree_Validate_insert_unprotected( RBTree_Node *the_node ) { RBTree_Node *u,*g; /* note: the insert root case is handled already */ /* if the parent is black, nothing needs to be done * otherwise may need to loop a few times */ while (_RBTree_Is_red(_RBTree_Parent(the_node))) { u = _RBTree_Parent_sibling(the_node); g = the_node->parent->parent; /* if uncle is red, repaint uncle/parent black and grandparent red */ if(_RBTree_Is_red(u)) { the_node->parent->color = RBT_BLACK; u->color = RBT_BLACK; g->color = RBT_RED; the_node = g; } else { /* if uncle is black */ RBTree_Direction dir = the_node != the_node->parent->child[0]; RBTree_Direction pdir = the_node->parent != g->child[0]; /* ensure node is on the same branch direction as parent */ if (dir != pdir) { _RBTree_Rotate(the_node->parent, pdir); the_node = the_node->child[pdir]; } the_node->parent->color = RBT_BLACK; g->color = RBT_RED; /* now rotate grandparent in the other branch direction (toward uncle) */ _RBTree_Rotate(g, (1-pdir)); } } if(!the_node->parent->parent) the_node->color = RBT_BLACK; }