diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-08-14 19:33:04 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-08-14 19:33:04 -0700 |
commit | 7ac870e986d747880307f071ec0465604f299c24 (patch) | |
tree | 785fff24a3a13a1a159f52e6bfa150cf2da9250c | |
parent | 29f314829fef594a90f7fe9c3152023f144af90a (diff) | |
download | txr-7ac870e986d747880307f071ec0465604f299c24.tar.gz txr-7ac870e986d747880307f071ec0465604f299c24.tar.bz2 txr-7ac870e986d747880307f071ec0465604f299c24.zip |
tree: bug: tree-delete-specific-node doesn't use key fun
* tree.c (tr_delete_specific): We cant' juse use key(node)
as the search key; we must apply the tree's key function
to the node key field to retrieve the correct search key.
* tests/010/tree.tl: New test case which fails without
this bugfix: a node which is the left subtree of the root
node doesn't get deleted since the search is led astray
by the wrong key object.
-rw-r--r-- | tests/010/tree.tl | 8 | ||||
-rw-r--r-- | tree.c | 4 |
2 files changed, 10 insertions, 2 deletions
diff --git a/tests/010/tree.tl b/tests/010/tree.tl index 56d04fa9..9d00fda6 100644 --- a/tests/010/tree.tl +++ b/tests/010/tree.tl @@ -166,7 +166,7 @@ (tree-delete tr 18) 18 (tree-delete tr 19) 19) -(set *tree-fun-whitelist* [list* '= '< *tree-fun-whitelist*]) +(set *tree-fun-whitelist* [list* '= '< 'to *tree-fun-whitelist*]) (let ((tr [tree '(1 2 3) identity < =])) (mtest @@ -256,3 +256,9 @@ (tree-del-min tr) 10 (tree-count tr) 0 (tree-del-min tr) nil)) + +(let* ((tr [tree '(#R(1 10) #R(11 20) #R(21 30)) to]) + (node (tree-lookup-node tr 10))) + (test node #N(#R(1 10) nil nil)) + (tree-delete-specific-node tr node) + (test tr #T((to) #R(11 20) #R(21 30)))) @@ -589,8 +589,10 @@ static val tr_delete(val tree, struct tree *tr, val key) static val tr_delete_specific(val tree, struct tree *tr, val thisnode) { if (tr->root) { + val nkey = key(thisnode); + val key = if3(tr->key_fn, funcall1(tr->key_fn, nkey), nkey); val node = tr_do_delete_specific(tree, tr, tr->root, - nil, key(thisnode), thisnode); + nil, key, thisnode); if (node) { if (2 * --tr->size < tr->max_size) { tr_rebuild(tree, tr, tr->root, nil, tr->size); |