@@ -15,58 +15,68 @@ let runCompiler () =
1515 FSharp.Compiler.CommandLineMain.main args |> ignore
1616
1717[<CustomEquality; NoComparison>]
18- type Node =
18+ type GenericNode < 'State , 'SingleResult > =
1919 {
2020 Idx : FileIdx
2121 Deps : FileIdx []
2222 TransitiveDeps : FileIdx []
2323 Dependants : FileIdx []
24- mutable PartialResult : string option
25- mutable ThisResult : int option
24+ mutable Result : ( 'SingleResult * 'State ) option
2625 mutable UnprocessedDepsCount : int
2726 _lock : Object
2827 }
2928 override this.Equals ( y ) =
3029 match y with
31- | :? Node as other -> ( this.Idx = other.Idx)
30+ | :? GenericNode < 'State , 'SingleResult > as other -> ( this.Idx = other.Idx)
3231 | _ -> false
3332 override this.GetHashCode () = this.Idx.Idx
3433
34+ module Node =
35+ let idx ( node : GenericNode < _ , _ >) = node.Idx
36+
3537type State = string // TcState
3638type SingleResult = int // partial result for a single file
37-
39+
40+ type Node = GenericNode< State, SingleResult>
41+
3842/// <summary >
39- /// Combine results of all transitive dependencies for a single target node.
43+ /// Combine results of all transitive dependencies
4044/// </summary >
4145/// <param name =" graph " ></param >
4246/// <param name =" deps " >Transitive deps</param >
43- let combineResults ( graph : IDictionary < FileIdx , Node >) ( node : Node ) ( folder : State -> SingleResult -> State ) : State =
44-
47+ let combineResults < 'State , 'SingleResult > ( graph : IDictionary < FileIdx , GenericNode < 'State , 'SingleResult >>) ( transitiveDeps : FileIdx []) ( folder : 'State -> 'SingleResult -> 'State ) : 'State =
4548 // Find the child with most transitive deps
4649 let biggestChild =
47- node.TransitiveDeps
50+ transitiveDeps
4851 |> Array.map ( fun d -> graph[ d])
4952 |> Array.maxBy ( fun n -> n.TransitiveDeps.Length)
5053
5154 // Start with that child's state
52- let state = biggestChild.PartialResult |> Option.defaultWith ( fun () -> failwith " Unexpected lack of result" )
55+ let state = biggestChild.Result |> Option.defaultWith ( fun () -> failwith " Unexpected lack of result" ) |> snd
5356
5457 let alreadyIncluded = HashSet< FileIdx>( biggestChild.TransitiveDeps, HashIdentity.Structural)
5558
5659 // Find individual results from all transitive deps that were not in biggestChild
5760 let toBeAdded =
58- node.TransitiveDeps
61+ transitiveDeps
5962 |> Array.filter alreadyIncluded.Add
6063
6164 // Add those results to the initial one
6265 let state =
6366 toBeAdded
64- |> Array.map ( fun d -> graph[ d]. ThisResult |> Option.defaultWith ( fun () -> failwith " Unexpected lack of result" ))
67+ |> Array.map ( fun d -> graph[ d]. Result |> Option.defaultWith ( fun () -> failwith " Unexpected lack of result" ) |> fst )
6568 |> Array.fold folder state
6669
6770 state
71+
72+ let fold ( state : string ) ( singleResult : int ) =
73+ state + singleResult.ToString()
6874
69- let processGraph ( graph : IDictionary < FileIdx , Node >) =
75+ let actualActualWork ( idx : FileIdx ) ( state : State ) : SingleResult =
76+ let thisResult = idx.Idx
77+ thisResult
78+
79+ let processGraph ( graph : IDictionary < FileIdx , Node >) ( work : FileIdx -> SingleResult * State ) =
7080
7181 printfn " start"
7282 use q = new BlockingCollection< FileIdx>()
@@ -88,28 +98,15 @@ let processGraph (graph : IDictionary<FileIdx, Node>) =
8898 printfn $" UnprocessedCount = {unprocessedCount}"
8999 )
90100
91- let fold ( state : string ) ( singleResult : int ) =
92- state + singleResult.ToString()
93-
94- let actualActualWork ( idx : FileIdx ) ( state : State ) : SingleResult * State =
95- let thisResult = idx.Idx
96- let state = fold state thisResult
97- thisResult, state
98-
99- let actualWork ( idx : FileIdx ) =
100- let node = graph[ idx]
101- let state = combineResults graph node fold
102- let thisResult = actualActualWork idx state
103- thisResult
104-
105- // Processing of a single node/file - gives a result
106- let go ( idx : FileIdx ) =
101+ // Processing of a single node/file
102+ let go ( idx : FileIdx ) : unit =
107103 let node = graph[ idx]
108104 printfn $" Start {idx} -> %+A {node.Deps}"
109105 Thread.Sleep( 500 )
110- let singleResult , state = actualWork idx
111- node.ThisResult <- Some singleResult
112- node.PartialResult <- Some state
106+ let node = graph[ idx]
107+ let state = combineResults graph node.TransitiveDeps fold
108+ let singleResult = actualActualWork idx state
109+ node.Result <- Some ( singleResult, state)
113110 printfn $" Stop {idx} work - SingleResult={singleResult} State={state}"
114111
115112 // Increment processed deps count for all dependants and schedule those who are now unblocked
@@ -152,10 +149,7 @@ let processGraph (graph : IDictionary<FileIdx, Node>) =
152149 printfn " waitall"
153150 Task.WaitAll workers
154151
155- let fullResult =
156- graph
157- |> Seq.map ( fun ( KeyValue ( idx , node )) -> node.PartialResult |> Option.get) // TODO Oops
158- |> Seq.fold ( fun state item -> state + item) " "
152+ let fullResult = combineResults graph ( graph.Values |> Seq.map Node.idx |> Seq.toArray)
159153
160154 printfn $" End result: {fullResult}"
161155
0 commit comments