@@ -696,36 +696,38 @@ module Solver = struct
696
696
might need, adding all of them to [sat_problem]. *)
697
697
let build_problem context root_req sat ~dummy_impl =
698
698
(* For each (iface, source) we have a list of implementations. *)
699
- let impl_cache = ref Input.Role.Map. empty in
699
+ let impl_cache = Fiber_cache. create ( module Input. Role ) in
700
700
let conflict_classes = Conflict_classes. create () in
701
701
let + () =
702
702
let rec lookup_impl expand_deps role =
703
- match Input.Role.Map. find ! impl_cache role with
704
- | Some s -> Fiber. return s
705
- | None ->
706
- let * clause, impls =
707
- Candidates. make_impl_clause sat context ~dummy_impl role
708
- in
709
- impl_cache := Input.Role.Map. set ! impl_cache role clause;
710
- let + () =
711
- Fiber. sequential_iter impls ~f: (fun { var = impl_var ; impl } ->
712
- Conflict_classes. process conflict_classes impl_var impl;
713
- match expand_deps with
714
- | `No_expand -> Fiber. return ()
715
- | `Expand_and_collect_conflicts deferred ->
716
- Input.Impl. requires role impl
717
- |> Fiber. sequential_iter ~f: (fun (dep : Input.dependency ) ->
718
- match dep.importance with
719
- | Ensure -> process_dep expand_deps impl_var dep
720
- | Prevent ->
721
- (* Defer processing restricting deps until all essential
722
- deps have been processed for the entire problem.
723
- Restricting deps will be processed later without
724
- recurring into their dependencies. *)
725
- deferred := (impl_var, dep) :: ! deferred;
726
- Fiber. return () ))
727
- in
728
- clause
703
+ let impls = ref [] in
704
+ let * clause =
705
+ Fiber_cache. find_or_add impl_cache role ~f: (fun () ->
706
+ let + clause, impls' =
707
+ Candidates. make_impl_clause sat context ~dummy_impl role
708
+ in
709
+ impls := impls';
710
+ clause)
711
+ in
712
+ let + () =
713
+ Fiber. parallel_iter ! impls ~f: (fun { var = impl_var ; impl } ->
714
+ Conflict_classes. process conflict_classes impl_var impl;
715
+ match expand_deps with
716
+ | `No_expand -> Fiber. return ()
717
+ | `Expand_and_collect_conflicts deferred ->
718
+ Input.Impl. requires role impl
719
+ |> Fiber. parallel_iter ~f: (fun (dep : Input.dependency ) ->
720
+ match dep.importance with
721
+ | Ensure -> process_dep expand_deps impl_var dep
722
+ | Prevent ->
723
+ (* Defer processing restricting deps until all essential
724
+ deps have been processed for the entire problem.
725
+ Restricting deps will be processed later without
726
+ recurring into their dependencies. *)
727
+ deferred := (impl_var, dep) :: ! deferred;
728
+ Fiber. return () ))
729
+ in
730
+ clause
729
731
and process_dep expand_deps user_var (dep : Input.dependency ) : unit Fiber.t =
730
732
(* Process a dependency of [user_var]:
731
733
- find the candidate implementations to satisfy it
@@ -776,13 +778,12 @@ module Solver = struct
776
778
restricting dependencies are irrelevant to solving the dependency
777
779
problem. *)
778
780
List. rev ! conflicts
779
- |> Fiber. sequential_iter ~f: (fun (impl_var , dep ) ->
781
+ |> Fiber. parallel_iter ~f: (fun (impl_var , dep ) ->
780
782
process_dep `No_expand impl_var dep)
781
783
(* All impl_candidates have now been added, so snapshot the cache. *)
782
784
in
783
- let impl_clauses = ! impl_cache in
784
785
Conflict_classes. seal conflict_classes;
785
- impl_clauses
786
+ impl_cache
786
787
;;
787
788
788
789
(* * [do_solve model req] finds an implementation matching the given
@@ -807,7 +808,8 @@ module Solver = struct
807
808
*)
808
809
let sat = Sat. create () in
809
810
let dummy_impl = if closest_match then Some Input. Dummy else None in
810
- let + impl_clauses = build_problem context root_req sat ~dummy_impl in
811
+ let * impl_clauses = build_problem context root_req sat ~dummy_impl in
812
+ let + impl_clauses = Fiber_cache. to_table impl_clauses in
811
813
(* Run the solve *)
812
814
let decider () =
813
815
(* Walk the current solution, depth-first, looking for the first
@@ -819,7 +821,7 @@ module Solver = struct
819
821
then None (* Break cycles *)
820
822
else (
821
823
Table. set seen req true ;
822
- match Input.Role.Map . find_exn impl_clauses req |> Candidates. state with
824
+ match Table . find_exn impl_clauses req |> Candidates. state with
823
825
| Unselected -> None
824
826
| Undecided lit -> Some lit
825
827
| Selected deps ->
@@ -841,7 +843,13 @@ module Solver = struct
841
843
| false -> None
842
844
| true ->
843
845
(* Build the results object *)
844
- Some (Input.Role.Map. filter_map impl_clauses ~f: Candidates. selected)
846
+ Some
847
+ (Table. to_list impl_clauses
848
+ |> List. filter_map ~f: (fun (key , v ) ->
849
+ match Candidates. selected v with
850
+ | None -> None
851
+ | Some v -> Some (key, v))
852
+ |> Input.Role.Map. of_list_exn)
845
853
;;
846
854
end
847
855
0 commit comments