Source file file_id.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
type t = Unix.stats

let null_stat =
  { Unix.st_dev = -1;
    st_ino = -1;
    st_kind = Unix.S_REG;
    st_nlink = -1;
    st_perm = -1;
    st_uid = -1;
    st_gid = -1;
    st_rdev = -1;
    st_size = -1;
    st_atime = nan;
    st_mtime = nan;
    st_ctime = nan
  }

let get_res filename =
  try Result.ok @@ Unix.stat filename
  with _ -> Error ("Stat for" ^ filename ^ "couldn't be gathered")

let get filename =
  match get_res filename with
  | Ok fn -> fn
  | Error _ -> null_stat

let check a b =
  a == b
  || a != null_stat && b != null_stat
     &&
     let open Unix in
     a.st_mtime = b.st_mtime && a.st_size = b.st_size && a.st_ino = b.st_ino
     && a.st_dev = b.st_dev

let cache = ref None

let with_cache k = Std.let_ref cache (Some (Hashtbl.create 7)) k

let get filename =
  match !cache with
  | None -> get filename
  | Some table -> (
    match Hashtbl.find table filename with
    | stats ->
      Logger.log ~section:"stat_cache" ~title:"reuse cache" "%s" filename;
      stats
    | exception Not_found ->
      let stats = get filename in
      Hashtbl.add table filename stats;
      stats)