change 'helpInsert' function to return trie instead of trie option (I would guess there are fewer cases where the same string is inserted into the trie repeatedly)

This commit is contained in:
2024-09-04 12:05:43 +01:00
parent 90019de17f
commit 0d25b88caa
2 changed files with 17 additions and 42 deletions

Binary file not shown.

View File

@@ -220,7 +220,6 @@ struct
) = ) =
let let
val childNode = CHILDREN {keys = childKeys, children = childChildren} val childNode = CHILDREN {keys = childKeys, children = childChildren}
val keys = val keys =
Vector.mapi Vector.mapi
(fn (idx, key) => if idx <> insIdx then key else splitTrieKeyStart) (fn (idx, key) => if idx <> insIdx then key else splitTrieKeyStart)
@@ -230,9 +229,8 @@ struct
Vector.mapi (fn (idx, elt) => if idx <> insIdx then elt else childNode) Vector.mapi (fn (idx, elt) => if idx <> insIdx then elt else childNode)
parentChildren parentChildren
val node = CHILDREN {keys = keys, children = children}
in in
SOME node CHILDREN {keys = keys, children = children}
end end
(* (*
@@ -240,21 +238,16 @@ struct
* - Complete code for FOUND_WITH_CHILDREN case in insert function. * - Complete code for FOUND_WITH_CHILDREN case in insert function.
*) *)
fun helpInsert (insKey, keyPos, trie) : t option = fun helpInsert (insKey, keyPos, trie) : t =
case trie of case trie of
FOUND => FOUND =>
let if keyPos = String.size insKey then
val node = FOUND
if keyPos = String.size insKey then else
FOUND FOUND_WITH_CHILDREN
else { keys = Vector.fromList [insKey]
FOUND_WITH_CHILDREN , children = Vector.fromList [FOUND]
{ keys = Vector.fromList [insKey] }
, children = Vector.fromList [FOUND]
}
in
SOME node
end
| CHILDREN {keys, children} => | CHILDREN {keys, children} =>
let let
val findChr = String.sub (insKey, keyPos) val findChr = String.sub (insKey, keyPos)
@@ -273,9 +266,8 @@ struct
else if idx > insIdx then Vector.sub (children, idx - 1) else if idx > insIdx then Vector.sub (children, idx - 1)
else FOUND) else FOUND)
val node = CHILDREN {keys = newKeys, children = newChildren}
in in
SOME node CHILDREN {keys = newKeys, children = newChildren}
end end
| FOUND_INSERT_POS insIdx => | FOUND_INSERT_POS insIdx =>
let let
@@ -283,7 +275,7 @@ struct
val nextKeyPos = keyPos + 1 val nextKeyPos = keyPos + 1
in in
(case insertKeyMatch (insKey, trieKey, nextKeyPos) of (case insertKeyMatch (insKey, trieKey, nextKeyPos) of
NO_INSERT_MATCH => SOME trie NO_INSERT_MATCH => trie
(* 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
@@ -342,23 +334,14 @@ struct
* however, if this is a non-found node, then I need to change * however, if this is a non-found node, then I need to change
* the tag/case. *) * the tag/case. *)
| FULL_INSERT_MATCH => | FULL_INSERT_MATCH =>
let FOUND_WITH_CHILDREN {keys = keys, children = children}
val node =
FOUND_WITH_CHILDREN {keys = keys, children = children}
in
SOME node
end
(* if insert key contains trie key, need to recurse down node *) (* if insert key contains trie key, need to recurse down node *)
| INSERT_KEY_CONTAINS_TRIE_KEY => | INSERT_KEY_CONTAINS_TRIE_KEY =>
let let
val trieChild = Vector.sub (children, insIdx) val trieChild = Vector.sub (children, insIdx)
in in
(case helpInsert
helpInsert (insKey, keyPos + String.size trieKey, trieChild)
(insKey, keyPos + String.size trieKey, trieChild)
of
(result as SOME _) => result
| NONE => SOME trie)
end end
(* if trie key contains insert key, need to split node *) (* if trie key contains insert key, need to split node *)
| TRIE_KEY_CONTAINS_INSERT_KEY => | TRIE_KEY_CONTAINS_INSERT_KEY =>
@@ -385,10 +368,8 @@ struct
if idx <> insIdx then elt else newTrieChild) if idx <> insIdx then elt else newTrieChild)
children children
val node =
CHILDREN {keys = newKeys, children = newChildren}
in in
SOME node CHILDREN {keys = newKeys, children = newChildren}
end) end)
end end
| APPEND_NEW_CHILD => | APPEND_NEW_CHILD =>
@@ -396,20 +377,14 @@ struct
val newKeys = Vector.concat [keys, Vector.fromList [insKey]] val newKeys = Vector.concat [keys, Vector.fromList [insKey]]
val newChildren = Vector.concat val newChildren = Vector.concat
[children, Vector.fromList [FOUND]] [children, Vector.fromList [FOUND]]
val node = CHILDREN {keys = newKeys, children = newChildren}
in in
SOME node CHILDREN {keys = newKeys, children = newChildren}
end) end)
end end
| FOUND_WITH_CHILDREN {keys, children} => raise Empty (* todo *) | FOUND_WITH_CHILDREN {keys, children} => raise Empty (* todo *)
fun insert (insKey, trie) = fun insert (insKey, trie) =
if String.size insKey > 0 then if String.size insKey > 0 then helpInsert (insKey, 0, trie) else trie
case helpInsert (insKey, 0, trie) of
SOME trie => trie
| NONE => trie
else
trie
fun fromString str = fun fromString str =
CHILDREN {keys = Vector.fromList [str], children = Vector.fromList [FOUND]} CHILDREN {keys = Vector.fromList [str], children = Vector.fromList [FOUND]}