From a4abbbdc3c3af2b24a6aea065c700e9aca4f50b5 Mon Sep 17 00:00:00 2001 From: sneeker Date: Sun, 12 Jun 2022 01:49:31 +0000 Subject: [PATCH] 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. --- lib/cache.ml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 lib/cache.ml diff --git a/lib/cache.ml b/lib/cache.ml new file mode 100644 index 0000000..19607e0 --- /dev/null +++ b/lib/cache.ml @@ -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))