/* * Append a string representation of the entire node to orig and return it. * This is used to produce debugging information if check_redblack_tree() finds * a problem with a red-black binary tree. */ static char *append_node(char * orig, BtRbNode *pNode, int indent) { char buf[128]; int i; for( i=0; i<indent; i++ ){ orig = append_val(orig, " "); } sprintf(buf, "%p", pNode); orig = append_val(orig, buf); if( pNode ){ indent += 3; if( pNode->isBlack ){ orig = append_val(orig, " B \n"); }else{ orig = append_val(orig, " R \n"); } orig = append_node( orig, pNode->pLeft, indent ); orig = append_node( orig, pNode->pRight, indent ); }else{ orig = append_val(orig, "\n"); } return orig; }
void Pds_add_numval(pds_t *pds, const uint64_t value) { uint64_t i = value; if ((i & 0x8000000000000000LL) && (~i < 0x100000000LL)) { // Signed number. i = ~i; if (i <= 0x3) { // Shortcase for -1 to -4 append_val(pds, 0xFC | i); return; } else { append_val(pds, 0xF8); } } if (i < 0x80) { // Need top bit clear append_val(pds, i); } else if (i < 0x4000) { // Need top two bits clear append_val(pds, (i >> 8) | 0x80); append_val(pds, i & 0xFF); } else if (i < 0x200000) {
LFUNC bool get_next_dfs_val(tval_list *l, tnode *y,tvalue *v) { tvalue child,x ; tval_list newl ; newl.head=0 ; do { if(!pop_val(l,v)) return(FALSE) ; x= *v ; duel_get_struct_ptr_val(&x,"x-->y"); } while(x.u.lvalue==0) ; /* ignore null pointers */ while(eval_dot(y,&child,"-->",v,&x)) { set_search_symb_val("-->",&x,&child); /* makes x-->y[n] neatly */ append_val(&newl,&child); /* append to childs list */ } push_val_list(l,&newl); /* append new childs to stack */ return(TRUE); /* returns the popped value in v */ }
/* * Check the following properties of the red-black tree: * (1) - If a node is red, both of it's children are black * (2) - Each path from a given node to a leaf (NULL) node passes thru the * same number of black nodes * * If there is a problem, append a description (using append_val() ) to *msg. */ static void check_redblack_tree(BtRbTree * tree, char ** msg) { BtRbNode *pNode; /* 0 -> came from parent * 1 -> came from left * 2 -> came from right */ int prev_step = 0; pNode = tree->pHead; while( pNode ){ switch( prev_step ){ case 0: if( pNode->pLeft ){ pNode = pNode->pLeft; }else{ prev_step = 1; } break; case 1: if( pNode->pRight ){ pNode = pNode->pRight; prev_step = 0; }else{ prev_step = 2; } break; case 2: /* Check red-black property (1) */ if( !pNode->isBlack && ( (pNode->pLeft && !pNode->pLeft->isBlack) || (pNode->pRight && !pNode->pRight->isBlack) ) ){ char buf[128]; sprintf(buf, "Red node with red child at %p\n", pNode); *msg = append_val(*msg, buf); *msg = append_node(*msg, tree->pHead, 0); *msg = append_val(*msg, "\n"); } /* Check red-black property (2) */ { int leftHeight = 0; int rightHeight = 0; if( pNode->pLeft ){ leftHeight += pNode->pLeft->nBlackHeight; leftHeight += (pNode->pLeft->isBlack?1:0); } if( pNode->pRight ){ rightHeight += pNode->pRight->nBlackHeight; rightHeight += (pNode->pRight->isBlack?1:0); } if( leftHeight != rightHeight ){ char buf[128]; sprintf(buf, "Different black-heights at %p\n", pNode); *msg = append_val(*msg, buf); *msg = append_node(*msg, tree->pHead, 0); *msg = append_val(*msg, "\n"); } pNode->nBlackHeight = leftHeight; } if( pNode->pParent ){ if( pNode == pNode->pParent->pLeft ) prev_step = 1; else prev_step = 2; } pNode = pNode->pParent; break; default: assert(0); } } }