@@ -718,15 +718,19 @@ module Cached_value = struct
718
718
t.deps < - capture_dep_values ~deps_rev ;
719
719
t
720
720
721
- let value_changed (type o ) (node : (_, o) Dep_node.t ) prev_output curr_output
722
- =
723
- match (prev_output, curr_output) with
724
- | (Value. Error _ | Cancelled _ ), _ -> true
725
- | _ , (Value. Error _ | Cancelled _ ) -> true
726
- | Ok prev_output , Ok curr_output -> (
721
+ let value_changed (node : _ Dep_node.t ) prev_value cur_value =
722
+ match ((prev_value : _ Value.t ), (cur_value : _ Value.t )) with
723
+ | Cancelled _, _
724
+ | _, Cancelled _
725
+ | Error _, Ok _
726
+ | Ok _ , Error _ ->
727
+ true
728
+ | Ok prev_value , Ok cur_value -> (
727
729
match node.without_state.spec.allow_cutoff with
728
- | Yes equal -> not (equal prev_output curr_output )
730
+ | Yes equal -> not (equal prev_value cur_value )
729
731
| No -> true )
732
+ | Error prev_error , Error cur_error ->
733
+ not (Exn_set. equal prev_error cur_error)
730
734
end
731
735
732
736
(* Add a dependency on the [dep_node] from the caller, if there is one. Returns
@@ -832,7 +836,7 @@ let dep_node (t : (_, _) t) input =
832
836
833
837
- [Unchanged]: all the dependencies of the current node are up to date and we
834
838
can therefore skip recomputing the node and can reuse the value computed in
835
- the previuos run.
839
+ the previous run.
836
840
837
841
- [Changed]: one of the dependencies has changed since the previous run and
838
842
the current node should therefore be recomputed.
@@ -873,13 +877,15 @@ end = struct
873
877
(* Dependencies of cancelled computations are not accurate, so we can't
874
878
use [deps_changed] in this case. *)
875
879
Fiber. return (Error Cache_lookup.Failure. Not_found )
876
- | Error _ ->
877
- (* We always recompute errors, so there is no point in checking if any
878
- of their dependencies changed. In principle, we could introduce
879
- "persistent errors" that are recomputed only when their dependencies
880
- have changed. *)
881
- Fiber. return (Error Cache_lookup.Failure. Not_found )
882
- | Ok _ -> (
880
+ | Ok _
881
+ | Error _ -> (
882
+ (* We cache errors just like normal values. We assume that all [Memo]
883
+ computations are deterministic, which means if we rerun a computation
884
+ that previously led to raising a set of errors, we expect to get the
885
+ same set of errors back and we might as well skip the unnecessary
886
+ work. The downside is that if a computation is non-deterministic,
887
+ there is no way to force rerunning it, apart from changing some of
888
+ its dependencies. *)
883
889
let + deps_changed =
884
890
let rec go deps =
885
891
match deps with
@@ -891,8 +897,16 @@ end = struct
891
897
is up to date. If not, we must recompute [last_cached_value]. *)
892
898
let * restore_result = consider_and_restore_from_cache dep in
893
899
match restore_result with
894
- | Ok cached_value -> (
895
- match Value_id. equal cached_value.id v_id with
900
+ | Ok cached_value_of_dep -> (
901
+ (* Here we know that [dep] can be restored from the cache, so
902
+ how can [v_id] be different from [cached_value_of_dep.id]?
903
+ Good question! This can happen if [cached_value]'s node was
904
+ skipped in the previous run (because it was unreachable),
905
+ while [dep] wasn't skipped and its value changed. In the
906
+ current run, [cached_value] is therefore stale. We learn
907
+ this when we see that the [cached_value_of_dep] is not as
908
+ recorded when computing [cached_value]. *)
909
+ match Value_id. equal cached_value_of_dep.id v_id with
896
910
| true -> go deps
897
911
| false -> Fiber. return Changed_or_not. Changed )
898
912
| Error (Cancelled { dependency_cycle } ) ->
0 commit comments