Пример #1
0
/** @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 );
}
Пример #2
0
/** @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;
}