/* * A D D _ T O _ P R I O Q ( ) * */ void add_to_prioq (void *v, int depth) { struct vertex *vp = (struct vertex *) v; BU_CKMAG(vp, VERTEX_MAGIC, "vertex"); BU_CKMAG(vp -> v_bridge, BRIDGE_MAGIC, "bridge"); bu_rb_insert(prioq, (void *) (vp -> v_bridge)); }
/* * Perform one rewrite step on the root of a Boolean tree * * This function has two parameters: a Boolean-tree node and a rule * number. Do_bool_tree_rewrite() applies the specified rewrite rule * to the subtree rooted at the specified node. */ static void do_bool_tree_rewrite (struct bool_tree_node *rp, int rule_nm) { struct bool_tree_node *left; /* Left child of the root */ struct bool_tree_node *right; /* Right " " " " */ struct bool_tree_node *a, *b, *c; /* Subtrees unchanged */ BU_CKMAG(rp, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); left = bt_opd(rp, BT_LEFT); right = bt_opd(rp, BT_RIGHT); BU_CKMAG(left, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); BU_CKMAG(right, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); switch (rule_nm) { case 0: return; case 1: /* a U (b U c) : (a U b) U c */ case 5: /* a - (b U c) : (a - b) - c */ case 6: /* a * (b * c) : (a * b) * c */ case 8: /* a * (b - c) : (a * b) - c */ a = left; b = bt_opd(right, BT_LEFT); c = bt_opd(right, BT_RIGHT); bt_opd(rp, BT_LEFT) = right; bt_opd(bt_opd(rp, BT_LEFT), BT_LEFT) = a; bt_opd(bt_opd(rp, BT_LEFT), BT_RIGHT) = b; bt_opd(rp, BT_RIGHT) = c; bt_opn(bt_opd(rp, BT_LEFT)) = bt_opn(rp); if ((rule_nm == 5) || (rule_nm == 8)) bt_opn(rp) = OPN_DIFFERENCE; break; case 2: /* (a U b) * c : (a * c) U (b * c) */ case 4: /* (a U b) - c : (a - c) U (b - c) */ a = bt_opd(left, BT_LEFT); b = bt_opd(left, BT_RIGHT); c = right; bt_opn(left) = bt_opn(rp); bt_opd(left, BT_RIGHT) = dup_bool_tree(c); bt_opn(rp) = OPN_UNION; bt_opd(rp, BT_RIGHT) = bt_create_internal(bt_opn(left), b, c); break; case 3: /* a * (b U c) : (a * b) U (a * c) */ case 7: /* a - (b * c) : (a - b) U (a - c) */ case 9: /* a - (b - c) : (a - b) U (a * c) */ a = left; b = bt_opd(right, BT_LEFT); c = bt_opd(right, BT_RIGHT); bt_opd(rp, BT_LEFT) = bt_create_internal(bt_opn(rp), a, b); bt_opn(rp) = OPN_UNION; bt_opn(right) = (rule_nm == 7) ? OPN_DIFFERENCE : OPN_INTERSECTION; bt_opd(right, BT_LEFT) = dup_bool_tree(a); break; default: bu_exit (1, "Reached %s:%d. This shouldn't happen\n", __FILE__, __LINE__); } }
/* * C O M P A R E _ V E R T E X _ I N D I C E S ( ) */ int compare_vertex_indices (void *v1, void *v2) { struct vertex *vert1 = (struct vertex *) v1; struct vertex *vert2 = (struct vertex *) v2; BU_CKMAG(vert1, VERTEX_MAGIC, "vertex"); BU_CKMAG(vert2, VERTEX_MAGIC, "vertex"); return (vert1 -> v_index - vert2 -> v_index); }
/* * D E L _ F R O M _ P R I O Q ( ) * */ void del_from_prioq (struct vertex *vp) { BU_CKMAG(vp, VERTEX_MAGIC, "vertex"); BU_CKMAG(vp -> v_bridge, BRIDGE_MAGIC, "bridge"); if (debug) bu_log("del_from_prioq(<x%x>... bridge <x%x> %d)\n", vp, vp -> v_bridge, vp -> v_bridge -> b_index); if (bu_rb_search(prioq, PRIOQ_INDEX, (void *) (vp -> v_bridge)) == NULL) { bu_exit(1, "del_from_prioq: Cannot find bridge <x%x>.", vp -> v_bridge); } bu_rb_delete(prioq, PRIOQ_INDEX); }
/** * Restore the red-black properties of a red-black tree after the * splicing out of a node * * This function has three parameters: the tree to be fixed up, the * node where the trouble occurs, and the order. _rb_fixup() is an * implementation of the routine RB-DELETE-FIXUP on p. 274 of Cormen * et al. (p. 326 in the paperback version of the 2009 edition). */ HIDDEN void _rb_fixup(struct bu_rb_tree *tree, struct bu_rb_node *node, int order) { int direction; struct bu_rb_node *parent; struct bu_rb_node *w; BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); BU_CKMAG(node, BU_RB_NODE_MAGIC, "red-black node"); RB_CKORDER(tree, order); while ((node != RB_ROOT(tree, order)) && (RB_GET_COLOR(node, order) == RB_BLK)) { parent = RB_PARENT(node, order); if (node == RB_LEFT_CHILD(parent, order)) direction = RB_LEFT; else direction = RB_RIGHT; w = RB_OTHER_CHILD(parent, order, direction); if (RB_GET_COLOR(w, order) == RB_RED) { RB_SET_COLOR(w, order, RB_BLK); RB_SET_COLOR(parent, order, RB_RED); RB_ROTATE(parent, order, direction); w = RB_OTHER_CHILD(parent, order, direction); } if ((RB_GET_COLOR(RB_CHILD(w, order, direction), order) == RB_BLK) && (RB_GET_COLOR(RB_OTHER_CHILD(w, order, direction), order) == RB_BLK)) { RB_SET_COLOR(w, order, RB_RED); node = parent; } else { if (RB_GET_COLOR(RB_OTHER_CHILD(w, order, direction), order) == RB_BLK) { RB_SET_COLOR(RB_CHILD(w, order, direction), order, RB_BLK); RB_SET_COLOR(w, order, RB_RED); RB_OTHER_ROTATE(w, order, direction); w = RB_OTHER_CHILD(parent, order, direction); } RB_SET_COLOR(w, order, RB_GET_COLOR(parent, order)); RB_SET_COLOR(parent, order, RB_BLK); RB_SET_COLOR(RB_OTHER_CHILD(w, order, direction), order, RB_BLK); RB_ROTATE(parent, order, direction); node = RB_ROOT(tree, order); } } RB_SET_COLOR(node, order, RB_BLK); }
/* * C O M P A R E _ B R I D G E _ I N D I C E S ( ) */ int compare_bridge_indices (void *v1, void *v2) { struct bridge *b1 = (struct bridge *) v1; struct bridge *b2 = (struct bridge *) v2; BU_CKMAG(b1, BRIDGE_MAGIC, "bridge"); BU_CKMAG(b2, BRIDGE_MAGIC, "bridge"); if (b1 -> b_index < b2 -> b_index) return -1; else if (b1 -> b_index == b2 -> b_index) return 0; else return 1; }
/** * Delete a node from one order of a red-black tree * * This function has three parameters: a tree, the node to delete, and * the order from which to delete it. _rb_delete() is an * implementation of the routine RB-DELETE on p. 273 of Cormen et * al. (p. 324 in the paperback version of the 2009 edition). */ HIDDEN void _rb_delete(struct bu_rb_tree *tree, struct bu_rb_node *node, int order) { struct bu_rb_node *y; /* The node to splice out */ struct bu_rb_node *parent; struct bu_rb_node *only_child; BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); BU_CKMAG(node, BU_RB_NODE_MAGIC, "red-black node"); RB_CKORDER(tree, order); if (UNLIKELY(tree->rbt_debug & BU_RB_DEBUG_DELETE)) bu_log("_rb_delete(%p, %p, %d): data=%p\n", (void*)tree, (void*)node, order, RB_DATA(node, order)); if ((RB_LEFT_CHILD(node, order) == RB_NULL(tree)) || (RB_RIGHT_CHILD(node, order) == RB_NULL(tree))) y = node; else y = rb_neighbor(node, order, SENSE_MAX); if (RB_LEFT_CHILD(y, order) == RB_NULL(tree)) only_child = RB_RIGHT_CHILD(y, order); else only_child = RB_LEFT_CHILD(y, order); parent = RB_PARENT(only_child, order) = RB_PARENT(y, order); if (parent == RB_NULL(tree)) RB_ROOT(tree, order) = only_child; else if (y == RB_LEFT_CHILD(parent, order)) RB_LEFT_CHILD(parent, order) = only_child; else RB_RIGHT_CHILD(parent, order) = only_child; /* * Splice y out if it's not node */ if (y != node) { (node->rbn_package)[order] = (y->rbn_package)[order]; ((node->rbn_package)[order]->rbp_node)[order] = node; } if (RB_GET_COLOR(y, order) == RB_BLK) _rb_fixup(tree, only_child, order); if (--(y->rbn_pkg_refs) == 0) rb_free_node(y); }
/** _ R B _ N E I G H B O R ( ) * * Return a node adjacent to a given red-black node * * This function has three parameters: the node of interest, the * order on which to do the search, and the sense (min or max, * which is to say predecessor or successor). _rb_neighbor() * returns a pointer to the adjacent node. This function is * modeled after the routine TREE-SUCCESSOR on p. 249 of Cormen et al. */ struct bu_rb_node *_rb_neighbor (struct bu_rb_node *node, int order, int sense) { struct bu_rb_node *child; struct bu_rb_node *parent; bu_rb_tree *tree; struct bu_rb_node *empty_node; BU_CKMAG(node, BU_RB_NODE_MAGIC, "red-black node"); tree = node -> rbn_tree; BU_RB_CKORDER(tree, order); empty_node = bu_rb_null(tree); child = (sense == SENSE_MIN) ? bu_rb_left_child(node, order) : bu_rb_right_child(node, order); if (child != empty_node) return (_rb_extreme(child, order, 1 - sense, empty_node)); parent = bu_rb_parent(node, order); while ((parent != empty_node) && (node == bu_rb_child(parent, order, sense))) { node = parent; parent = bu_rb_parent(parent, order); } /* Record the node with which we've been working */ bu_rb_current(tree) = parent; return (parent); }
/** _ R B _ E X T R E M E ( ) * * Find the minimum or maximum node in one order of a red-black tree * * This function has four parameters: the root of the tree, the * order, the sense (min or max), and the address to be understood * as the nil node pointer. _rb_extreme() returns a pointer to the * extreme node. */ static struct bu_rb_node *_rb_extreme (struct bu_rb_node *root, int order, int sense, struct bu_rb_node *empty_node) { struct bu_rb_node *child; bu_rb_tree *tree; if (root == empty_node) return (root); while (1) { BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node"); tree = root -> rbn_tree; BU_RB_CKORDER(tree, order); child = (sense == SENSE_MIN) ? bu_rb_left_child(root, order) : bu_rb_right_child(root, order); if (child == empty_node) break; root = child; } /* Record the node with which we've been working */ bu_rb_current(tree) = root; return (root); }
/** B U _ R B _ R A N K ( ) * * Determines the rank of a node in one order of a red-black tree * * This function has two parameters: the tree in which to search * and the order on which to do the searching. If the current node * is null, bu_rb_rank() returns 0. Otherwise, it returns the rank * of the current node in the specified order. bu_rb_rank() is an * implementation of the routine OS-RANK on p. 283 of Cormen et al. */ int bu_rb_rank (bu_rb_tree *tree, int order) { int rank; struct bu_rb_node *node; struct bu_rb_node *parent; struct bu_rb_node *root; BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); BU_RB_CKORDER(tree, order); if ((node = bu_rb_current(tree)) == bu_rb_null(tree)) return (0); root = bu_rb_root(tree, order); rank = bu_rb_size(bu_rb_left_child(node, order), order) + 1; while (node != root) { parent = bu_rb_parent(node, order); if (node == bu_rb_right_child(parent, order)) rank += bu_rb_size(bu_rb_left_child(parent, order), order) + 1; node = parent; } return (rank); }
void bu_semaphore_release(unsigned int i) { #if !defined(PARALLEL) && !defined(DEFINED_BU_SEMAPHORES) i = i; /* quellage */ return; /* No support on this hardware */ #else if (bu_semaphores == NULL) { /* Semaphores not initialized yet. Must be non-parallel */ return; } BU_CKMAG(bu_semaphores, BU_SEMAPHORE_MAGIC, "bu_semaphore"); if (i >= bu_nsemaphores) { fprintf(stderr, "bu_semaphore_release(%d): semaphore # exceeds max of %d\n", i, bu_nsemaphores - 1); exit(3); /* cannot call bu_exit() here */ } BU_CKMAG(&bu_semaphores[i], BU_SEMAPHORE_MAGIC, "bu_semaphore"); /* * Begin vendor-specific initialization sections. */ # ifdef SUNOS if (mutex_unlock(&bu_semaphores[i].mu)) { fprintf(stderr, "bu_semaphore_acquire(): mutex_unlock() failed on [%d]\n", i); bu_bomb("fatal semaphore acquisition failure"); } # endif # if defined(HAVE_PTHREAD_H) if (pthread_mutex_unlock(&bu_semaphores[i].mu)) { fprintf(stderr, "bu_semaphore_acquire(): pthread_mutex_unlock() failed on [%d]\n", i); bu_bomb("fatal semaphore acquisition failure"); } # endif # if defined(_WIN32) && !defined(__CYGWIN__) if (!ReleaseMutex(bu_semaphores[i].m)) { fprintf(stderr, "bu_semaphore_acquire(): ReleaseMutex() failed on [%d]\n", i); bu_bomb("fatal semaphore acquisition failure"); } # endif #endif }
/* * P R I N T _ B R I D G E ( ) * */ void print_bridge (struct bridge *bp) { BU_CKMAG(bp, BRIDGE_MAGIC, "bridge"); bu_log(" bridge <x%x> %d... <x%x> and <x%x>, weight = %g\n", bp, bp -> b_index, bp -> b_vert_civ, bp -> b_vert_unciv, bp -> b_weight); }
static void free_script(struct script_rec *srp) { BU_CKMAG(srp, SCRIPT_REC_MAGIC, "script record"); bu_vls_free(&(srp->sr_script)); bu_free((void *) srp, "script record"); }
int bu_rb_is_uniq(struct bu_rb_tree *tree, int order) { BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); RB_CKORDER(tree, order); return RB_GET_UNIQUENESS(tree, order); }
/* * Find an applicable rewrite for the root of a Boolean tree * * This function has one parameter: a Boolean-tree node. * Find_bool_tree_rewrite() compares the structure of the subtree * rooted at the specified node to the LHS's of the rewrite rules and * returns the number of the first match it finds. */ static int find_bool_tree_rewrite (struct bool_tree_node *rp) { int rule_nm; /* An applicable rule */ int lop; /* Left child's operation */ int rop; /* Right " " */ BU_CKMAG(rp, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); BU_CKMAG(bt_opd(rp, BT_LEFT), BOOL_TREE_NODE_MAGIC, "Boolean tree node"); BU_CKMAG(bt_opd(rp, BT_RIGHT), BOOL_TREE_NODE_MAGIC, "Boolean tree node"); lop = bt_opn(bt_opd(rp, BT_LEFT)); rop = bt_opn(bt_opd(rp, BT_RIGHT)); rule_nm = 0; switch (bt_opn(rp)) { case OPN_UNION: if (rop == OPN_UNION) rule_nm = 1; break; case OPN_INTERSECTION: if (lop == OPN_UNION) rule_nm = 2; else switch (rop) { case OPN_UNION: rule_nm = 3; break; case OPN_INTERSECTION: rule_nm = 6; break; case OPN_DIFFERENCE: rule_nm = 8; break; } break; case OPN_DIFFERENCE: if (lop == OPN_UNION) rule_nm = 4; else switch (rop) { case OPN_UNION: rule_nm = 5; break; case OPN_INTERSECTION: rule_nm = 7; break; case OPN_DIFFERENCE: rule_nm = 9; break; } break; default: bu_exit (1, "Reached %s:%d. This shouldn't happen\n", __FILE__, __LINE__); } return rule_nm; }
/* * The comparison callback for the red-black tree */ int compare_pixels(void *v1, void *v2) { struct pixel *p1 = (struct pixel *)v1; struct pixel *p2 = (struct pixel *)v2; int i; BU_CKMAG(p1, PIXEL_MAGIC, "pixel"); BU_CKMAG(p2, PIXEL_MAGIC, "pixel"); for (i = 0; i < pixel_size; ++i) { if (p1->p_color[i] < p2->p_color[i]) return -1; else if (p1->p_color[i] > p2->p_color[i]) return 1; } return 0; }
/* * C O M P A R E _ V E R T E X _ L A B E L S ( ) */ int compare_vertex_labels (void *v1, void *v2) { struct vertex *vert1 = (struct vertex *) v1; struct vertex *vert2 = (struct vertex *) v2; BU_CKMAG(vert1, VERTEX_MAGIC, "vertex"); BU_CKMAG(vert2, VERTEX_MAGIC, "vertex"); if (vert1 -> v_label == '\0') bu_exit (1, "compare_vertex_labels: null label in vertex <x%x> %d\n", vert1, vert1 -> v_index); if (vert2 -> v_label == '\0') bu_exit (1, "compare_vertex_labels: null label in vertex <x%x> %d\n", vert2, vert2 -> v_index); if (*(vert1 -> v_label) < *(vert2 -> v_label)) return -1; else if (*(vert1 -> v_label) > *(vert2 -> v_label)) return 1; else return (strcmp(vert1 -> v_label, vert2 -> v_label)); }
/** B U _ R B _ C U R R ( ) * * Return the current red-black node * * This function has two parameters: the tree and order in which * to find the current node. bu_rb_curr() returns a pointer to * the data in the current node, if it exists. Otherwise, * it returns NULL. */ void *bu_rb_curr (bu_rb_tree *tree, int order) { BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); BU_RB_CKORDER(tree, order); if (bu_rb_current(tree) == bu_rb_null(tree)) return (NULL); else return (bu_rb_data(bu_rb_current(tree), order)); }
/* * Duplicate a Boolean tree * * This function has one parameter: a Boolean-tree node. * Dup_bool_tree() recursively copies the subtree rooted at the * specified node and returns a pointer to the root of the copy. */ static struct bool_tree_node *dup_bool_tree (struct bool_tree_node *rp) { BU_CKMAG(rp, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); if (bt_is_leaf(rp)) return rp; else return (bt_create_internal(bt_opn(rp), dup_bool_tree(bt_opd(rp, BT_LEFT)), dup_bool_tree(bt_opd(rp, BT_RIGHT)))); }
void bu_rb_walk(struct bu_rb_tree *tree, int order, void (*visit)(void), int trav_type) { BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); RB_CKORDER(tree, order); rb_walk(tree, order, visit, WALK_DATA, trav_type); }
void print_pixel(void *p, int UNUSED(depth)) { int i; struct pixel *pp = (struct pixel *)p; BU_CKMAG(pp, PIXEL_MAGIC, "pixel"); for (i = 0; i < pixel_size; ++i) fprintf(outfp, "%3d ", pp->p_color[i]); fprintf(outfp, " %d\n", pp->p_count); }
/* * P R I N T _ V E R T E X ( ) * */ void print_vertex (void *v, int depth) { struct vertex *vp = (struct vertex *) v; struct neighbor *np; BU_CKMAG(vp, VERTEX_MAGIC, "vertex"); bu_log(" vertex <x%x> %d '%s' %s...\n", vp, vp -> v_index, vp -> v_label, vp -> v_civilized ? "civilized" : "uncivilized"); for (BU_LIST_FOR(np, neighbor, &(vp -> v_neighbors))) { BU_CKMAG(np, NEIGHBOR_MAGIC, "neighbor"); BU_CKMAG(np -> n_vertex, VERTEX_MAGIC, "vertex"); bu_log(" is a neighbor <x%x> of vertex <x%x> %d '%s' at cost %g\n", np, np -> n_vertex, np -> n_vertex -> v_index, np -> n_vertex -> v_label, np -> n_weight); } }
/* * E X T R A C T _ M I N ( ) * */ struct bridge *extract_min (void) { struct bridge *bp; bp = (struct bridge *) bu_rb_min(prioq, PRIOQ_WEIGHT); if (bp != BRIDGE_NULL) { BU_CKMAG(bp, BRIDGE_MAGIC, "bridge"); bu_rb_delete(prioq, PRIOQ_WEIGHT); } return (bp); }
/* * Successively rewrite the root of a Boolean tree * * This function has one parameter: a Boolean-tree node. * Convert_one_node() iteratively rewrites the subtree rooted at the * specified node until it no longer matches the LHS of any of the * rewrite rules. It returns the number of times a rewrite rule was * applied. */ static int convert_one_node (struct bool_tree_node *rp) { int lisp = 1; int rule_nm; int nm_rewrites; BU_CKMAG(rp, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); for (nm_rewrites = 0; rule_nm = find_bool_tree_rewrite(rp); ++nm_rewrites) do_bool_tree_rewrite(rp, rule_nm); return nm_rewrites; }
/** * Raise or lower the uniqueness flags for all the linear orders of a * red-black tree * * This function has two parameters: the tree, and the new value for * all the flags. */ HIDDEN void _rb_set_uniq_all(struct bu_rb_tree *tree, int new_value) { int nm_orders; int order; BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); new_value = (new_value != 0); nm_orders = tree->rbt_nm_orders; for (order = 0; order < nm_orders; ++order) RB_SET_UNIQUENESS(tree, order, new_value); }
/* * C O M P A R E _ B R I D G E _ W E I G H T S ( ) */ int compare_bridge_weights (void *v1, void *v2) { double delta; struct bridge *b1 = (struct bridge *) v1; struct bridge *b2 = (struct bridge *) v2; BU_CKMAG(b1, BRIDGE_MAGIC, "bridge"); BU_CKMAG(b2, BRIDGE_MAGIC, "bridge"); if (is_infinite_bridge(b1)) if (is_infinite_bridge(b2)) return 0; else return 1; else if (is_infinite_bridge(b2)) return -1; delta = b1 -> b_weight - b2 -> b_weight; return ((delta < 0.0) ? -1 : (delta == 0.0) ? 0 : 1); }
/** * Raise or lower the uniqueness flag for one linear order of a * red-black tree * * This function has three parameters: the tree, the order for which * to modify the flag, and the new value for the flag. _rb_set_uniq() * sets the specified flag to the specified value and returns the * previous value of the flag. */ HIDDEN int _rb_set_uniq(struct bu_rb_tree *tree, int order, int new_value) { int prev_value; BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree"); RB_CKORDER(tree, order); new_value = (new_value != 0); prev_value = RB_GET_UNIQUENESS(tree, order); RB_SET_UNIQUENESS(tree, order, new_value); return prev_value; }
/* * Convert a Boolean tree to GIFT-Boolean form. * * This function has one parameter: a Boolean-tree node. * Cvt_to_gift_bool() recursively rewrites the subtree rooted at the * specified node. It returns the number of times a rewrite rule was * applied. */ int cvt_to_gift_bool (struct bool_tree_node *rp) { int cnr; /* Cumulative number of rewrites */ int nr; /* Number of rewrites in this pass */ BU_CKMAG(rp, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); for (cnr = 0; nr = _cvt_to_gift_bool(rp); cnr += nr) { ; } return cnr; }
/* * Make one conversion pass through a Boolean tree * * This function has one parameter: a Boolean-tree node. * _cvt_to_gift_bool() recursively rewrites the subtree rooted at the * specified node. It returns the number of times a rewrite rule was * applied. */ static int _cvt_to_gift_bool (struct bool_tree_node *rp) { int nm_rewrites; BU_CKMAG(rp, BOOL_TREE_NODE_MAGIC, "Boolean tree node"); if (bt_is_leaf(rp)) return 0; nm_rewrites = convert_one_node(rp); nm_rewrites += _cvt_to_gift_bool(bt_opd(rp, BT_LEFT)); nm_rewrites += _cvt_to_gift_bool(bt_opd(rp, BT_RIGHT)); return nm_rewrites; }
/** * Search for a node in a red-black tree * * This function has four parameters: the root and order of the tree * in which to search, the comparison function, and a data block * containing the desired value of the key. On success, _rb_search() * returns a pointer to the discovered node. Otherwise, it returns * (tree->rbt_empty_node). */ HIDDEN struct bu_rb_node * _rb_search(struct bu_rb_node *root, int order_nm, int (*compare)(const void *, const void *), void *data) { int result; struct bu_rb_tree *tree; BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node"); tree = root->rbn_tree; RB_CKORDER(tree, order_nm); while (1) { if (root == RB_NULL(root->rbn_tree)) break; if ((result = compare(data, RB_DATA(root, order_nm))) == 0) break; else if (result < 0) root = RB_LEFT_CHILD(root, order_nm); else /* result > 0 */ root = RB_RIGHT_CHILD(root, order_nm); BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node"); } RB_CURRENT(tree) = root; return root; }