@@ -62,9 +62,10 @@ func (n *trieNode) addToList(node *trieNode) *trieNode {
62
62
63
63
// Removes node from the linked list.
64
64
// Returns the new head (if it has changed).
65
+ // Returns true if the list is now empty.
65
66
// Should be called on the head node.
66
67
// Will loop forever if node is not in the list.
67
- func (n * trieNode ) removeFromList (c byte ) * trieNode {
68
+ func (n * trieNode ) removeFromList (c byte ) ( * trieNode , bool ) {
68
69
curr := n
69
70
for {
70
71
if curr .c == c {
@@ -78,10 +79,14 @@ func (n *trieNode) removeFromList(c byte) *trieNode {
78
79
79
80
if curr .prev == nil {
80
81
// Head has changed.
81
- return curr .next
82
+ if curr .next == nil {
83
+ // List is now empty.
84
+ return nil , true
85
+ }
86
+ return curr .next , false
82
87
}
83
88
84
- return nil
89
+ return nil , false
85
90
}
86
91
87
92
curr = curr .next
@@ -249,25 +254,37 @@ func (kv *KV[V]) Del(key string) error {
249
254
defer kv .mux .Unlock ()
250
255
251
256
node := kv .trie
252
- var prev * trieNode
257
+ stack := [] * trieNode {}
253
258
for i := 0 ; i < len (key ); i ++ {
254
259
next := node.down [key [i ]]
255
260
if next == nil {
256
- return nil
261
+ // If we are here, the key does not exist.
262
+ return kv .data .Del (key )
257
263
}
258
264
259
- prev = node
265
+ stack = append ( stack , node )
260
266
node = next
261
267
}
262
268
263
269
node .terminal = false
264
270
265
- if node .nextLevelHead == nil && prev != nil {
266
- head := prev .nextLevelHead .removeFromList (node .c )
267
- if head != nil {
268
- prev .nextLevelHead = head
271
+ // Go back the stack removing nodes with no descendants.
272
+ for i := len (stack ) - 1 ; i >= 0 ; i -- {
273
+ prev := stack [i ]
274
+ stack = stack [:i ]
275
+ if node .nextLevelHead == nil {
276
+ head , empty := prev .nextLevelHead .removeFromList (node .c )
277
+ if head != nil || (head == nil && empty ) {
278
+ prev .nextLevelHead = head
279
+ }
280
+ delete (prev .down , node .c )
281
+ }
282
+
283
+ if prev .terminal || len (prev .down ) > 0 && prev == kv .trie {
284
+ break
269
285
}
270
- delete (prev .down , node .c )
286
+
287
+ node = prev
271
288
}
272
289
273
290
return kv .data .Del (key )
0 commit comments