Пример #1
0
// x must be already open for writing
// x must have a parent
static void _right_rotate(ptst_t *ptst, stm_tx *tx, stm_blk *sb, stm_blk *xb, node_t *x) {
    stm_blk *lb, *lrb, *pb;
    node_t *l, *lr, *p;

    lb = GET_LEFT(x);
    pb = GET_PARENT(x);

    l = WRITE_OBJ(lb);
    p = WRITE_OBJ(pb);
    lrb = GET_RIGHT(l);

    x = WRITE_OBJ(xb);
    SET_LEFT(x, lrb);
    if (lrb != NULL ) {
        lr = WRITE_OBJ(lrb);
        SET_PARENT(lr, xb);
    }

    SET_PARENT(l, pb);
    if(pb == NULL) {
        set_t * s = (set_t*) WRITE_OBJ(sb);
        SET_ROOT(s, lb);
    } else if ( xb == GET_RIGHT(p) ) {
        SET_RIGHT(p, lb);
    } else {
        SET_LEFT(p, lb);
    }
    SET_RIGHT(l, xb);
    SET_PARENT(x, lb);
}//right_rotate
Пример #2
0
// x must be already open for writing
// x must have a parent
static void _left_rotate(ptst_t *ptst, stm_tx *tx, stm_blk *sb, stm_blk *xb, node_t *x) {
    stm_blk *rb, *rlb, *pb;
    node_t *r, *rl, *p;

    rb = GET_RIGHT(x);
    pb = GET_PARENT(x);

    r = WRITE_OBJ(rb);
    p = WRITE_OBJ(pb);
    rlb = GET_LEFT(r);

    x = WRITE_OBJ(xb);
    SET_RIGHT(x, rlb);
    if ( rlb != NULL ) {
        rl = WRITE_OBJ(rlb);
        SET_PARENT(rl, xb);
    }

    SET_PARENT(r, pb);
    if(pb == NULL) {
        set_t * s = (set_t*) WRITE_OBJ(sb);
        SET_ROOT(s, rb);
    } else if ( GET_LEFT(p) == xb ) {
        SET_LEFT(p, rb);
    } else {
        SET_RIGHT(p, rb);
    }
    SET_LEFT(r, xb);
    SET_PARENT(x, rb);
}//left_rotate
Пример #3
0
static void remove_obj(uint16_t object)
{
  uint16_t parent = PARENT(object);

  if(parent != 0)
  {
    uint16_t child = CHILD(parent);

    /* Direct child */
    if(child == object)
    {
      /* parent->child = parent->child->sibling */
      SET_CHILD(parent, SIBLING(child));
    }
    else
    {
      while(SIBLING(child) != object)
      {
        /* child = child->sibling */
        child = SIBLING(child);
      }

      /* Now the sibling of child is the object to remove. */

      /* child->sibling = child->sibling->sibling */
      SET_SIBLING(child, SIBLING(SIBLING(child)));
    }

    /* object->parent = 0 */
    SET_PARENT(object, 0);

    /* object->sibling = 0 */
    SET_SIBLING(object, 0);
  }
}
Пример #4
0
BSTNode* CC RotateRightAtXLeftAtY ( BSTNode *y, BSTNode *x )
{
    BSTNode *w = x -> child [ 0 ];
    BSTNode *z = w -> child [ 1 ];
    x -> child [ 0 ] = z;
    if ( z != 0 )
        SET_PARENT ( z, x );
    z = w -> child [ 0 ];
    w -> child [ 1 ] = x;
    y -> child [ 1 ] = z;
    w -> child [ 0 ] = y;
        
    switch ( BALANCE ( w ) )
    {
    case 0:
        w -> par = PARENT ( y );
        x -> par = w;
        y -> par = w;
        break;
    case LEFT:
        w -> par = PARENT ( y );
        SET_PARBAL ( x, w, RIGHT );
        y -> par = w;
        break;
    case RIGHT:
        w -> par = PARENT ( y );
        x -> par = w;
        SET_PARBAL ( y, w, LEFT );
        break;
    }

    /* patch parent link */
    if ( z != 0 )
        SET_PARENT ( z, y );

    return w;
}
Пример #5
0
BSTNode* CC RotateLeftAtY ( BSTNode *y, BSTNode *x )
{
    BSTNode *w = x;
    BSTNode *z = x -> child [ 0 ];
    y -> child [ 1 ] = z;
    x -> child [ 0 ] = y;
    x -> par = PARENT ( y );
    y -> par = x;

    /* patch parent link */
    if ( z != 0 )
        SET_PARENT ( z, y );

    return w;
}
Пример #6
0
/* create_block_tree:
 * Construct block tree by peeling nodes from block list in state.
 * When done, return root. The block list is empty
 * FIX: use largest block as root
 */
block_t *createBlocktree(Agraph_t * g, circ_state * state)
{
    block_t *bp;
    block_t *next;
    block_t *root;
    int min;
    /* int        ordercnt; */

    find_blocks(g, state);

    bp = state->bl.first;	/* if root chosen, will be first */
    /* Otherwise, just pick first as root */
    root = bp;

    /* Find node with minimum VAL value to find parent block */
    /* FIX: Should be some way to avoid search below.               */
    /* ordercnt = state->orderCount;  */
    for (bp = bp->next; bp; bp = next) {
	Agnode_t *n;
	Agnode_t *parent;
	Agnode_t *child;
	Agraph_t *subg = bp->sub_graph;

	child = n = agfstnode(subg);
	min = VAL(n);
	parent = PARENT(n);
	for (n = agnxtnode(subg, n); n; n = agnxtnode(subg, n)) {
	    if (VAL(n) < min) {
		child = n;
		min = VAL(n);
		parent = PARENT(n);
	    }
	}
	SET_PARENT(parent);
	CHILD(bp) = child;
	next = bp->next;	/* save next since list insertion destroys it */
	appendBlock(&(BLOCK(parent)->children), bp);
    }
    initBlocklist(&state->bl);	/* zero out list */
    return root;
}
Пример #7
0
static
void CC BTUnlink ( BSTNode **root, BSTNode *p, int dir )
{
    BSTNode *q = PARENT ( p );
    BSTNode *l, *r = p -> child [ 1 ];
    if ( r == 0 )
    {
      /* no right child - simple unlink */
        l = p -> child [ 0 ];
        if ( q == 0 )
            * root = l;
        else
            q -> child [ dir ] = l;
        if ( l != 0 )
            SET_PARENT ( l, q );
    }
    else
    {
      /* have a right child - check its left */
        l = r -> child [ 0 ];
        if ( l == 0 )
        {
            l = p -> child [ 0 ];
            r -> child [ 0 ] = l;

            /* take not only p's parent ( q )
            // but its balance as well */
            r -> par = p -> par;

            if ( q == 0 )
                * root = r;
            else
                q -> child [ dir ] = r;

            if ( l != 0 )
                SET_PARENT ( l, r );

            /* artificially reset for following */
            q = r;
            dir = 1;
        }

        /* involves some work */
        else
        {
	  /* find smallest subsequent item */
            r = l -> child [ 0 ];
            while ( r != 0 )
            {
                l = r;
                r = l -> child [ 0 ];
            }

            /* unlink it */
            r = PARENT ( l );
            r -> child [ 0 ] = l -> child [ 1 ];

            /* take over doomed node */
            l -> child [ 0 ] = p -> child [ 0 ];
            l -> child [ 1 ] = p -> child [ 1 ];

            /* take not only p's parent ( q )
            // but its balance as well */
            l -> par = p -> par;

            /* new king pin */
            if ( q == 0 )
                * root = l;
            else
                q -> child [ dir ] = l;

            /* update parent links */
            q = l -> child [ 0 ];
            if ( q != 0 )
                SET_PARENT ( q, l );
            q = l -> child [ 1 ];
            SET_PARENT ( q, l );
            q = r -> child [ 0 ];
            if ( q != 0 )
                SET_PARENT ( q, r );

            q = r;
            dir = 0;
        }
    }

    /* now - rebalance what we've undone */
    if ( q != 0 )
        RebalanceAfterUnlink ( root, q, dir );
}
Пример #8
0
/* BSTreeUnlink
 *  removes a node from tree
 */
static
void CC RebalanceAfterUnlink ( BSTNode **root, BSTNode *q, int dir )
{
    while ( q != 0 )
    {
        BSTNode *w, *x, *y = q;
        q = PARENT ( q );

        if ( ! dir )
        {
            if ( q && q -> child [ 1 ] == y )
                dir = 1;

            /* simulate an increment of balance */
            switch ( BALANCE ( y ) )
            {
            case 0:
                SET_BALANCE ( y, RIGHT );
                return;
            case LEFT:
                CLR_BALANCE ( y, LEFT );
                break;
            case RIGHT:
                /* y has just become ++ */
                x = y -> child [ 1 ];
                if ( LEFT_HEAVY ( x ) )
                {
                    w = RotateRightAtXLeftAtY ( y, x );
                    if ( q == 0 )
                        * root = w;
                    else
                        q -> child [ dir ] = w;
                }
                else
                {
                    w = y -> child [ 1 ] = x -> child [ 0 ];
                    x -> child [ 0 ] = y;
                    SET_PARENT ( x, q );
                    SET_PARENT ( y, x );
                    if ( w != 0 )
                        SET_PARENT ( w, y );
                    if ( q == 0 )
                        * root = x;
                    else
                        q -> child [ dir ] = x;
                    if ( BALANCE ( x ) == 0 )
                    {
                        SET_BALANCE ( x, LEFT );
                        SET_PARBAL ( y, x, RIGHT );
                        return;
                    }
                    ZERO_BALANCE ( x );
                    ZERO_BALANCE ( y );
                    /* y = x; */
                }
                break;
            }
        }

        /* symmetric case */
        else
        {
            if ( q && q -> child [ 0 ] == y )
                dir = 0;

            switch ( BALANCE ( y ) )
            {
            case 0:
                SET_BALANCE ( y, LEFT );
                return;
            case LEFT:
                /* y has just become -- */
                x = y -> child [ 0 ];
                if ( RIGHT_HEAVY ( x ) )
                {
                    w = RotateLeftAtXRightAtY ( y, x );
                    if ( q == 0 )
                        * root = w;
                    else
                        q -> child [ dir ] = w;
                }
                else
                {
                    w = x -> child [ 1 ];
                    y -> child [ 0 ] = w;
                    x -> child [ 1 ] = y;
                    SET_PARENT ( x, q );
                    SET_PARENT ( y, x );
                    if ( w != 0 )
                        SET_PARENT ( w, y );
                    if ( q == 0 )
                        * root = x;
                    else
                        q -> child [ dir ] = x;
                    if ( BALANCE ( x ) == 0 )
                    {
                        SET_BALANCE ( x, RIGHT );
                        SET_PARBAL ( y, x, LEFT );
                        return;
                    }
                    ZERO_BALANCE ( x );
                    ZERO_BALANCE ( y );
                    /* y = x; */
                }
                break;
            case RIGHT:
                CLR_BALANCE ( y, RIGHT );
                break;
            }
        }
    }
}