00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef lint
00036 static char const libbu_rb_delete_RCSid[] = "@(#) $Header: /cvsroot/brlcad/brlcad/src/libbu/rb_delete.c,v 14.14 2006/08/31 23:16:38 lbutler Exp $";
00037 #endif
00038
00039 #include "common.h"
00040
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <math.h>
00044
00045 #include "machine.h"
00046 #include "bu.h"
00047 #include "./rb_internals.h"
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 static void bu_rb_fixup (bu_rb_tree *tree, struct bu_rb_node *node, int order)
00061 {
00062 int direction;
00063 struct bu_rb_node *parent;
00064 struct bu_rb_node *w;
00065
00066 BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00067 BU_CKMAG(node, BU_RB_NODE_MAGIC, "red-black node");
00068 BU_RB_CKORDER(tree, order);
00069
00070 while ((node != bu_rb_root(tree, order))
00071 && (bu_rb_get_color(node, order) == BU_RB_BLACK))
00072 {
00073 parent = bu_rb_parent(node, order);
00074 if (node == bu_rb_left_child(parent, order))
00075 direction = BU_RB_LEFT;
00076 else
00077 direction = BU_RB_RIGHT;
00078
00079 w = bu_rb_other_child(parent, order, direction);
00080 if (bu_rb_get_color(w, order) == BU_RB_RED)
00081 {
00082 bu_rb_set_color(w, order, BU_RB_BLACK);
00083 bu_rb_set_color(parent, order, BU_RB_RED);
00084 bu_rb_rotate(parent, order, direction);
00085 w = bu_rb_other_child(parent, order, direction);
00086 }
00087 if ((bu_rb_get_color(bu_rb_child(w, order, direction), order)
00088 == BU_RB_BLACK)
00089 && (bu_rb_get_color(bu_rb_other_child(w, order, direction), order)
00090 == BU_RB_BLACK))
00091 {
00092 bu_rb_set_color(w, order, BU_RB_RED);
00093 node = parent;
00094 }
00095 else
00096 {
00097 if (bu_rb_get_color(bu_rb_other_child(w, order, direction),
00098 order)
00099 == BU_RB_BLACK)
00100 {
00101 bu_rb_set_color(bu_rb_child(w, order, direction), order,
00102 BU_RB_BLACK);
00103 bu_rb_set_color(w, order, BU_RB_RED);
00104 bu_rb_other_rotate(w, order, direction);
00105 w = bu_rb_other_child(parent, order, direction);
00106 }
00107 bu_rb_set_color(w, order, bu_rb_get_color(parent, order));
00108 bu_rb_set_color(parent, order, BU_RB_BLACK);
00109 bu_rb_set_color(bu_rb_other_child(w, order, direction),
00110 order, BU_RB_BLACK);
00111 bu_rb_rotate(parent, order, direction);
00112 node = bu_rb_root(tree, order);
00113 }
00114 }
00115 bu_rb_set_color(node, order, BU_RB_BLACK);
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 static void _rb_delete (bu_rb_tree *tree, struct bu_rb_node *node, int order)
00127 {
00128 struct bu_rb_node *y;
00129 struct bu_rb_node *parent;
00130 struct bu_rb_node *only_child;
00131
00132 BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00133 BU_CKMAG(node, BU_RB_NODE_MAGIC, "red-black node");
00134 BU_RB_CKORDER(tree, order);
00135
00136 if (tree -> rbt_debug & BU_RB_DEBUG_DELETE)
00137 bu_log("_rb_delete(%x,%x,%d): data=x%x\n",
00138 tree, node, order, bu_rb_data(node, order));
00139
00140 if ((bu_rb_left_child(node, order) == bu_rb_null(tree))
00141 || (bu_rb_right_child(node, order) == bu_rb_null(tree)))
00142 y = node;
00143 else
00144 y = _rb_neighbor(node, order, SENSE_MAX);
00145
00146 if (bu_rb_left_child(y, order) == bu_rb_null(tree))
00147 only_child = bu_rb_right_child(y, order);
00148 else
00149 only_child = bu_rb_left_child(y, order);
00150
00151 parent = bu_rb_parent(only_child, order) = bu_rb_parent(y, order);
00152 if (parent == bu_rb_null(tree))
00153 bu_rb_root(tree, order) = only_child;
00154 else if (y == bu_rb_left_child(parent, order))
00155 bu_rb_left_child(parent, order) = only_child;
00156 else
00157 bu_rb_right_child(parent, order) = only_child;
00158
00159
00160
00161
00162 if (y != node)
00163 {
00164 (node -> rbn_package)[order] = (y -> rbn_package)[order];
00165 ((node -> rbn_package)[order] -> rbp_node)[order] = node;
00166 }
00167
00168 if (bu_rb_get_color(y, order) == BU_RB_BLACK)
00169 bu_rb_fixup(tree, only_child, order);
00170
00171 if (--(y -> rbn_pkg_refs) == 0)
00172 bu_rb_free_node(y);
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 void bu_rb_delete (bu_rb_tree *tree, int order)
00185 {
00186 int nm_orders;
00187 struct bu_rb_node **node;
00188 struct bu_rb_package *package;
00189
00190 BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00191 BU_RB_CKORDER(tree, order);
00192
00193 if (tree -> rbt_nm_nodes <= 0)
00194 {
00195 bu_log("Error: Attempt to delete from tree with %d nodes\n",
00196 tree -> rbt_nm_nodes);
00197 bu_bomb("");
00198 }
00199 if (bu_rb_current(tree) == bu_rb_null(tree))
00200 {
00201 bu_log("Warning: bu_rb_delete(): current node is undefined\n");
00202 return;
00203 }
00204
00205 nm_orders = tree -> rbt_nm_orders;
00206 package = (bu_rb_current(tree) -> rbn_package)[order];
00207
00208 node = (struct bu_rb_node **)
00209 bu_malloc(nm_orders * sizeof(struct bu_rb_node *), "node list");
00210
00211 for (order = 0; order < nm_orders; ++order)
00212 node[order] = (package -> rbp_node)[order];
00213
00214
00215
00216
00217 for (order = 0; order < nm_orders; ++order)
00218 _rb_delete(tree, node[order], order);
00219
00220 --(tree -> rbt_nm_nodes);
00221 bu_rb_free_package(package);
00222 bu_free((genptr_t) node, "node list");
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233