Commit 16c58ab9738f91d021a8685184054c4270c32f47

Authored by Georg Hopp
1 parent 5fd8c71f

change all the rebalance code to be macros

@@ -41,10 +41,10 @@ @@ -41,10 +41,10 @@
41 41
42 #define TR_TREE_GRANDPARENT(node) (TR_TREE_PARENT((node))->parent) 42 #define TR_TREE_GRANDPARENT(node) (TR_TREE_PARENT((node))->parent)
43 43
44 -#define TR_TREE_UNCLE(node) \  
45 - ((node)->parent == (node)->parent->parent->left? \  
46 - (node)->parent->parent->right: \  
47 - (node)->parent->parent->left) 44 +#define TR_TREE_UNCLE(node) \
  45 + ((node)->parent == (node)->parent->parent->left \
  46 + ? (node)->parent->parent->right \
  47 + : (node)->parent->parent->left)
48 48
49 #define TR_TREE_REPLACE_NODE(root, node1, node2) \ 49 #define TR_TREE_REPLACE_NODE(root, node1, node2) \
50 if (NULL != (node1)->parent) { \ 50 if (NULL != (node1)->parent) { \
@@ -89,16 +89,21 @@ @@ -89,16 +89,21 @@
89 89
90 typedef enum {rbBlack=1, rbRed=2} TR_rbColor; 90 typedef enum {rbBlack=1, rbRed=2} TR_rbColor;
91 91
92 -#define TR_TREE_NODE_BLACK(node) (NULL == (node) || rbBlack == (node)->color)  
93 -#define TR_TREE_NODE_RED(node) (NULL == (node) || rbRed == (node)->color)  
94 -#define TR_TREE_NODE_STRICT_BLACK(node) (NULL != (node) && rbBlack == (node)->color)  
95 -#define TR_TREE_NODE_STRICT_RED(node) (NULL != (node) && rbRed == (node)->color) 92 +#define TR_TREE_NODE_BLACK(node) \
  93 + (NULL == (node) || rbBlack == (node)->color)
  94 +#define TR_TREE_NODE_RED(node) \
  95 + (NULL == (node) || rbRed == (node)->color)
  96 +#define TR_TREE_NODE_STRICT_BLACK(node) \
  97 + (NULL != (node) && rbBlack == (node)->color)
  98 +#define TR_TREE_NODE_STRICT_RED(node) \
  99 + (NULL != (node) && rbRed == (node)->color)
96 100
97 #define TR_TREE_INORDER_SUCC(node, succ) \ 101 #define TR_TREE_INORDER_SUCC(node, succ) \
98 succ = (node)->right; \ 102 succ = (node)->right; \
99 while (NULL != succ->left) { \ 103 while (NULL != succ->left) { \
100 succ = succ->left; \ 104 succ = succ->left; \
101 } 105 }
  106 +
102 /* 107 /*
103 * Find data in a tree. 108 * Find data in a tree.
104 * Attention: This will change node, so normally you need to copy 109 * Attention: This will change node, so normally you need to copy
@@ -125,6 +130,151 @@ typedef enum {rbBlack=1, rbRed=2} TR_rbColor; @@ -125,6 +130,151 @@ typedef enum {rbBlack=1, rbRed=2} TR_rbColor;
125 } \ 130 } \
126 } 131 }
127 132
  133 +#define TR_TREE_BALANCE_DELETE_CASE1(node) \
  134 + if (NULL == TR_TREE_PARENT((node))) { \
  135 + break; \
  136 + }
  137 +
  138 +#define TR_TREE_BALANCE_DELETE_CASE2(root, node, sibling) \
  139 + if (NULL != (sibling) && rbRed == (sibling)->color) { \
  140 + (node)->parent->color = rbRed; \
  141 + (sibling)->color = rbBlack; \
  142 + if (NULL != (node)->parent->right \
  143 + && (node) != (node)->parent->right) { \
  144 + TR_TREE_ROTATE(left, (root), (node)->parent); \
  145 + } else { \
  146 + TR_TREE_ROTATE(right, (root), (node)->parent); \
  147 + } \
  148 + (sibling) = TR_TREE_SIBLING((node)); \
  149 + }
  150 +
  151 +#define TR_TREE_BALANCE_DELETE_CASE34(root, node, sibling) \
  152 + if (NULL == (sibling) \
  153 + || (rbBlack == (sibling)->color \
  154 + && TR_TREE_NODE_BLACK((sibling)->left) \
  155 + && TR_TREE_NODE_BLACK((sibling)->right))) { \
  156 + if (NULL != (sibling)) { \
  157 + (sibling)->color = rbRed; \
  158 + } \
  159 + if (rbBlack == (node)->parent->color) { \
  160 + (node) = (node)->parent; \
  161 + continue; \
  162 + } else { \
  163 + (node)->parent->color = rbBlack; \
  164 + break; \
  165 + } \
  166 + }
  167 +
  168 +/*
  169 + * this if statement is trivial,
  170 + * due to case 2 (even though case 2 changed the sibling to a
  171 + * sibling's child,
  172 + * the sibling's child can't be red, since no red parent can
  173 + * have a red child).
  174 + *
  175 + * the following statements just force the red to be on the
  176 + * left of the left of the parent,
  177 + * or right of the right, so case 6 will rotate correctly.
  178 + */
  179 +#define TR_TREE_BALANCE_DELETE_CASE5(root, node, sibling) \
  180 + if (NULL != (sibling) && rbBlack == (sibling)->color) { \
  181 + if ((node) == (node)->parent->left \
  182 + && TR_TREE_NODE_BLACK((sibling)->right) \
  183 + && TR_TREE_NODE_STRICT_RED((sibling)->left)) { \
  184 + (sibling)->color = rbRed; \
  185 + (sibling)->left->color = rbBlack; \
  186 + TR_TREE_ROTATE(right, (root), (sibling)); \
  187 + } else if ((node) == (node)->parent->right \
  188 + && TR_TREE_NODE_BLACK((sibling)->left) \
  189 + && TR_TREE_NODE_STRICT_RED((sibling)->right)) { \
  190 + (sibling)->color = rbRed; \
  191 + (sibling)->right->color = rbBlack; \
  192 + TR_TREE_ROTATE(left, (root), (sibling)); \
  193 + } \
  194 + (sibling) = TR_TREE_SIBLING((node)); \
  195 + }
  196 +
  197 +#define TR_TREE_BALANCE_DELETE_CASE6(root, node, sibling) \
  198 + if (NULL != (sibling)) { \
  199 + (sibling)->color = (node)->parent->color; \
  200 + } \
  201 + if (NULL != (node) && NULL != (node)->parent) { \
  202 + (node)->parent->color = rbBlack; \
  203 + if (NULL != (node)->parent->right \
  204 + && (node) != (node)->parent->right) { \
  205 + if (NULL != (sibling)->right) { \
  206 + (sibling)->right->color = rbBlack; \
  207 + } \
  208 + TR_TREE_ROTATE(left, (root), (node)->parent); \
  209 + } else { \
  210 + if (NULL != (sibling)->left) { \
  211 + (sibling)->left->color = rbBlack; \
  212 + } \
  213 + TR_TREE_ROTATE(right, (root), (node)->parent); \
  214 + } \
  215 + }
  216 +
  217 +#define TR_TREE_BALANCE_DELETE(root, node, sibling) \
  218 + while(1) { \
  219 + TR_TREE_BALANCE_DELETE_CASE1((node)) \
  220 + TR_TREE_BALANCE_DELETE_CASE2((root), (node), (sibling)) \
  221 + TR_TREE_BALANCE_DELETE_CASE34((root), (node), (sibling)) \
  222 + TR_TREE_BALANCE_DELETE_CASE5((root), (node), (sibling)) \
  223 + TR_TREE_BALANCE_DELETE_CASE6((root), (node), (sibling)) \
  224 + break; \
  225 + }
  226 +
  227 +#define TR_TREE_BALANCE_INSERT_CASE1(node) \
  228 + if (NULL == TR_TREE_PARENT((node))) { \
  229 + (node)->color = rbBlack; \
  230 + break; \
  231 + }
  232 +
  233 +#define TR_TREE_BALANCE_INSERT_CASE2(node) \
  234 + if (rbBlack == (node)->parent->color) { \
  235 + break; \
  236 + }
  237 +
  238 +#define TR_TREE_BALANCE_INSERT_CASE3(node) \
  239 + if (NULL != TR_TREE_UNCLE(node) \
  240 + && rbRed == TR_TREE_UNCLE(node)->color) { \
  241 + (node)->parent->color = rbBlack; \
  242 + TR_TREE_UNCLE(node)->color = rbBlack; \
  243 + (node)->parent->parent->color = rbRed; \
  244 + (node) = (node)->parent->parent; \
  245 + continue; \
  246 + }
  247 +
  248 +#define TR_TREE_BALANCE_INSERT_CASE4(root, node) \
  249 + if ((node) == (node)->parent->right \
  250 + && (node)->parent == (node)->parent->parent->left) { \
  251 + TR_TREE_ROTATE(left, (root), (node)->parent); \
  252 + (node) = (node)->left; \
  253 + } else if ((node) == (node)->parent->left \
  254 + && (node)->parent == (node)->parent->parent->right) { \
  255 + TR_TREE_ROTATE(right, (root), (node)->parent); \
  256 + (node) = (node)->right; \
  257 + }
  258 +
  259 +#define TR_TREE_BALANCE_INSERT_CASE5(root, node) \
  260 + (node)->parent->color = rbBlack; \
  261 + (node)->parent->parent->color = rbRed; \
  262 + if ((node) == (node)->parent->left) { \
  263 + TR_TREE_ROTATE(right, (root), (node)->parent->parent); \
  264 + } else { \
  265 + TR_TREE_ROTATE(left, (root), (node)->parent->parent); \
  266 + }
  267 +
  268 +#define TR_TREE_BALANCE_INSERT(root, node) \
  269 + while (1) { \
  270 + TR_TREE_BALANCE_INSERT_CASE1((node)) \
  271 + TR_TREE_BALANCE_INSERT_CASE2((node)) \
  272 + TR_TREE_BALANCE_INSERT_CASE3((node)) \
  273 + TR_TREE_BALANCE_INSERT_CASE4((root), (node)) \
  274 + TR_TREE_BALANCE_INSERT_CASE5((root), (node)) \
  275 + break; \
  276 + }
  277 +
128 #endif // __TR_TREE_MACROS_H__ 278 #endif // __TR_TREE_MACROS_H__
129 279
130 // vim: set ts=4 sw=4: 280 // vim: set ts=4 sw=4:
@@ -131,8 +131,6 @@ insertElement(struct memSegment ** tree, struct memSegment * element) @@ -131,8 +131,6 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
131 { 131 {
132 struct memSegment * node = *tree; 132 struct memSegment * node = *tree;
133 struct memSegment * new_node = NULL; 133 struct memSegment * new_node = NULL;
134 - struct memSegment * u;  
135 - struct memSegment * g;  
136 int found; 134 int found;
137 135
138 element->next = NULL; 136 element->next = NULL;
@@ -173,63 +171,10 @@ insertElement(struct memSegment ** tree, struct memSegment * element) @@ -173,63 +171,10 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
173 } 171 }
174 } 172 }
175 173
176 - if (NULL != new_node) {  
177 - /*  
178 - * handle reballancing rb style  
179 - */  
180 - while (1) {  
181 - // case 1  
182 - if (node->parent == NULL) {  
183 - node->color = rbBlack;  
184 - // we're done.... :)  
185 - break;  
186 - }  
187 -  
188 - // case 2  
189 - if (node->parent->color == rbBlack) {  
190 - // Tree is still valid ... wow, again we're done... :)  
191 - break;  
192 - }  
193 -  
194 - // case 3  
195 - u = TR_TREE_UNCLE(node);  
196 - g = TR_TREE_GRANDPARENT(node);  
197 -  
198 - if (u != NULL && u->color == rbRed) {  
199 - node->parent->color = rbBlack;  
200 - u->color = rbBlack;  
201 - g->color = rbRed;  
202 -  
203 - node = g;  
204 - continue;  
205 - }  
206 -  
207 - // case 4  
208 - if (node == node->parent->right && node->parent == g->left) {  
209 - TR_TREE_ROTATE(left, tree, node->parent);  
210 - node = node->left;  
211 - } else if (node == node->parent->left && node->parent == g->right) {  
212 -  
213 - TR_TREE_ROTATE(right, tree, node->parent);  
214 - node = node->right;  
215 - }  
216 -  
217 - // case 5  
218 - g = TR_TREE_GRANDPARENT(node);  
219 -  
220 - node->parent->color = rbBlack;  
221 - g->color = rbRed;  
222 -  
223 - if (node == node->parent->left) {  
224 - TR_TREE_ROTATE(right, tree, g);  
225 - } else {  
226 - TR_TREE_ROTATE(left, tree, g);  
227 - }  
228 -  
229 - // we're done..  
230 - break;  
231 - }  
232 - } 174 + /*
  175 + * handle reballancing rb style
  176 + */
  177 + TR_TREE_BALANCE_INSERT(tree, node);
233 178
234 return new_node; 179 return new_node;
235 } 180 }
@@ -345,116 +290,8 @@ deleteElement(struct memSegment ** tree, size_t size) @@ -345,116 +290,8 @@ deleteElement(struct memSegment ** tree, size_t size)
345 return del_node; 290 return del_node;
346 } 291 }
347 292
348 - // delete and rb rebalance...  
349 - while(1) {  
350 - // case 1  
351 - if (NULL == node->parent) {  
352 - // done again  
353 - break;  
354 - }  
355 -  
356 - // case 2  
357 - s = TR_TREE_SIBLING(node);  
358 -  
359 - if (NULL != s && s->color == rbRed) {  
360 - node->parent->color = rbRed;  
361 - s->color = rbBlack;  
362 -  
363 - /*  
364 - * detect which child we are...assumption  
365 - * if we are not parent->right and parent->right is not  
366 - * null we must be left, even if its set to NULL previously  
367 - */  
368 - if (NULL != node->parent->right && node != node->parent->right) {  
369 - TR_TREE_ROTATE(left, tree, node->parent);  
370 - } else {  
371 - TR_TREE_ROTATE(right, tree, node->parent);  
372 - }  
373 - }  
374 -  
375 - s = TR_TREE_SIBLING(node);  
376 - // case 3 / 4  
377 - if (NULL == s || ((s->color == rbBlack) &&  
378 - (NULL == s->left || s->left->color == rbBlack) &&  
379 - (NULL == s->right || s->right->color == rbBlack))) {  
380 -  
381 - if (NULL != s) {  
382 - s->color = rbRed;  
383 - }  
384 -  
385 - if (node->parent->color == rbBlack) {  
386 - // case 3  
387 - node = node->parent;  
388 - continue;  
389 - } else {  
390 - // case 4  
391 - node->parent->color = rbBlack;  
392 - // and done again...  
393 - break;  
394 - }  
395 - }  
396 -  
397 - // case 5  
398 - if (NULL != s && s->color == rbBlack) {  
399 - // this if statement is trivial,  
400 - // due to case 2 (even though case 2 changed the sibling to a  
401 - // sibling's child,  
402 - // the sibling's child can't be red, since no red parent can  
403 - // have a red child).  
404 - //  
405 - // the following statements just force the red to be on the  
406 - // left of the left of the parent,  
407 - // or right of the right, so case 6 will rotate correctly.  
408 - if ((node == node->parent->left) &&  
409 - (NULL == s->right || s->right->color == rbBlack) &&  
410 - (NULL != s->left && s->left->color == rbRed)) {  
411 -  
412 - // this last test is trivial too due to cases 2-4.  
413 - s->color = rbRed;  
414 - s->left->color = rbBlack;  
415 -  
416 - TR_TREE_ROTATE(right, tree, s);  
417 - } else if ((node == node->parent->right) &&  
418 - (NULL == s->left || s->left->color == rbBlack) &&  
419 - (NULL != s->right && s->right->color == rbRed)) {  
420 - // this last test is trivial too due to cases 2-4.  
421 - s->color = rbRed;  
422 - s->right->color = rbBlack;  
423 -  
424 - TR_TREE_ROTATE(left, tree, s);  
425 - }  
426 - }  
427 -  
428 - s = TR_TREE_SIBLING(node);  
429 - // case 6  
430 - if (NULL != s) {  
431 - s->color = node->parent->color;  
432 - }  
433 -  
434 - if (NULL != node && NULL != node->parent) {  
435 - node->parent->color = rbBlack;  
436 -  
437 - /*  
438 - * detect which child we are...assumption  
439 - * if we are not parent->right and parent->right is not  
440 - * null we must be left, even if its set to NULL previously  
441 - */  
442 - if (NULL != node->parent->right && node != node->parent->right) {  
443 - if (NULL != s->right) {  
444 - s->right->color = rbBlack;  
445 - }  
446 - TR_TREE_ROTATE(left, tree, node->parent);  
447 - } else {  
448 - if (NULL != s->left) {  
449 - s->left->color = rbBlack;  
450 - }  
451 - TR_TREE_ROTATE(right, tree, node->parent);  
452 - }  
453 - }  
454 -  
455 - // done...  
456 - break;  
457 - } 293 + s = TR_TREE_SIBLING(node);
  294 + TR_TREE_BALANCE_DELETE(tree, node, s);
458 295
459 return del_node; 296 return del_node;
460 } 297 }
Please register or login to post a comment