Bug 706075: Fix errors in property deletion.

1) Copy "level" from the replacement node.
2) Fix rebalancing by using exact algorithm from AA-tree paper.
This commit is contained in:
Tor Andersson
2022-11-14 17:43:20 +01:00
parent f882c6c5fe
commit 09b3fcb1e7

View File

@@ -104,36 +104,43 @@ static void freeproperty(js_State *J, js_Object *obj, js_Property *node)
--obj->count;
}
static js_Property *unlinkproperty(js_State *J, js_Object *obj, js_Property *node, const char *name, js_Property **garbage)
static js_Property *unlinkproperty(js_Property *node, const char *name, js_Property **garbage)
{
js_Property *temp, *succ;
js_Property *temp, *a, *b;
if (node != &sentinel) {
int c = strcmp(name, node->name);
if (c < 0) {
node->left = unlinkproperty(J, obj, node->left, name, garbage);
node->left = unlinkproperty(node->left, name, garbage);
} else if (c > 0) {
node->right = unlinkproperty(J, obj, node->right, name, garbage);
node->right = unlinkproperty(node->right, name, garbage);
} else {
if (node->left == &sentinel) {
*garbage = node;
node = node->right;
} else if (node->right == &sentinel) {
*garbage = node;
node = node->left;
} else {
*garbage = node;
succ = node->right;
while (succ->left != &sentinel)
succ = succ->left;
succ->right = unlinkproperty(J, obj, node->right, succ->name, &temp);
succ->left = node->left;
node = succ;
*garbage = node;
if (node->left == &sentinel && node->right == &sentinel) {
return &sentinel;
}
else if (node->left == &sentinel) {
a = node->right;
while (a->left != &sentinel)
a = a->left;
b = unlinkproperty(node->right, a->name, &temp);
temp->level = node->level;
temp->left = node->left;
temp->right = b;
node = temp;
}
else {
a = node->left;
while (a->right != &sentinel)
a = a->right;
b = unlinkproperty(node->left, a->name, &temp);
temp->level = node->level;
temp->left = b;
temp->right = node->right;
node = temp;
}
}
if (node->left->level < node->level - 1 ||
node->right->level < node->level - 1)
if (node->left->level < node->level - 1 || node->right->level < node->level - 1)
{
if (node->right->level > --node->level)
node->right->level = node->level;
@@ -149,9 +156,9 @@ static js_Property *unlinkproperty(js_State *J, js_Object *obj, js_Property *nod
static js_Property *deleteproperty(js_State *J, js_Object *obj, js_Property *tree, const char *name)
{
js_Property *garbage = NULL;
tree = unlinkproperty(J, obj, tree, name, &garbage);
if (garbage != NULL)
js_Property *garbage = &sentinel;
tree = unlinkproperty(tree, name, &garbage);
if (garbage != &sentinel)
freeproperty(J, obj, garbage);
return tree;
}