aboutsummaryrefslogtreecommitdiffstats
path: root/main/musl/0016-fix-tdelete-to-properly-balance-the-tree.patch
blob: bb3c79cfbf19cf705495f5afc786ffe57496f77a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
From e4f9d811684011d8a67e363827de39d5f2d3ae5a Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <nsz@port70.net>
Date: Sat, 5 Dec 2015 21:02:34 +0100
Subject: [PATCH] fix tdelete to properly balance the tree

the tsearch data structure is an avl tree, but it did not implement
the deletion operation correctly so the tree could become unbalanced.

reported by Ed Schouten.
---
 src/search/tsearch_avl.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/search/tsearch_avl.c b/src/search/tsearch_avl.c
index 8620092..0864460 100644
--- a/src/search/tsearch_avl.c
+++ b/src/search/tsearch_avl.c
@@ -105,10 +105,13 @@ static struct node *insert(struct node **n, const void *k,
 	return r;
 }
 
-static struct node *movr(struct node *n, struct node *r) {
-	if (!n)
-		return r;
-	n->right = movr(n->right, r);
+static struct node *remove_rightmost(struct node *n, struct node **rightmost)
+{
+	if (!n->right) {
+		*rightmost = n;
+		return n->left;
+	}
+	n->right = remove_rightmost(n->right, rightmost);
 	return balance(n);
 }
 
@@ -122,7 +125,13 @@ static struct node *remove(struct node **n, const void *k,
 	c = cmp(k, (*n)->key);
 	if (c == 0) {
 		struct node *r = *n;
-		*n = movr(r->left, r->right);
+		if (r->left) {
+			r->left = remove_rightmost(r->left, n);
+			(*n)->left = r->left;
+			(*n)->right = r->right;
+			*n = balance(*n);
+		} else
+			*n = r->right;
 		free(r);
 		return parent;
 	}
-- 
2.7.0