@@ -13,25 +13,17 @@ let queryTrie (trie: TrieNode) (path: ModuleSegment list) : QueryTrieNodeResult
1313 match path with
1414 | [] -> failwith " path should not be empty"
1515 | [ lastNodeFromPath ] ->
16- let childResults =
17- currentNode.Children
18- |> Seq.tryFind ( fun ( KeyValue ( segment , _childNode )) -> segment = lastNodeFromPath)
19-
20- match childResults with
21- | None -> QueryTrieNodeResult.NodeDoesNotExist
22- | Some ( KeyValue (_, childNode)) ->
16+ match currentNode.Children.TryGetValue( lastNodeFromPath) with
17+ | false , _ -> QueryTrieNodeResult.NodeDoesNotExist
18+ | true , childNode ->
2319 if Set.isEmpty childNode.Files then
2420 QueryTrieNodeResult.NodeDoesNotExposeData
2521 else
2622 QueryTrieNodeResult.NodeExposesData( childNode.Files)
2723 | currentPath :: restPath ->
28- let childResults =
29- currentNode.Children
30- |> Seq.tryFind ( fun ( KeyValue ( segment , _childNode )) -> segment = currentPath)
31-
32- match childResults with
33- | None -> QueryTrieNodeResult.NodeDoesNotExist
34- | Some ( KeyValue (_, childNode)) -> visit childNode restPath
24+ match currentNode.Children.TryGetValue( currentPath) with
25+ | false , _ -> QueryTrieNodeResult.NodeDoesNotExist
26+ | true , childNode -> visit childNode restPath
3527
3628 visit trie path
3729
@@ -91,7 +83,7 @@ let rec processStateEntry (queryTrie: QueryTrie) (state: FileContentQueryState)
9183 // The extended path could add a new link (in case of a module or namespace with types)
9284 // It might also not add anything at all (in case it the extended path is still a partial one)
9385 ( stateAfterFullOpenPath, state.OpenNamespaces)
94- ||> Seq .fold ( fun acc openNS -> processOpenPath queryTrie [ yield ! openNS; yield ! path ] acc)
86+ ||> Set .fold ( fun acc openNS -> processOpenPath queryTrie [ yield ! openNS; yield ! path ] acc)
9587
9688 | FileContentEntry.PrefixedIdentifier path ->
9789 match path with
@@ -101,14 +93,14 @@ let rec processStateEntry (queryTrie: QueryTrie) (state: FileContentQueryState)
10193 | _ ->
10294 // path could consist out of multiple segments
10395 ( state, [| 1 .. path.Length |])
104- ||> Seq .fold ( fun state takeParts ->
96+ ||> Array .fold ( fun state takeParts ->
10597 let path = List.take takeParts path
10698 // process the name was if it were a FQN
10799 let stateAfterFullIdentifier = processIdentifier queryTrie path state
108100
109101 // Process the name in combination with the existing open namespaces
110102 ( stateAfterFullIdentifier, state.OpenNamespaces)
111- ||> Seq .fold ( fun acc openNS -> processIdentifier queryTrie [ yield ! openNS; yield ! path ] acc))
103+ ||> Set .fold ( fun acc openNS -> processIdentifier queryTrie [ yield ! openNS; yield ! path ] acc))
112104
113105 | FileContentEntry.NestedModule ( nestedContent = nestedContent) ->
114106 // We don't want our current state to be affect by any open statements in the nested module
@@ -133,32 +125,28 @@ let time msg f a =
133125
134126/// Returns a list of all the files that child nodes contain
135127let indexesUnderNode ( node : TrieNode ) : Set < int > =
136- let rec collect ( node : TrieNode ) ( continuation : int seq -> int seq ) : int seq =
137- let continuations : (( int seq -> int seq ) -> int seq ) list =
138- node.Children
139- |> Seq.map ( fun ( KeyValue ( _ , node )) -> collect node)
140- |> Seq.toList
128+ let rec collect ( node : TrieNode ) ( continuation : int list -> int list ) : int list =
129+ let continuations : (( int list -> int list ) -> int list ) list =
130+ [
131+ for node in node.Children.Values do
132+ yield collect node
133+ ]
141134
142135 let finalContinuation indexes =
143- continuation (
144- seq {
145- yield ! node.Files
146- yield ! Seq.collect id indexes
147- }
148- )
136+ continuation [ yield ! node.Files; yield ! List.collect id indexes ]
149137
150138 Continuation.sequence continuations finalContinuation
151139
152- Set.ofSeq ( collect node id)
140+ Set.ofList ( collect node id)
153141
154142/// A "ghost" dependency is a link between files that actually should be avoided.
155143/// The user has a partial namespace or opens a namespace that does not produce anything.
156144/// In order to still be able to compile the current file, the given namespace should be known to the file.
157145/// We did not find it via the trie, because there are no files that contribute to this namespace.
158146let collectGhostDependencies ( fileIndex : int ) ( trie : TrieNode ) ( queryTrie : QueryTrie ) ( result : FileContentQueryState ) =
159147 // Go over all open namespaces, and assert all those links eventually went anywhere
160- result.OpenedNamespaces
161- |> Seq .collect ( fun path ->
148+ Set.toArray result.OpenedNamespaces
149+ |> Array .collect ( fun path ->
162150 match queryTrie path with
163151 | QueryTrieNodeResult.NodeExposesData _
164152 | QueryTrieNodeResult.NodeDoesNotExist -> Array.empty
@@ -188,7 +176,6 @@ let collectGhostDependencies (fileIndex: int) (trie: TrieNode) (queryTrie: Query
188176 else
189177 // The partial open did eventually lead to a link in a file
190178 Array.empty)
191- |> Seq.toArray
192179
193180let mkGraph ( files : FileWithAST array ) =
194181 // Implementation files backed by signatures should be excluded to construct the trie.
@@ -229,6 +216,7 @@ let mkGraph (files: FileWithAST array) =
229216
230217 // Process all entries of a file and query the trie when required to find the dependent files.
231218 let result =
219+ // Seq is faster than List in this case.
232220 Seq.fold ( processStateEntry queryTrie) ( FileContentQueryState.Create file.Idx knownFiles) fileContent
233221
234222 // after processing the file we should verify if any of the open statements are found in the trie but do not yield any file link.
0 commit comments