[sql] do not generate the source file for attribute store if they are no-op

Summary: If we know for sure we won't need to store an attribute in the DB, there's no need to compute its marshalled value.

Reviewed By: jberdine

Differential Revision: D5891050

fbshipit-source-id: cf4534e
master
Jules Villard 7 years ago committed by Facebook Github Bot
parent ee1b688e6d
commit 8012d61b0f

@ -62,9 +62,6 @@ let get_replace_statement =
in several files *) in several files *)
(* TRICK: older versions of sqlite (prior to version 3.15.0 (2016-10-14)) do not support row (* TRICK: older versions of sqlite (prior to version 3.15.0 (2016-10-14)) do not support row
values so the lexicographic ordering for (:akind, :sfile) is done by hand *) values so the lexicographic ordering for (:akind, :sfile) is done by hand *)
(* TODO (optim): it might be worth not generating the source file everytime we do a store, but
only generate it if the attribute needs updating (which should be orders of magnitude less
frequent) *)
ResultsDir.register_statement ResultsDir.register_statement
{| {|
INSERT OR REPLACE INTO attributes INSERT OR REPLACE INTO attributes
@ -91,6 +88,24 @@ let replace pname_blob akind loc_file attr_blob =
|> SqliteUtils.check_sqlite_error ~log:"replace bind proc attributes" ; |> SqliteUtils.check_sqlite_error ~log:"replace bind proc attributes" ;
SqliteUtils.sqlite_unit_step ~finalize:false ~log:"Attributes.replace" replace_stmt SqliteUtils.sqlite_unit_step ~finalize:false ~log:"Attributes.replace" replace_stmt
let get_find_more_defined_statement =
ResultsDir.register_statement
{|
SELECT attr_kind
FROM attributes
WHERE proc_name = :pname
AND attr_kind > :akind
|}
let should_try_to_update pname_blob akind =
let find_stmt = get_find_more_defined_statement () in
Sqlite3.bind find_stmt 1 (* :pname *) pname_blob
|> SqliteUtils.check_sqlite_error ~log:"replace bind pname" ;
Sqlite3.bind find_stmt 2 (* :akind *) (Sqlite3.Data.INT (int64_of_attributes_kind akind))
|> SqliteUtils.check_sqlite_error ~log:"replace bind attribute kind" ;
SqliteUtils.sqlite_result_step ~finalize:false ~log:"Attributes.replace" find_stmt
|> (* there is no entry with a strictly larger "definedness" for that proc name *) Option.is_none
let get_select_statement = let get_select_statement =
ResultsDir.register_statement "SELECT proc_attributes FROM attributes WHERE proc_name = :k" ResultsDir.register_statement "SELECT proc_attributes FROM attributes WHERE proc_name = :k"
@ -111,7 +126,8 @@ let load pname = Data.of_pname pname |> find ~defined:false
let store (attr: ProcAttributes.t) = let store (attr: ProcAttributes.t) =
let pkind = proc_kind_of_attr attr in let pkind = proc_kind_of_attr attr in
let key = Data.of_pname attr.proc_name in let key = Data.of_pname attr.proc_name in
replace key pkind (Data.of_source_file attr.loc.Location.file) (Data.of_proc_attr attr) if should_try_to_update key pkind then
replace key pkind (Data.of_source_file attr.loc.Location.file) (Data.of_proc_attr attr)
let load_defined pname = Data.of_pname pname |> find ~defined:true let load_defined pname = Data.of_pname pname |> find ~defined:true

@ -28,7 +28,7 @@ let append_crc_cutoff ?(key= "") ?(crc_only= false) name =
let name_for_crc = name ^ key in let name_for_crc = name ^ key in
Utils.string_crc_hex32 name_for_crc Utils.string_crc_hex32 name_for_crc
in in
if crc_only then crc_str else name_up_to_cutoff ^ Char.to_string crc_token ^ crc_str if crc_only then crc_str else Printf.sprintf "%s%c%s" name_up_to_cutoff crc_token crc_str
(* Lengh of .crc part: 32 characters of digest, plus 1 character of crc_token *) (* Lengh of .crc part: 32 characters of digest, plus 1 character of crc_token *)
let dot_crc_len = 1 + 32 let dot_crc_len = 1 + 32

@ -27,7 +27,7 @@ val sqlite_result_rev_list_step :
(** Return a reversed list of results obtained by repeatedly stepping through [stmt] and saving only column 0 of each returned row (all that's been needed so far). *) (** Return a reversed list of results obtained by repeatedly stepping through [stmt] and saving only column 0 of each returned row (all that's been needed so far). *)
val sqlite_result_step : ?finalize:bool -> log:string -> Sqlite3.stmt -> Sqlite3.Data.t option val sqlite_result_step : ?finalize:bool -> log:string -> Sqlite3.stmt -> Sqlite3.Data.t option
(** Same as [sqlite_result_rev_list_step] but asserts that exactly one result is returned. *) (** Same as [sqlite_result_rev_list_step] but asserts that at most one result is returned. *)
val sqlite_unit_step : ?finalize:bool -> log:string -> Sqlite3.stmt -> unit val sqlite_unit_step : ?finalize:bool -> log:string -> Sqlite3.stmt -> unit
(** Same as [sqlite_result_rev_list_step] but asserts that no result is returned. *) (** Same as [sqlite_result_rev_list_step] but asserts that no result is returned. *)

Loading…
Cancel
Save