// 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
// 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
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); } }
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; }
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; }
/* 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; }
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 ); }
/* 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; } } } }