feat(cache): key actions on content, argv and the real input set
Digests every input plus the exact argument vector into one key, persisted under the build directory. Staleness becomes a content question rather than a timestamp comparison.
This commit is contained in:
1 file changed
+39
@@ -0,0 +1,39 @@
|
||||
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 digest_file p = match Digest.file p with d -> Some (Digest.to_hex d) | exception Sys_error _ -> None
|
||||
|
||||
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))
|
||||
Reference in new issue
Block a user