fix all bugs in remove5; now, all remove tests have been ported and they all pass fully; should port other tests from KTrie next too
This commit is contained in:
@@ -532,7 +532,8 @@ struct
|
|||||||
|
|
||||||
(* should be called when there is a FULL_SEARCH_MATCH
|
(* should be called when there is a FULL_SEARCH_MATCH
|
||||||
* and child is a terminal FOUND node *)
|
* and child is a terminal FOUND node *)
|
||||||
fun removeWhenChildIsMadeEmpty (idx, keys, children, parentConstructor) =
|
fun removeWhenChildIsMadeEmpty
|
||||||
|
(idx, keys, children, isFoundWithChildren, parentConstructor) =
|
||||||
(* if child was made empty, then:
|
(* if child was made empty, then:
|
||||||
* - if the parent only has 1 child, it should be MADE_EMPTY too
|
* - if the parent only has 1 child, it should be MADE_EMPTY too
|
||||||
* - otherwise, just remove the key and child at this idx from parent
|
* - otherwise, just remove the key and child at this idx from parent
|
||||||
@@ -570,11 +571,22 @@ struct
|
|||||||
CHANGED newNode
|
CHANGED newNode
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
MADE_EMPTY
|
(* if the caller was from the FOUND_WITH_CHILDREN case,
|
||||||
|
* then, instead of deleting this node entirely,
|
||||||
|
* we only delete this node's children, and mark this node
|
||||||
|
* as found.
|
||||||
|
* However, in general case where this is a CHILDREN node
|
||||||
|
* whose key was not inserted into the trie,
|
||||||
|
* we should fully delete this node as well. *)
|
||||||
|
if isFoundWithChildren then
|
||||||
|
CHANGED FOUND
|
||||||
|
else
|
||||||
|
MADE_EMPTY
|
||||||
|
|
||||||
(* should be called when searchKeyMatch returns FULL_MATCH
|
(* should be called when searchKeyMatch returns FULL_MATCH
|
||||||
*in helpRemove function *)
|
*in helpRemove function *)
|
||||||
fun removeWhenFullMatch (idx, keys, children, parentConstructor) =
|
fun removeWhenFullMatch
|
||||||
|
(idx, keys, children, isFoundWithChildren, parentConstructor) =
|
||||||
(* matching over the child at this idx *)
|
(* matching over the child at this idx *)
|
||||||
case Vector.sub (children, idx) of
|
case Vector.sub (children, idx) of
|
||||||
(* CHILDREN is a not-found case, so have to leave parent unchanged
|
(* CHILDREN is a not-found case, so have to leave parent unchanged
|
||||||
@@ -596,10 +608,11 @@ struct
|
|||||||
CHANGED newParent
|
CHANGED newParent
|
||||||
end
|
end
|
||||||
| FOUND =>
|
| FOUND =>
|
||||||
removeWhenChildIsMadeEmpty (idx, keys, children, parentConstructor)
|
removeWhenChildIsMadeEmpty
|
||||||
|
(idx, keys, children, isFoundWithChildren, parentConstructor)
|
||||||
|
|
||||||
fun removeWhenSearchKeyContainsTrieKey
|
fun removeWhenSearchKeyContainsTrieKey
|
||||||
(childResult, idx, keys, children, parentConstructor) =
|
(childResult, idx, keys, children, isFoundWithChildren, parentConstructor) =
|
||||||
case childResult of
|
case childResult of
|
||||||
(* if result is UNCHANGED, let UNCHANGED bubble to the top.
|
(* if result is UNCHANGED, let UNCHANGED bubble to the top.
|
||||||
* At the top, can return same trie given as input as there was no
|
* At the top, can return same trie given as input as there was no
|
||||||
@@ -619,7 +632,8 @@ struct
|
|||||||
CHANGED newNode
|
CHANGED newNode
|
||||||
end
|
end
|
||||||
| MADE_EMPTY =>
|
| MADE_EMPTY =>
|
||||||
removeWhenChildIsMadeEmpty (idx, keys, children, parentConstructor)
|
removeWhenChildIsMadeEmpty
|
||||||
|
(idx, keys, children, isFoundWithChildren, parentConstructor)
|
||||||
|
|
||||||
fun helpRemove (removeKey, keyPos, trie) =
|
fun helpRemove (removeKey, keyPos, trie) =
|
||||||
case trie of
|
case trie of
|
||||||
@@ -636,7 +650,7 @@ struct
|
|||||||
(* no search match means nothing to delete *)
|
(* no search match means nothing to delete *)
|
||||||
NO_SEARCH_MATCH => UNCHANGED
|
NO_SEARCH_MATCH => UNCHANGED
|
||||||
| FULL_SEARCH_MATCH =>
|
| FULL_SEARCH_MATCH =>
|
||||||
removeWhenFullMatch (idx, keys, children, CHILDREN)
|
removeWhenFullMatch (idx, keys, children, false, CHILDREN)
|
||||||
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
||||||
removeWhenSearchKeyContainsTrieKey
|
removeWhenSearchKeyContainsTrieKey
|
||||||
( helpRemove
|
( helpRemove
|
||||||
@@ -647,6 +661,7 @@ struct
|
|||||||
, idx
|
, idx
|
||||||
, keys
|
, keys
|
||||||
, children
|
, children
|
||||||
|
, false
|
||||||
, CHILDREN
|
, CHILDREN
|
||||||
)
|
)
|
||||||
| TRIE_KEY_CONTAINS_SEARCH_KEY => UNCHANGED)
|
| TRIE_KEY_CONTAINS_SEARCH_KEY => UNCHANGED)
|
||||||
@@ -667,7 +682,7 @@ struct
|
|||||||
NO_SEARCH_MATCH => UNCHANGED
|
NO_SEARCH_MATCH => UNCHANGED
|
||||||
| FULL_SEARCH_MATCH =>
|
| FULL_SEARCH_MATCH =>
|
||||||
removeWhenFullMatch
|
removeWhenFullMatch
|
||||||
(idx, keys, children, FOUND_WITH_CHILDREN)
|
(idx, keys, children, true, FOUND_WITH_CHILDREN)
|
||||||
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
||||||
removeWhenSearchKeyContainsTrieKey
|
removeWhenSearchKeyContainsTrieKey
|
||||||
( helpRemove
|
( helpRemove
|
||||||
@@ -678,6 +693,7 @@ struct
|
|||||||
, idx
|
, idx
|
||||||
, keys
|
, keys
|
||||||
, children
|
, children
|
||||||
|
, true
|
||||||
, FOUND_WITH_CHILDREN
|
, FOUND_WITH_CHILDREN
|
||||||
)
|
)
|
||||||
| TRIE_KEY_CONTAINS_SEARCH_KEY => UNCHANGED)
|
| TRIE_KEY_CONTAINS_SEARCH_KEY => UNCHANGED)
|
||||||
@@ -701,9 +717,4 @@ struct
|
|||||||
CHANGED trie => trie
|
CHANGED trie => trie
|
||||||
| MADE_EMPTY => empty
|
| MADE_EMPTY => empty
|
||||||
| UNCHANGED => trie
|
| UNCHANGED => trie
|
||||||
|
|
||||||
(*
|
|
||||||
* todo:
|
|
||||||
* test remove functionality
|
|
||||||
* *)
|
|
||||||
end
|
end
|
||||||
|
|||||||
Binary file not shown.
@@ -126,8 +126,6 @@ struct
|
|||||||
val trie = StringSet.remove ("x", trie)
|
val trie = StringSet.remove ("x", trie)
|
||||||
val _ = assertFalse (StringSet.exists ("x", trie), "x does not exist after remove in remove5")
|
val _ = assertFalse (StringSet.exists ("x", trie), "x does not exist after remove in remove5")
|
||||||
|
|
||||||
(* error: "abc" should exist at this point, but it seems not to.
|
|
||||||
* find out why and fix. *)
|
|
||||||
val _ = assertTrue (StringSet.exists ("abc", trie), "abc exists before remove in remove5")
|
val _ = assertTrue (StringSet.exists ("abc", trie), "abc exists before remove in remove5")
|
||||||
val trie = StringSet.remove ("abc", trie)
|
val trie = StringSet.remove ("abc", trie)
|
||||||
val _ = assertFalse (StringSet.exists ("abc", trie), "abc does not exist after remove in remove5")
|
val _ = assertFalse (StringSet.exists ("abc", trie), "abc does not exist after remove in remove5")
|
||||||
|
|||||||
Reference in New Issue
Block a user