Exemple #1
0
static void set_root_node(qrb_tree *tree_p, qrb_node *np)
{
	tree_p->root = np;
	if( np != NULL ){
		np->parent = NULL;
		MAKE_BLACK(np);
	}
}
Exemple #2
0
static
rbtree_node_t *
__tree_insert     (rbtree_t *T, PyObject *k, PyObject *v)
{
    rbtree_node_t *x = T->root;
    rbtree_node_t *y = T->nil;
    int            rc = 0;

    // Use the optimized function until we can't
    if (!PyString_CheckExact(k)) {
        T->cmp_func = rbtree_node_compare;
    }

    while (x != T->nil)
        {
            rc = COMPARE(T, k, x->key);
            y  = x;

            if (rc == 0)
                {
                    // force a value update
                    // XXX: (later) validate this?
                    Py_XDECREF(x->value);
                    x->value = v;
                    Py_INCREF(v);
                    return NULL;
                }
            if (rc  < 0) x = x->l;
            else x = x->r;
        }

    NEW(x, rbtree_node_t);
    x->key = k;
    x->value = v;
    x->p   = y;
    x->l   = T->nil;
    x->r   = T->nil;
    MAKE_BLACK(x);
    T->ct++;


    if (y == T->nil)
        {
            T->root = x;
            return x;
        }

    if (rc < 0)
        {
            y->l = x;
            return x;
        }

    {
        y->r = x;
        return x;
    }
}
Exemple #3
0
int
rbtree_init            (rbtree_t *T)
{
    NEW(T->nil, rbtree_node_t);
    memset(T->nil, 0, sizeof(rbtree_node_t));
    MAKE_BLACK(T->nil);
    T->nil->l = T->nil;
    T->nil->r = T->nil;
    T->nil->p = T->nil;
    T->root   = T->nil;
    T->ct     = 0;
    T->cmp_func = rbtree_node_compare_string;
    T->compare = Py_None;
    Py_INCREF(Py_None);

    return 0;
}
Exemple #4
0
static
void
__rb_del_fix(rbtree_t *T, rbtree_node_t *x)
{
    rbtree_node_t *w;

    while ((x != T->root) && (COLOR(x) == BLACK))
        {
            if (x == x->p->l)
                {
                    w = x->p->r;
                    if (COLOR(w) == RED)
                        {
                            MAKE_BLACK(w);
                            MAKE_RED  (x->p);
                            __rotate_left(T, x->p);
                            w = x->p->r;
                        }
                    if ((COLOR(w->l) == BLACK) && (COLOR(w->r) == BLACK))
                        {
                            MAKE_RED(w);
                            x = x->p;
                        }
                    else
                        {
                            if (COLOR(w->r) == BLACK)
                                {
                                    MAKE_BLACK(w->l);
                                    MAKE_RED  (w);
                                    __rotate_right(T, w);
                                    w = x->p->r;
                                }

                            w->color = COLOR(x->p);

                            MAKE_BLACK(x->p);
                            MAKE_BLACK(w->r);
                            __rotate_left(T, x->p);
                            x = T->root;
                            break;
                        }
                }
            else
                {
                    w = x->p->l;
                    if (COLOR(w) == RED)
                        {
                            MAKE_BLACK(w);
                            MAKE_RED  (x->p);
                            __rotate_right(T, x->p);
                            w = x->p->l;
                        }
                    if ((COLOR(w->l) == BLACK) && (COLOR(w->r) == BLACK))
                        {
                            MAKE_RED(w);
                            x = x->p;
                        }
                    else
                        {
                            if (COLOR(w->l) == BLACK)
                                {
                                    MAKE_BLACK(w->r);
                                    MAKE_RED  (w);
                                    __rotate_left(T, w);
                                    w = x->p->l;
                                }
                            w->color = COLOR(x->p);
                            MAKE_BLACK(x->p);
                            MAKE_BLACK(w->l);
                            __rotate_right(T, x->p);
                            x = T->root;
                            break;
                        }
                }
        }

    MAKE_BLACK(x);
}
Exemple #5
0
static
void
__rb_insert (rbtree_t *T, PyObject *k, PyObject *v)
{
    rbtree_node_t *x, *y;

    Py_INCREF(k);
    Py_INCREF(v);

    x = __tree_insert(T, k, v);
    if (x ==  NULL) {
        return;
    }


    MAKE_RED  (x);

    while ((x != T->root) && (COLOR(x->p) == RED))
	{
	    if (x->p == x->p->p->l)
		{
		    y = x->p->p->r;
		    if (COLOR(y) == RED)
			{
			    MAKE_BLACK(x->p);
			    MAKE_BLACK(y);
			    MAKE_RED  (x->p->p);
			    x = x->p->p;
			}
		    else
			{
			    if (x == x->p->r)
				{
				    x = x->p;
				    __rotate_left(T, x);
				}
			    MAKE_BLACK(x->p);
			    MAKE_RED  (x->p->p);
			    __rotate_right(T, x->p->p);
			    break;
			}
		}
	    else
		{
		    y = x->p->p->l;
		    if (COLOR(y) == RED)
			{
			    MAKE_BLACK(x->p);
			    MAKE_BLACK(y);
			    MAKE_RED  (x->p->p);
			    x = x->p->p;
			}
		    else
			{
			    if (x == x->p->l)
				{
				    x = x->p;
				    __rotate_right(T, x);
				}
			    MAKE_BLACK(x->p);
			    MAKE_RED  (x->p->p);
			    __rotate_left(T, x->p->p);
			    break;
			}
		}
	}

    MAKE_BLACK(T->root);
}
Exemple #6
0
static void rb_delete(qrb_tree *tree_p, qrb_node *n_p )
{
	qrb_node *c_p;		// the single non-leaf child
	qrb_node *parent;

	tree_p->node_count --;

	if( tree_p->node_count == 0 ){
		assert( IS_ROOT_NODE(n_p) );
		givbuf(n_p);
		tree_p->root = NULL;
		return;
	}

	if( n_p->left != NULL && n_p->right != NULL ){
//fprintf(stderr,"before calling binary_tree_delete:\n");
//dump_rb_node(n_p);
		n_p = binary_tree_delete(n_p);
//fprintf(stderr,"after calling binary_tree_delete:\n");
//dump_rb_node(n_p);
	} else if( IS_ROOT_NODE(n_p) ){
		// we are deleting a root node with only one child
		if( n_p->left != NULL ){
			set_root_node(tree_p,n_p->left);
		} else {
			set_root_node(tree_p,n_p->right);
		}
		givbuf(n_p);
		return;
	}

	assert( n_p->left == NULL || n_p->right == NULL );

	if( n_p->left != NULL )
		c_p = n_p->left;
	else	c_p = n_p->right;	// may be NULL


	// if c_p is null, then we need to keep a reference to the parent...
	parent=n_p->parent;
	replace_node(tree_p,n_p,c_p);


	if( IS_RED(n_p) ){
		givbuf(n_p);
		return;
	}
	
	// Now we can free n_p
	givbuf(n_p);

	if( IS_RED(c_p) ){
		MAKE_BLACK(c_p);
		return;
	}

	// Now we know the node in question is black and has no red child
	//assert( n_p->left != NULL && n_p->right != NULL );

	// Now we know that both n_p and c_p are black

	rebalance(tree_p,c_p,parent);
}
Exemple #7
0
static void rebalance(qrb_tree *tree_p, qrb_node *n_p, qrb_node *parent)
{
	qrb_node *s_p;		// sibling
	int c;

	if( n_p != NULL && IS_ROOT_NODE(n_p) ) return;	// wikipedia case 1

	assert(parent!=NULL);
	assert( IS_BLACK(n_p) );

	s_p = sibling(n_p,parent);	// we have to pass the parent because n_p may be NULL

	if( IS_RED(s_p) ){		// wikipedia case 2 : sibling is red
		MAKE_RED(/*n_p->*/parent);
		MAKE_BLACK(s_p);
		if( n_p == /*n_p->*/parent->left ){
			rotate_left(tree_p,s_p);
		} else {
			rotate_right(tree_p,s_p);
		}
		//assert(n_p!=NULL);
		s_p = sibling(n_p,parent);		// has changed
	}
	
	if( IS_BLACK(s_p) ){
		if( IS_BLACK(s_p->left) && IS_BLACK(s_p->right) ){
			// sibling and its children are black
			if( IS_BLACK(/*n_p->*/parent) ){
				// wikipedia case 3 - make the sibling red
				MAKE_RED(s_p);
				rebalance(tree_p,/*n_p->*/parent,parent->parent);
				return;
			} else {
				// wikipedia case 4
				MAKE_BLACK(/*n_p->*/parent);
				MAKE_RED(s_p);
				return;
			}
		}
		// remaining cases depend on which side S is on
		if( s_p == /*n_p->*/ parent->right ){
			// S on right - the case shown in wikipedia examples
			if( IS_RED(s_p->left) && IS_BLACK(s_p->right) ){
				// wikipedia case 5
				assert( IS_BLACK(s_p->right) );
				rotate_right(tree_p,s_p->left);
				MAKE_RED(s_p);
				MAKE_BLACK(s_p->parent);	// used to be s_p->left

				// N's sibling has changed
				s_p = sibling(n_p,parent);

				// goto case 6
			}
		} else {
			// sibling is left child - mirror case
			if( IS_RED(s_p->right) && IS_BLACK(s_p->left) ){
				// wikipedia case 5
				assert( IS_BLACK(s_p->left) );
				rotate_left(tree_p,s_p->right);
				MAKE_RED(s_p);
				MAKE_BLACK(s_p->parent);	// used to be s_p->left

				// N's sibling has changed
				s_p = sibling(n_p,parent);

				// goto case 6
			}
		}

		// fall-through to case 6
			
		if( s_p == /*n_p->*/parent->right ){
			// case 6 illustrated on wikipedia
			assert( IS_RED(s_p->right) );
			rotate_left(tree_p,s_p);
			// exchange colors - s_p is now the parent and the old parent is now its left child
			c = s_p->color;
			s_p->color = s_p->left->color;
			s_p->left->color = c;
			MAKE_BLACK(s_p->right);
		} else {
			// case 6, mirror condition
			assert( IS_RED(s_p->left) );
			rotate_right(tree_p,s_p);
			// exchange colors - s_p is now the parent and the old parent is now its left child
			c = s_p->color;
			s_p->color = s_p->right->color;
			s_p->right->color = c;
			MAKE_BLACK(s_p->left);
		}
	}
}
Exemple #8
0
qrb_node * _rb_insert_item(QSP_ARG_DECL  qrb_tree* tree_p, Item *ip )
{
	qrb_node * x_p;
	qrb_node * new_node_p;
	qrb_node * gp_p;	// grandparent
	qrb_node * u_p;	// uncle

	new_node_p = (qrb_node*) getbuf(sizeof(qrb_node));
//	new_node_p->key = key;
	new_node_p->data  = ip;
	new_node_p->left = NULL;
	new_node_p->right = NULL;
	MAKE_RED(new_node_p);

	binary_tree_insert(tree_p,new_node_p);

	x_p = new_node_p;

	while( 1 ){
		if( IS_ROOT_NODE(x_p) ){	// wikipedia case 1
			MAKE_BLACK(x_p);
			return new_node_p;
		}

		if( IS_BLACK(x_p->parent) ){	// wikipedia case 2
			return new_node_p;
		}

		gp_p = grandparent(x_p);
		assert( gp_p != NULL );

		u_p = uncle(x_p);

		// We know the parent is red

		if( IS_RED(u_p) ){	// wikipedia case 3
			MAKE_BLACK(x_p->parent);
			MAKE_BLACK(u_p);
			MAKE_RED(gp_p);
			x_p = gp_p;	// loop on grandparent
		} else {
			// uncle is black
			if( x_p == x_p->parent->left && x_p->parent == gp_p->left ){
				// wikipedia case 5, left child of a left child
				rotate_right(tree_p,x_p->parent);
				MAKE_BLACK(x_p->parent);
				// new uncle is old grandparent
				MAKE_RED(gp_p);
				return new_node_p;
			} else if( x_p == x_p->parent->right && x_p->parent == gp_p->right ){
				// wikipedia case 5 mirror image
				rotate_left(tree_p,x_p->parent);
				MAKE_BLACK(x_p->parent);
				// new uncle is old grandparent
				MAKE_RED(gp_p);
				return new_node_p;
			} else {
				// wikipedia case 4
				if( x_p == x_p->parent->right ){
					// right child of left child
					rotate_left(tree_p,x_p);
					x_p = x_p->left;
				} else {
					// left child of right child
					rotate_right(tree_p,x_p);
					x_p = x_p->right;
				}
			}
		}
	} // end tail recursion loop
	//MAKE_BLACK( RB_TREE_ROOT(tree) );

	// NOTREACHED ???
	/*
	tree_p->node_count ++;

	return new_node_p;
	 */
} // rb_insert