Browse Source

use tree macros in memory management tree

1.0.2
Georg Hopp 12 years ago
parent
commit
da3ff34168
  1. 217
      src/memory.c

217
src/memory.c

@ -54,8 +54,7 @@
#include <unistd.h>
#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);
}
}

Loading…
Cancel
Save