00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00028 #include "dbprim.h"
00029 #include "dbprim_int.h"
00030
00031 RCSTAG("@(#)$Id: rt_remove.c,v 1.3 2006/07/13 19:16:24 klmitch Exp $");
00032
00042 #define _rn_clear(node) \
00043 do { \
00044 (node)->rn_color = RB_COLOR_NONE; \
00045 (node)->rn_tree = 0; \
00046 (node)->rn_parent = 0; \
00047 (node)->rn_left = 0; \
00048 (node)->rn_right = 0; \
00049 } while (0)
00050
00064 #define _rt_update_parent(tree, node, new) \
00065 do { \
00066 if (!(node)->rn_parent) \
00067 (tree)->rt_root = (new); \
00068 else if (rn_isleft(node)) \
00069 (node)->rn_parent->rn_left = (new); \
00070 else \
00071 (node)->rn_parent->rn_right = (new); \
00072 } while (0)
00073
00087 #define isleft(par, n) ((par)->rn_left == (n))
00088
00104 #define sel_lr(t, n) ((t) ? (n)->rn_right : (n)->rn_left)
00105
00119 #define sibling(par, n) (sel_lr(isleft((par), (n)), (par)))
00120
00135 #define l_neph(par, n) (sel_lr(!isleft((par), (n)), sibling((par), (n))))
00136
00151 #define r_neph(par, n) (sel_lr(isleft((par), (n)), sibling((par), (n))))
00152
00153 unsigned long
00154 rt_remove(rb_tree_t *tree, rb_node_t *node)
00155 {
00156 rb_color_t col;
00157 rb_node_t *nchild, *nparent;
00158
00159 initialize_dbpr_error_table();
00160
00161 if (!rt_verify(tree) || !rn_verify(node))
00162 return DB_ERR_BADARGS;
00163
00164 if (!node->rn_tree)
00165 return DB_ERR_UNUSED;
00166 if (node->rn_tree != tree)
00167 return DB_ERR_WRONGTABLE;
00168
00169 if (tree->rt_flags & RBT_FLAG_FREEZE)
00170 return DB_ERR_FROZEN;
00171
00172 if (tree->rt_count == 1) {
00173 _rn_clear(node);
00174
00175 tree->rt_root = 0;
00176 tree->rt_count--;
00177
00178 return 0;
00179 }
00180
00181
00182
00183
00184 if (node->rn_left && node->rn_right) {
00185 rb_node_t *ggchild;
00186
00187 for (ggchild = node->rn_right; ggchild->rn_left;
00188 ggchild = ggchild->rn_left)
00189 ;
00190
00191
00192 nparent = (ggchild->rn_parent == node) ? ggchild : ggchild->rn_parent;
00193 nchild = ggchild->rn_right;
00194 col = ggchild->rn_color;
00195
00196
00197 ggchild->rn_left = node->rn_left;
00198 ggchild->rn_right = node->rn_right == ggchild ? 0 : node->rn_right;
00199 ggchild->rn_parent = node->rn_parent;
00200 ggchild->rn_color = node->rn_color;
00201
00202
00203 _rt_update_parent(tree, node, ggchild);
00204
00205 ggchild->rn_left->rn_parent = ggchild;
00206 if (ggchild->rn_right)
00207 ggchild->rn_right->rn_parent = ggchild;
00208
00209
00210 if (nparent != ggchild)
00211 nparent->rn_left = nchild;
00212 else
00213 nparent->rn_right = nchild;
00214 } else {
00215 nparent = node->rn_parent;
00216 nchild = node->rn_left ? node->rn_left : node->rn_right;
00217 col = node->rn_color;
00218
00219
00220 _rt_update_parent(tree, node, nchild);
00221 }
00222
00223 if (nchild)
00224 nchild->rn_parent = nparent;
00225
00226 if (col == RB_COLOR_BLACK) {
00227
00228 while (nparent && rn_isblack(nchild)) {
00229
00230 if (rn_isred(sibling(nparent, nchild))) {
00231 _rb_rotate(tree, sibling(nparent, nchild));
00232 nparent->rn_color = RB_COLOR_RED;
00233 nparent->rn_parent->rn_color = RB_COLOR_BLACK;
00234 }
00235
00236
00237 if (rn_isblack(l_neph(nparent, nchild)) &&
00238 rn_isblack(r_neph(nparent, nchild))) {
00239 sibling(nparent, nchild)->rn_color = RB_COLOR_RED;
00240 nchild = nparent;
00241 nparent = nparent->rn_parent;
00242 continue;
00243 }
00244
00245
00246 if (rn_isred(l_neph(nparent, nchild)))
00247 _rb_rotate(tree, l_neph(nparent, nchild));
00248 _rb_rotate(tree, sibling(nparent, nchild));
00249
00250
00251 nparent->rn_parent->rn_color = nparent->rn_color;
00252 nparent->rn_color = RB_COLOR_BLACK;
00253
00254 sibling(nparent->rn_parent, nparent)->rn_color = RB_COLOR_BLACK;
00255 break;
00256 }
00257
00258 if (rn_isred(nchild))
00259 nchild->rn_color = RB_COLOR_BLACK;
00260 }
00261
00262 _rn_clear(node);
00263
00264 tree->rt_count--;
00265
00266 return 0;
00267 }