diff --git a/src/memory.c b/src/memory.c index 55550cc..e7257d7 100644 --- a/src/memory.c +++ b/src/memory.c @@ -54,8 +54,7 @@ #include #include "tr/memory.h" - -enum rbColor {rbBlack=1, rbRed=2}; +#include "tr/tree_macros.h" struct memSegment @@ -64,7 +63,9 @@ struct memSegment size_t size; void * ptr; - enum rbColor color; + TR_rbColor color; + + struct memSegment * data; struct memSegment * next; struct memSegment * last; @@ -84,6 +85,8 @@ newElement(size_t size) element->size = size; element->ptr = (void*)element + sizeof(struct memSegment); + element->data = element; + element->next = NULL; element->last = NULL; @@ -121,133 +124,6 @@ findElement(struct memSegment * tree, size_t size) return fitting; } -/* - * function to get specific elements needed for - * rb handling, grandparent, uncle and sibbling - */ -static -struct memSegment * -grandparent(struct memSegment * node) -{ - if (NULL != node && NULL != node->parent) { - return node->parent->parent; - } - - return NULL; -} - -static -struct memSegment * -uncle(struct memSegment * node) -{ - struct memSegment * gp = grandparent(node); - - if (NULL == gp) { - return NULL; - } - - if (node->parent == gp->left) { - return gp->right; - } - - return gp->left; -} - -static -struct memSegment * -sibling(struct memSegment * node) -{ - if (NULL == node) { - return NULL; - } - - if (NULL == node->parent->left || node == node->parent->left) { - return node->parent->right; - } else { - return node->parent->left; - } -} - -/* - * tree modifications...needed for rb handling. - */ -static -void -rotateLeft(struct memSegment ** tree, struct memSegment * node) -{ - struct memSegment * rightChild = node->right; - struct memSegment * rcLeftSub = node->right->left; - - rightChild->left = node; - rightChild->parent = node->parent; - node->right = rcLeftSub; - if (NULL != rcLeftSub) { - rcLeftSub->parent = node; - } - - if (node->parent) { - if (node->parent->left == node) { - node->parent->left = rightChild; - } else { - node->parent->right = rightChild; - } - } else { - *tree = rightChild; - } - - node->parent = rightChild; -} - -static -void -rotateRight(struct memSegment ** tree, struct memSegment * node) -{ - struct memSegment * leftChild = node->left; - struct memSegment * lcRightSub = node->left->right; - - leftChild->right = node; - leftChild->parent = node->parent; - node->left = lcRightSub; - if (NULL != lcRightSub) { - lcRightSub->parent = node; - } - - if (node->parent) { - if (node->parent->left == node) { - node->parent->left = leftChild; - } else { - node->parent->right = leftChild; - } - } else { - *tree = leftChild; - } - - node->parent = leftChild; -} - -static -void -replaceNode( - struct memSegment ** tree, - struct memSegment * node1, - struct memSegment * node2) -{ - if (NULL != node1->parent) { - if (node1 == node1->parent->left) { - node1->parent->left = node2; - } else { - node1->parent->right = node2; - } - } else { - *tree = node2; - } - - if (NULL != node2) { - node2->parent = node1->parent; - } -} - - /** * insert element in tree */ @@ -324,8 +200,8 @@ insertElement(struct memSegment ** tree, struct memSegment * element) } // case 3 - u = uncle(node); - g = grandparent(node); + u = TR_TREE_UNCLE(node); + g = TR_TREE_GRANDPARENT(node); if (u != NULL && u->color == rbRed) { node->parent->color = rbBlack; @@ -338,24 +214,24 @@ insertElement(struct memSegment ** tree, struct memSegment * element) // case 4 if (node == node->parent->right && node->parent == g->left) { - rotateLeft(tree, node->parent); + TR_TREE_ROTATE(left, tree, node->parent); node = node->left; } else if (node == node->parent->left && node->parent == g->right) { - rotateRight(tree, node->parent); + TR_TREE_ROTATE(right, tree, node->parent); node = node->right; } // case 5 - g = grandparent(node); + g = TR_TREE_GRANDPARENT(node); node->parent->color = rbBlack; g->color = rbRed; if (node == node->parent->left) { - rotateRight(tree, g); + TR_TREE_ROTATE(right, tree, g); } else { - rotateLeft(tree, g); + TR_TREE_ROTATE(left, tree, g); } // we're done.. @@ -366,36 +242,6 @@ insertElement(struct memSegment ** tree, struct memSegment * element) return new_node; } -/** - * delete element from tree - * here multiple functions are involved.... - * ======================================================================= - */ -/** - * find minimum of the right subtree aka leftmost leaf of right subtree - * aka left in-order successor. - * We return the parent of the element in the out argument parent. - * This can be NULL wenn calling. - * - * 2: *successor = {size = 80, ptr = 0x603ae0, color = rbRed, parent = 0x603160, - * left = 0x0, right = 0x0} - * 1: *node = {size = 70, ptr = 0x603a60, color = rbBlack, parent = 0x603070, - * left = 0x6030e0, right = 0x6031e0} - * - */ -static -struct memSegment * -findInOrderSuccessor(struct memSegment * tree) -{ - struct memSegment * node = tree->right; - - while (NULL != node->left) { - node = node->left; - } - - return node; -} - static struct memSegment * deleteElement(struct memSegment ** tree, struct memSegment * element) @@ -456,14 +302,19 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) // case 1: two children if (NULL != node->left && NULL != node->right) { - struct memSegment * successor = findInOrderSuccessor(node); + struct memSegment * successor; + struct memSegment * tmpparent; + struct memSegment * tmpleft; + struct memSegment * tmpright; + TR_rbColor tmpcolor; - enum rbColor tmpcolor = successor->color; - struct memSegment * tmpparent = successor->parent; - struct memSegment * tmpleft = successor->left; - struct memSegment * tmpright = successor->right; + TR_TREE_INORDER_SUCC(node, successor); + tmpparent = successor->parent; + tmpleft = successor->left; + tmpright = successor->right; + tmpcolor = successor->color; - replaceNode(tree, node, successor); + TR_TREE_REPLACE_NODE(tree, node, successor); successor->color = node->color; successor->left = node->left; @@ -486,7 +337,7 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) // Precondition: n has at most one non-null child. child = (NULL == node->right) ? node->left : node->right; - replaceNode(tree, node, child); + TR_TREE_REPLACE_NODE(tree, node, child); // delete one child case // TODO this is overly complex as simply derived from the function... @@ -518,7 +369,7 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) } // case 2 - s = sibling(node); + s = TR_TREE_SIBLING(node); if (NULL != s && s->color == rbRed) { node->parent->color = rbRed; @@ -530,13 +381,13 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) * null we must be left, even if its set to NULL previously */ if (NULL != node->parent->right && node != node->parent->right) { - rotateLeft(tree, node->parent); + TR_TREE_ROTATE(left, tree, node->parent); } else { - rotateRight(tree, node->parent); + TR_TREE_ROTATE(right, tree, node->parent); } } - s = sibling(node); + s = TR_TREE_SIBLING(node); // case 3 / 4 if (NULL == s || ((s->color == rbBlack) && (NULL == s->left || s->left->color == rbBlack) && @@ -577,7 +428,7 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) s->color = rbRed; s->left->color = rbBlack; - rotateRight(tree, s); + TR_TREE_ROTATE(right, tree, s); } else if ((node == node->parent->right) && (NULL == s->left || s->left->color == rbBlack) && (NULL != s->right && s->right->color == rbRed)) { @@ -585,11 +436,11 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) s->color = rbRed; s->right->color = rbBlack; - rotateLeft(tree, s); + TR_TREE_ROTATE(left, tree, s); } } - s = sibling(node); + s = TR_TREE_SIBLING(node); // case 6 if (NULL != s) { s->color = node->parent->color; @@ -607,12 +458,12 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) if (NULL != s->right) { s->right->color = rbBlack; } - rotateLeft(tree, node->parent); + TR_TREE_ROTATE(left, tree, node->parent); } else { if (NULL != s->left) { s->left->color = rbBlack; } - rotateRight(tree, node->parent); + TR_TREE_ROTATE(right, tree, node->parent); } }