Files
meowc/lib/cache.ml
T
milner bf81a54bc2 perf(cache): memoise file digests and invalidate them on write
A header included by fourteen translation units was hashed once per dependent,
and every built action hashed its inputs twice: once to decide it was stale and
again to store the new key. Digests are now memoised for the run, and the
scheduler drops the entries for an action's outputs and depfile once it
finishes, so a freshly written file is never read from the memo.
2022-07-12 08:44:33 +00:00

50 lines
1.6 KiB
OCaml

type t = { path : string; keys : (string, string) Hashtbl.t }
let load path =
let keys = Hashtbl.create 64 in
(match Fs.read path with
| exception Sys_error _ -> ()
| raw ->
String.split_on_char '\n' raw
|> List.iter (fun line ->
match String.index_opt line '\t' with
| None -> ()
| Some i ->
let key = String.sub line 0 i in
let out = String.sub line (i + 1) (String.length line - i - 1) in
if out <> "" then Hashtbl.replace keys out key));
{ path; keys }
let save c =
let b = Buffer.create 4096 in
Hashtbl.iter (fun out key -> Buffer.add_string b (key ^ "\t" ^ out ^ "\n")) c.keys;
Fs.write c.path (Buffer.contents b)
let current c out = Hashtbl.find_opt c.keys out
let put c out key = Hashtbl.replace c.keys out key
let drop c out = Hashtbl.remove c.keys out
let digests : (string, string option) Hashtbl.t = Hashtbl.create 256
let digest_file p =
match Hashtbl.find_opt digests p with
| Some d -> d
| None ->
let d = match Digest.file p with d -> Some (Digest.to_hex d) | exception Sys_error _ -> None in
Hashtbl.replace digests p d;
d
let forget p = Hashtbl.remove digests p
let key ~cmd ~inputs =
let b = Buffer.create 256 in
Buffer.add_string b cmd;
List.iter
(fun p ->
Buffer.add_char b '\000';
Buffer.add_string b p;
Buffer.add_char b '\000';
Buffer.add_string b (match digest_file p with Some d -> d | None -> "?"))
(List.sort compare inputs);
Digest.to_hex (Digest.string (Buffer.contents b))