source/server/checksumMap.ml (74 lines of code) (raw):

(* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. *) open Base type t = string Hashtbl.M(String).t exception LoadError of string let load_from_string text = let open Yojson.Safe in try from_string text |> Util.to_assoc |> List.map ~f:(fun (key, json) -> key, Util.to_string json) |> Hashtbl.of_alist (module String) |> function | `Duplicate_key key -> let message = Format.sprintf "Duplicate key `%s` in checksum map" key in Result.Error message | `Ok state -> Result.Ok state with | Util.Type_error (message, _) | Yojson.Json_error message -> Result.Error message let load { Configuration.UnwatchedFiles.root; checksum_path } = let checksum_full_path = PyrePath.create_relative ~root ~relative:checksum_path in try Stdio.In_channel.read_all (PyrePath.absolute checksum_full_path) |> load_from_string with | Sys_error message -> Result.Error message let load_exn wheel = match load wheel with | Result.Ok result -> result | Result.Error message -> raise (LoadError message) let of_alist_exn list = Hashtbl.of_alist_exn (module String) list let to_alist table = Hashtbl.to_alist table let empty = of_alist_exn [] module Difference = struct module Kind = struct type t = | New | Deleted | Changed [@@deriving sexp, compare] end type t = { kind: Kind.t; path: string; } [@@deriving sexp, compare] end let difference ~original current = let scan_original ~key ~data sofar = match Hashtbl.find current key with | Some right_data -> (* The key exists in both maps *) if String.equal data right_data then sofar else { Difference.kind = Difference.Kind.Changed; path = key } :: sofar | None -> (* The key exists in original but not current *) { Difference.kind = Difference.Kind.Deleted; path = key } :: sofar in let scan_current ~key ~data:_ sofar = match Hashtbl.find original key with | None -> (* The key exists in current but not original. *) { Difference.kind = Difference.Kind.New; path = key } :: sofar | Some _ -> (* We've already handled this case in `scan_left`. *) sofar in let result = Hashtbl.fold original ~init:[] ~f:scan_original in Hashtbl.fold current ~init:result ~f:scan_current