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))