static AOFF_RBTree_t * check_tree(Carrier_t* within_crr, enum AOFFSortOrder order, AOFF_RBTree_t* root, Uint size) { AOFF_RBTree_t *res = NULL; Sint blacks; Sint curr_blacks; AOFF_RBTree_t *x; Carrier_t* crr; Uint depth, max_depth, node_cnt; #ifdef PRINT_TREE print_tree(root); #endif ASSERT((within_crr && order >= FF_AOFF) || (!within_crr && order <= FF_AOFF)); if (!root) return res; x = root; ASSERT(IS_BLACK(x)); ASSERT(!x->parent); curr_blacks = 1; blacks = -1; depth = 1; max_depth = 0; node_cnt = 0; while (x) { if (!IS_LEFT_VISITED(x)) { SET_LEFT_VISITED(x); if (x->left) { x = x->left; ++depth; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (!IS_RIGHT_VISITED(x)) { SET_RIGHT_VISITED(x); if (x->right) { x = x->right; ++depth; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } ++node_cnt; if (depth > max_depth) max_depth = depth; if (within_crr) { crr = FBLK_TO_MBC(&x->hdr); ASSERT(crr == within_crr); ASSERT((char*)x > (char*)crr); ASSERT(((char*)x + AOFF_BLK_SZ(x)) <= ((char*)crr + CARRIER_SZ(crr))); } if (order == FF_BF) { AOFF_RBTree_t* y = x; AOFF_RBTree_t* nxt = LIST_NEXT(y); ASSERT(IS_TREE_NODE(x)); while (nxt) { ASSERT(IS_LIST_ELEM(nxt)); ASSERT(AOFF_BLK_SZ(nxt) == AOFF_BLK_SZ(x)); ASSERT(FBLK_TO_MBC(&nxt->hdr) == within_crr); ASSERT(LIST_PREV(nxt) == y); y = nxt; nxt = LIST_NEXT(nxt); } } if (IS_RED(x)) { ASSERT(IS_BLACK(x->right)); ASSERT(IS_BLACK(x->left)); } ASSERT(x->parent || x == root); if (x->left) { ASSERT(x->left->parent == x); ASSERT(cmp_blocks(order, x->left, x) < 0); ASSERT(x->left->max_sz <= x->max_sz); } if (x->right) { ASSERT(x->right->parent == x); ASSERT(cmp_blocks(order, x->right, x) > 0); ASSERT(x->right->max_sz <= x->max_sz); } ASSERT(x->max_sz >= AOFF_BLK_SZ(x)); ASSERT(x->max_sz == AOFF_BLK_SZ(x) || x->max_sz == (x->left ? x->left->max_sz : 0) || x->max_sz == (x->right ? x->right->max_sz : 0)); if (size && AOFF_BLK_SZ(x) >= size) { if (!res || cmp_blocks(order, x, res) < 0) { res = x; } } UNSET_LEFT_VISITED(x); UNSET_RIGHT_VISITED(x); if (IS_BLACK(x)) curr_blacks--; x = x->parent; --depth; } ASSERT(depth == 0 || (!root && depth==1)); ASSERT(curr_blacks == 0); ASSERT((1 << (max_depth/2)) <= node_cnt); UNSET_LEFT_VISITED(root); UNSET_RIGHT_VISITED(root); return res; }
static RBTree_t * check_tree(RBTree_t *root, int ao, Uint size) { RBTree_t *res = NULL; Sint blacks; Sint curr_blacks; RBTree_t *x; #ifdef PRINT_TREE print_tree(root, ao); #endif if (!root) return res; x = root; ASSERT(IS_BLACK(x)); ASSERT(!x->parent); curr_blacks = 1; blacks = -1; while (x) { if (!IS_LEFT_VISITED(x)) { SET_LEFT_VISITED(x); if (x->left) { x = x->left; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (!IS_RIGHT_VISITED(x)) { SET_RIGHT_VISITED(x); if (x->right) { x = x->right; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (IS_RED(x)) { ASSERT(IS_BLACK(x->right)); ASSERT(IS_BLACK(x->left)); } ASSERT(x->parent || x == root); if (x->left) { ASSERT(x->left->parent == x); if (ao) { ASSERT(BF_BLK_SZ(x->left) < BF_BLK_SZ(x) || (BF_BLK_SZ(x->left) == BF_BLK_SZ(x) && x->left < x)); } else { ASSERT(IS_TREE_NODE(x->left)); ASSERT(BF_BLK_SZ(x->left) < BF_BLK_SZ(x)); } } if (x->right) { ASSERT(x->right->parent == x); if (ao) { ASSERT(BF_BLK_SZ(x->right) > BF_BLK_SZ(x) || (BF_BLK_SZ(x->right) == BF_BLK_SZ(x) && x->right > x)); } else { ASSERT(IS_TREE_NODE(x->right)); ASSERT(BF_BLK_SZ(x->right) > BF_BLK_SZ(x)); } } if (size && BF_BLK_SZ(x) >= size) { if (ao) { if (!res || BF_BLK_SZ(x) < BF_BLK_SZ(res) || (BF_BLK_SZ(x) == BF_BLK_SZ(res) && x < res)) res = x; } else { if (!res || BF_BLK_SZ(x) < BF_BLK_SZ(res)) res = x; } } UNSET_LEFT_VISITED(x); UNSET_RIGHT_VISITED(x); if (IS_BLACK(x)) curr_blacks--; x = x->parent; } ASSERT(curr_blacks == 0); UNSET_LEFT_VISITED(root); UNSET_RIGHT_VISITED(root); return res; }
static AOFF_RBTree_t * check_tree(AOFF_RBTree_t* root, Uint size) { AOFF_RBTree_t *res = NULL; Sint blacks; Sint curr_blacks; AOFF_RBTree_t *x; #ifdef PRINT_TREE print_tree(root); #endif if (!root) return res; x = root; ASSERT(IS_BLACK(x)); ASSERT(!x->parent); curr_blacks = 1; blacks = -1; while (x) { if (!IS_LEFT_VISITED(x)) { SET_LEFT_VISITED(x); if (x->left) { x = x->left; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (!IS_RIGHT_VISITED(x)) { SET_RIGHT_VISITED(x); if (x->right) { x = x->right; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (IS_RED(x)) { ASSERT(IS_BLACK(x->right)); ASSERT(IS_BLACK(x->left)); } ASSERT(x->parent || x == root); if (x->left) { ASSERT(x->left->parent == x); ASSERT(x->left < x); ASSERT(x->left->max_sz <= x->max_sz); } if (x->right) { ASSERT(x->right->parent == x); ASSERT(x->right > x); ASSERT(x->right->max_sz <= x->max_sz); } ASSERT(x->max_sz >= BLK_SZ(x)); ASSERT(x->max_sz == BLK_SZ(x) || x->max_sz == (x->left ? x->left->max_sz : 0) || x->max_sz == (x->right ? x->right->max_sz : 0)); if (size && BLK_SZ(x) >= size) { if (!res || x < res) { res = x; } } UNSET_LEFT_VISITED(x); UNSET_RIGHT_VISITED(x); if (IS_BLACK(x)) curr_blacks--; x = x->parent; } ASSERT(curr_blacks == 0); UNSET_LEFT_VISITED(root); UNSET_RIGHT_VISITED(root); return res; }