[utils] Cache results of realpath

Summary: Speed up capture on MacOS by caching results of realpath. Improvements to lint speed on MacOS will be sent later

Reviewed By: jvillard

Differential Revision: D4166902

fbshipit-source-id: 4d065bc
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent 6ffaded4be
commit 1a4d165d44

@ -236,7 +236,7 @@ let initial_analysis_time = Unix.time ()
(* Resolve symlinks to get to the real executable. The real executable is located in [bin_dir] (* Resolve symlinks to get to the real executable. The real executable is located in [bin_dir]
below, which allows us to find [lib_dir], [models_dir], etc., relative to it. *) below, which allows us to find [lib_dir], [models_dir], etc., relative to it. *)
let real_exe_name = let real_exe_name =
Core.Std.Filename.realpath Sys.executable_name realpath Sys.executable_name
let current_exe = let current_exe =
if !Sys.interactive then CLOpt.Interactive if !Sys.interactive then CLOpt.Interactive
@ -402,7 +402,7 @@ let init_work_dir, is_originator =
Sys.getcwd () Sys.getcwd ()
with _ -> with _ ->
Sys.getcwd () in Sys.getcwd () in
let real_cwd = Core.Std.Filename.realpath cwd in let real_cwd = realpath cwd in
Unix.putenv "INFER_CWD" real_cwd; Unix.putenv "INFER_CWD" real_cwd;
(real_cwd, true) (real_cwd, true)
@ -1465,7 +1465,6 @@ and print_types = !print_types
and print_using_diff = !print_using_diff and print_using_diff = !print_using_diff
and procs_csv = !procs_csv and procs_csv = !procs_csv
and procs_xml = !procs_xml and procs_xml = !procs_xml
and project_root_realpath = Core.Std.Filename.realpath project_root
and quandary = !quandary and quandary = !quandary
and quiet = !quiet and quiet = !quiet
and reactive_mode = !reactive and reactive_mode = !reactive

@ -228,7 +228,6 @@ val print_using_diff : bool
val procs_csv : string option val procs_csv : string option
val procs_xml : string option val procs_xml : string option
val project_root : string val project_root : string
val project_root_realpath : string
val quandary : bool val quandary : bool
val quiet : bool val quiet : bool
val reactive_mode : bool val reactive_mode : bool

@ -662,3 +662,12 @@ let rec create_path path =
| Unix.Unix_error (Unix.ENOENT, _, _) -> | Unix.Unix_error (Unix.ENOENT, _, _) ->
create_path (Filename.dirname path); create_path (Filename.dirname path);
create_dir path create_dir path
let realpath_cache = Hashtbl.create 1023
let realpath path =
try Hashtbl.find realpath_cache path
with Not_found ->
let realpath = Core.Std.Filename.realpath path in
Hashtbl.add realpath_cache path realpath;
realpath

@ -298,3 +298,7 @@ val create_dir : string -> unit
(** [create_path path] will create a directory at [path], creating all the parent directories if (** [create_path path] will create a directory at [path], creating all the parent directories if
non-existing *) non-existing *)
val create_path : string -> unit val create_path : string -> unit
(** [realpath path] returns path with all symbolic links resolved. It caches results of previous
calls to avoid expensive system calls *)
val realpath : string -> string

@ -30,21 +30,14 @@ let clang_to_sil_location trans_unit_ctx clang_loc =
Location.{line; col; file} Location.{line; col; file}
let file_in_project file = let file_in_project file =
(* Look at file paths before resolving them to real paths. Do it to (* IMPORTANT: results of realpath are cached to not ruin performance *)
improve performance of most likely case when calling realpath is not needed *) let real_root = realpath Config.project_root in
let file_in_project, used_project_root, used_file = let real_file = realpath file in
if string_is_prefix Config.project_root file then let file_in_project = string_is_prefix real_root real_file in
true, Config.project_root, file
else if string_is_prefix Config.project_root_realpath file then
true, Config.project_root_realpath, file
else
let real_root = Config.project_root_realpath in
let real_file = Core.Std.Filename.realpath file in
string_is_prefix real_root real_file, real_root, real_file in
let paths = Config.skip_translation_headers in let paths = Config.skip_translation_headers in
let file_should_be_skipped = let file_should_be_skipped =
IList.exists IList.exists
(fun path -> string_is_prefix (Filename.concat used_project_root path) used_file) (fun path -> string_is_prefix (Filename.concat real_root path) real_file)
paths in paths in
file_in_project && not (file_should_be_skipped) file_in_project && not (file_should_be_skipped)

Loading…
Cancel
Save