1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586let{Logger.log}=Logger.for_section"Phase cache"moduletypeS=sigtypettypeoutputvalf:t->outputvaltitle:stringmoduleFingerprint:sigtypeinputtypetvalmake:input->(t,string)resultvalequal:t->t->boolendwithtypeinput:=tendmoduleWith_cache(Phase:S)=structmoduleVersion=structtypet=intoptionletequalv1v2=match(v1,v2)with|None,_|_,None->false|Somev1,Somev2->Int.equalv1v2endtypet={output:Phase.output;cache_was_hit:bool;version:Version.t}typecache={fingerprint:Phase.Fingerprint.t;output:Phase.output;version:Version.t}letget_next_version=(* A mutable counter separate from [cache.version] is necessary because of [Phase.f]
erroring. In [apply], when [Phase.f = Error], cache is reset to [None], losing the
value of [next_version] if not stored elsewhere. *)letnext_version=ref0infun():Version.t->letv=Some!next_versioninincrnext_version;vletcache=refNoneletapply?(cache_disabling=None)?(force_invalidation=false)input=lettitle=Phase.titleinmatchcache_disablingwith|Somereason->log~title"Cache is disabled: %s"reason;cache:=None;letoutput=Phase.finputin{output;cache_was_hit=false;version=None}|None->(letnew_fingerprint=Phase.Fingerprint.makeinputinmatch(!cache,new_fingerprint)with|None,Oknew_fingerprint->log~title"Cache wasn't populated\n";letoutput=Phase.finputinletversion=get_next_version()incache:=Some{fingerprint=new_fingerprint;output;version};{output;cache_was_hit=false;version}|Some{fingerprint;output;version=old_version},Oknew_fingerprint->if(notforce_invalidation)&&Phase.Fingerprint.equalfingerprintnew_fingerprintthen(log~title"Cache hit";{output;cache_was_hit=true;version=old_version})else(log~title"Cache invalidation";letoutput=Phase.finputinletversion=get_next_version()incache:=Some{fingerprint=new_fingerprint;output;version};{output;cache_was_hit=false;version})|(None|Some_),Errorerr->log~title"Cache workflow is incomplete: %s"err;cache:=None;letoutput=Phase.finputin{output;cache_was_hit=false;version=None})end