seem to have fixed error with 'exists' function previously mentioned in todo, without introducing regressions

This commit is contained in:
2024-09-04 18:57:39 +01:00
parent b2b0837524
commit dd41c971e3

View File

@@ -79,9 +79,6 @@ struct
fun helpExists (searchKey, keyPos, trie) = fun helpExists (searchKey, keyPos, trie) =
case trie of case trie of
CHILDREN {keys, children} => CHILDREN {keys, children} =>
if keyPos = String.size searchKey then
false
else
let let
val findChr = String.sub (searchKey, keyPos) val findChr = String.sub (searchKey, keyPos)
in in
@@ -97,20 +94,14 @@ struct
in isFoundNode trieChild in isFoundNode trieChild
end end
| SEARCH_KEY_CONTAINS_TRIE_KEY => | SEARCH_KEY_CONTAINS_TRIE_KEY =>
let let val trieChild = Vector.sub (children, idx)
val trieChild = Vector.sub (children, idx) in helpExists (searchKey, String.size trieKey, trieChild)
in
helpExists
(searchKey, keyPos + String.size trieKey, trieChild)
end end
| TRIE_KEY_CONTAINS_SEARCH_KEY => false) | TRIE_KEY_CONTAINS_SEARCH_KEY => false)
end end
| NONE => false) | NONE => false)
end end
| FOUND_WITH_CHILDREN {keys, children} => | FOUND_WITH_CHILDREN {keys, children} =>
if keyPos = String.size searchKey then
true
else
let let
val findChr = String.sub (searchKey, keyPos) val findChr = String.sub (searchKey, keyPos)
in in
@@ -126,17 +117,24 @@ struct
in isFoundNode trieChild in isFoundNode trieChild
end end
| SEARCH_KEY_CONTAINS_TRIE_KEY => | SEARCH_KEY_CONTAINS_TRIE_KEY =>
let let val trieChild = Vector.sub (children, idx)
val trieChild = Vector.sub (children, idx) in helpExists (searchKey, String.size trieKey, trieChild)
in
helpExists
(searchKey, keyPos + String.size trieKey, trieChild)
end end
| TRIE_KEY_CONTAINS_SEARCH_KEY => false) | TRIE_KEY_CONTAINS_SEARCH_KEY => false)
end end
| NONE => false) | NONE => false)
end end
| FOUND => keyPos = String.size searchKey - 1 | FOUND =>
(*
* This case should only occur if we recurse in a node
* when there is a partial, but not full, string match.
* This is because of the isFoundNode helper function
* which is called by the parent.
* In other words, only the parent node returns true,
* by checking if the child is a found node and has
* a full string match.
*)
false
fun exists (searchKey, trie) = helpExists (searchKey, 0, trie) fun exists (searchKey, trie) = helpExists (searchKey, 0, trie)
@@ -155,8 +153,7 @@ struct
let let
val trieChild = Vector.sub (children, idx) val trieChild = Vector.sub (children, idx)
in in
helpGetPrefixSubtrie helpGetPrefixSubtrie (prefix, String.size trieKey, trieChild)
(prefix, keyPos + String.size trieKey, trieChild)
end end
| FULL_SEARCH_MATCH => | FULL_SEARCH_MATCH =>
let val node = Vector.sub (children, idx) let val node = Vector.sub (children, idx)
@@ -177,7 +174,7 @@ struct
| FOUND_WITH_CHILDREN {keys, children} => | FOUND_WITH_CHILDREN {keys, children} =>
helpGetPrefixSubtrieChildren (prefix, keyPos, keys, children, trie) helpGetPrefixSubtrieChildren (prefix, keyPos, keys, children, trie)
| FOUND => | FOUND =>
if keyPos = String.size prefix then if keyPos = String.size prefix - 1 then
let val node = fromString prefix let val node = fromString prefix
in SOME node in SOME node
end end
@@ -209,7 +206,7 @@ struct
fun getPrefixList (prefix, trie) = fun getPrefixList (prefix, trie) =
case getPrefixSubtrie (prefix, trie) of case getPrefixSubtrie (prefix, trie) of
SOME subtrie => helpGetPrefixList (trie, []) SOME subtrie => helpGetPrefixList (subtrie, [])
| NONE => [] | NONE => []
datatype insert_string_match = datatype insert_string_match =
@@ -351,9 +348,8 @@ struct
fun foundInsertPos (keys, children, keyPos, insKey, insIdx, trie, constructor) = fun foundInsertPos (keys, children, keyPos, insKey, insIdx, trie, constructor) =
let let
val trieKey = Vector.sub (keys, insIdx) val trieKey = Vector.sub (keys, insIdx)
val nextKeyPos = keyPos + 1
in in
(case insertKeyMatch (insKey, trieKey, nextKeyPos) of (case insertKeyMatch (insKey, trieKey, keyPos + 1) of
(* may need to split string if difference found but prefix matched *) (* may need to split string if difference found but prefix matched *)
DIFFERENCE_FOUND_AT diffIdx => DIFFERENCE_FOUND_AT diffIdx =>
let let
@@ -410,8 +406,8 @@ struct
| INSERT_KEY_CONTAINS_TRIE_KEY => | INSERT_KEY_CONTAINS_TRIE_KEY =>
let let
val trieChild = Vector.sub (children, insIdx) val trieChild = Vector.sub (children, insIdx)
val newTrieChild = helpInsert val newTrieChild =
(insKey, keyPos + String.size trieKey, trieChild) helpInsert (insKey, String.size trieKey, trieChild)
val newChildren = val newChildren =
Vector.mapi Vector.mapi
(fn (idx, elt) => if idx <> insIdx then elt else newTrieChild) (fn (idx, elt) => if idx <> insIdx then elt else newTrieChild)
@@ -508,4 +504,10 @@ struct
* todo: * todo:
* - Test prefix searching, which turns found strings to list. * - Test prefix searching, which turns found strings to list.
*) *)
val trie = fromList ["hello", "hit", "hi", "henlo", "help"]
val lst = getPrefixList ("hi", trie)
val helloExists = exists ("hello", trie)
val hitExists = exists ("hit", trie)
val hiExists = exists ("hi", trie)
end end