Commit 03fdf503 authored by Warren Dukes's avatar Warren Dukes

some tree bugfixes

git-svn-id: https://svn.musicpd.org/mpd/trunk@4498 09075e82-0dd4-0310-85a5-a0d7c8717e4f
parent 60a7abc1
...@@ -231,6 +231,7 @@ _AddDataToSplitNodes(Tree * tree, ...@@ -231,6 +231,7 @@ _AddDataToSplitNodes(Tree * tree,
{ {
assert(newNode == NULL || assert(newNode == NULL ||
tree->compareData(data, newNode->data[0]) < 0); tree->compareData(data, newNode->data[0]) < 0);
assert(moreNode->children[0] == NULL);
void * retData; void * retData;
...@@ -240,6 +241,13 @@ _AddDataToSplitNodes(Tree * tree, ...@@ -240,6 +241,13 @@ _AddDataToSplitNodes(Tree * tree,
lessNode->dataCount--; lessNode->dataCount--;
retData = lessNode->data[lessNode->dataCount]; retData = lessNode->data[lessNode->dataCount];
lessNode->data[lessNode->dataCount] = NULL; lessNode->data[lessNode->dataCount] = NULL;
moreNode->children[0] =
lessNode->children[lessNode->dataCount+1];
if (moreNode->children[0])
{
moreNode->children[0]->parent = moreNode;
}
lessNode->children[lessNode->dataCount+1] = NULL;
} }
else else
{ {
...@@ -350,18 +358,25 @@ _MergeNodes(TreeNode * lessNode, TreeNode * moreNode) ...@@ -350,18 +358,25 @@ _MergeNodes(TreeNode * lessNode, TreeNode * moreNode)
for(; i < moreNode->dataCount; i++,j++) for(; i < moreNode->dataCount; i++,j++)
{ {
assert(!lessNode->children[j]);
assert(!lessNode->data[j]);
lessNode->data[j] = moreNode->data[i]; lessNode->data[j] = moreNode->data[i];
lessNode->children[j] = moreNode->children[i]; lessNode->children[j] = moreNode->children[i];
lessNode->children[j]->parent = lessNode; if (lessNode->children[j])
{
lessNode->children[j]->parent = lessNode;
}
} }
lessNode->children[j] = moreNode->children[i]; lessNode->children[j] = moreNode->children[i];
lessNode->children[j]->parent = lessNode; if (lessNode->children[j])
lessNode->dataCount = j; {
lessNode->children[j]->parent = lessNode;
}
lessNode->dataCount += i;
free(moreNode); free(moreNode);
} }
static
void void
_DeleteAt(TreeIterator * iter) _DeleteAt(TreeIterator * iter)
{ {
...@@ -369,47 +384,57 @@ _DeleteAt(TreeIterator * iter) ...@@ -369,47 +384,57 @@ _DeleteAt(TreeIterator * iter)
void ** data = &(node->data[iter->which]); void ** data = &(node->data[iter->which]);
void * dataToFree = *data; void * dataToFree = *data;
// perculate up data to fill the whole!
while (1)
{ {
TreeNode ** child = &(node->children[iter->which+1]); int dir = 0;
void ** childData = NULL; TreeNode * child = NULL;
if (*child) // find the least greater than data to fill the whole!
if (node->children[iter->which+1])
{ {
assert((*child)->dataCount); dir = -1;
childData = &((*child)->data[0]); child = node->children[iter->which+1];
} }
else if (*(--child)) // or the greatest lesser than data to fill the whole!
else if (node->children[iter->which])
{ {
assert((*child)->dataCount); dir = 1;
childData = &((*child)->data[(*child)->dataCount-1]); child = node->children[iter->which];
} }
else
if (dir > 0)
{ {
// no children! while (child->children[child->dataCount])
break; {
} child = child->children[child->dataCount];
}
// move childData up to parent node *data = child->data[child->dataCount-1];
*data = *childData; data = &(child->data[child->dataCount-1]);
node = child;
}
else if (dir < 0)
{
while (child->children[0])
{
child = child->children[0];
}
// set data and node for next iteration *data = child->data[0];
data = childData; data = &(child->data[0]);
node = *child; node = child;
}
} }
void * tempData = *data; void * tempData = *data;
// move data nodes over, we're at a leaf node, so we can ignore // move data nodes over, we're at a leaf node, so we can ignore
// children // children
void ** leftData = node->data[node->dataCount-1]; int i = --node->dataCount;
while (data != leftData) for (; data != &(node->data[i]); i--)
{ {
*(leftData-1) = *leftData; node->data[i-1] = node->data[i];
leftData--;
} }
node->data[--(node->dataCount)] = NULL; node->data[node->dataCount] = NULL;
// merge the nodes from the bottom up which have too few data // merge the nodes from the bottom up which have too few data
while (node->dataCount < (CHILDREN_PER_NODE/2)) while (node->dataCount < (CHILDREN_PER_NODE/2))
...@@ -419,10 +444,16 @@ _DeleteAt(TreeIterator * iter) ...@@ -419,10 +444,16 @@ _DeleteAt(TreeIterator * iter)
{ {
TreeNode ** child; TreeNode ** child;
int pos; int pos;
_FindPositionInNode(iter->tree, if (_FindPositionInNode(iter->tree,
node->parent, node->parent,
tempData, tempData,
&pos); &pos))
{
if (node->parent->children[pos] != node)
{
pos++;
}
}
assert(node->parent->children[pos] == node); assert(node->parent->children[pos] == node);
child = &(node->parent->children[pos]); child = &(node->parent->children[pos]);
...@@ -435,7 +466,11 @@ _DeleteAt(TreeIterator * iter) ...@@ -435,7 +466,11 @@ _DeleteAt(TreeIterator * iter)
node->parent->data[pos]; node->parent->data[pos];
node->children[node->dataCount] = node->children[node->dataCount] =
(*child)->children[0]; (*child)->children[0];
node->children[node->dataCount]->parent = node; if (node->children[node->dataCount])
{
node->children[node->dataCount]->
parent = node;
}
node->parent->data[pos] = node->parent->data[pos] =
(*child)->data[0]; (*child)->data[0];
int i = 0; int i = 0;
...@@ -461,20 +496,23 @@ _DeleteAt(TreeIterator * iter) ...@@ -461,20 +496,23 @@ _DeleteAt(TreeIterator * iter)
node->data[0] = node->parent->data[pos-1]; node->data[0] = node->parent->data[pos-1];
node->children[0] = node->children[0] =
(*child)->children[(*child)->dataCount]; (*child)->children[(*child)->dataCount];
node->children[0]->parent = node; if (node->children[0])
{
node->children[0]->parent = node;
}
node->parent->data[pos-1] = node->parent->data[pos-1] =
(*child)->data[(*child)->dataCount-1]; (*child)->data[(*child)->dataCount-1];
(*child)->children[(*child)->dataCount--] =NULL; (*child)->children[(*child)->dataCount--] =
NULL;
(*child)->data[(*child)->dataCount] = NULL; (*child)->data[(*child)->dataCount] = NULL;
} }
else else
{ {
// merge with one of our siblings // merge with one of our siblings
if(pos < node->parent->dataCount-1) if (pos < node->parent->dataCount)
{ {
child++; child++;
assert(*child); assert(*child);
pos--;
tempData = node->parent->data[pos]; tempData = node->parent->data[pos];
node->data[node->dataCount++] = node->data[node->dataCount++] =
...@@ -487,12 +525,14 @@ _DeleteAt(TreeIterator * iter) ...@@ -487,12 +525,14 @@ _DeleteAt(TreeIterator * iter)
assert(pos > 0); assert(pos > 0);
child--; child--;
assert(*child); assert(*child);
pos--;
tempData = node->parent->data[pos]; tempData = node->parent->data[pos];
(*child)->data[(*child)->dataCount++] = (*child)->data[(*child)->dataCount++] =
tempData; tempData;
_MergeNodes(*child, node); _MergeNodes(*child, node);
node = *child;
} }
int i = pos; int i = pos;
...@@ -505,6 +545,7 @@ _DeleteAt(TreeIterator * iter) ...@@ -505,6 +545,7 @@ _DeleteAt(TreeIterator * iter)
} }
node->parent->data[i] = NULL; node->parent->data[i] = NULL;
node->parent->children[i+1] = NULL; node->parent->children[i+1] = NULL;
node->parent->dataCount--;
node = node->parent; node = node->parent;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment