From db9828809e728b20fee20fcde9b0196860a4000f Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Fri, 4 Sep 2020 05:05:34 -0700 Subject: [PATCH] [sourcefiles] use custom serializer Summary: Given the brittleness of DB-indexing over marshalled values (one example exposed in D23191601), the serializer "for comparison" must be removed. Its only use is for source files, and these have an obvious, trivial (and possibly faster and less space hungry) protocol. Reviewed By: jberdine Differential Revision: D23499481 fbshipit-source-id: 57ad0ced6 --- infer/src/base/SourceFile.ml | 41 +++++++++++++++++++++------------- infer/src/base/SqliteUtils.ml | 14 ------------ infer/src/base/SqliteUtils.mli | 6 ----- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/infer/src/base/SourceFile.ml b/infer/src/base/SourceFile.ml index 21d15abb7..9b1cbd0f1 100644 --- a/infer/src/base/SourceFile.ml +++ b/infer/src/base/SourceFile.ml @@ -139,24 +139,33 @@ let changed_sources_from_changed_files changed_files = module SQLite = struct - module T = struct - type nonrec t = t - end + type nonrec t = t - module Serializer = SqliteUtils.MarshalledDataForComparison (T) - include T + let invalid_tag = 'I' - let serialize = function - | RelativeProjectRoot path -> - (* show the most common paths as text (for debugging, possibly perf) *) - Sqlite3.Data.TEXT path - | _ as x -> - Serializer.serialize x + let absolute_tag = 'A' + let relative_tag = 'R' - let deserialize = function - | Sqlite3.Data.TEXT rel_path -> - RelativeProjectRoot rel_path - | blob -> - Serializer.deserialize blob + let serialize sourcefile = + let tag_text tag str = Sqlite3.Data.TEXT (Printf.sprintf "%c%s" tag str) in + match sourcefile with + | Invalid {ml_source_file} -> + tag_text invalid_tag ml_source_file + | Absolute abs_path -> + tag_text absolute_tag abs_path + | RelativeProjectRoot rel_path -> + tag_text relative_tag rel_path + + + let deserialize serialized_sourcefile = + let[@warning "-8"] (Sqlite3.Data.TEXT text) = serialized_sourcefile in + if String.is_empty text then + L.die InternalError "Could not deserialize sourcefile with empty representation@." ; + let tag = text.[0] in + let str = String.sub ~pos:1 ~len:(String.length text - 1) text in + if Char.equal tag invalid_tag then Invalid {ml_source_file= str} + else if Char.equal tag absolute_tag then Absolute str + else if Char.equal tag relative_tag then RelativeProjectRoot str + else L.die InternalError "Could not deserialize sourcefile with tag=%c, str= %s@." tag str end diff --git a/infer/src/base/SqliteUtils.ml b/infer/src/base/SqliteUtils.ml index f3bce1aed..bac9a564e 100644 --- a/infer/src/base/SqliteUtils.ml +++ b/infer/src/base/SqliteUtils.ml @@ -101,20 +101,6 @@ module type T = sig type t end -module MarshalledDataForComparison (D : T) = struct - type t = D.t - - let deserialize = function[@warning "-8"] Sqlite3.Data.BLOB b -> Marshal.from_string b 0 - - (* - If the serialized data is used for comparison (e.g. used in WHERE clause), we need to normalize it. - Marshalling is brittle as it depends on sharing. - - For now let's suppose that marshalling with no sharing is normalizing. - *) - let serialize x = Sqlite3.Data.BLOB (Marshal.to_string x [Marshal.No_sharing]) -end - module MarshalledDataNOTForComparison (D : T) = struct type t = D.t diff --git a/infer/src/base/SqliteUtils.mli b/infer/src/base/SqliteUtils.mli index b18ed5e29..74f4782a4 100644 --- a/infer/src/base/SqliteUtils.mli +++ b/infer/src/base/SqliteUtils.mli @@ -69,12 +69,6 @@ module type Data = sig val deserialize : Sqlite3.Data.t -> t end -(** A default implementation of the Data API that encodes every objects as marshalled blobs with no - sharing *) -module MarshalledDataForComparison (D : sig - type t -end) : Data with type t = D.t - (** A default implementation of the Data API that encodes every objects as marshalled blobs *) module MarshalledDataNOTForComparison (D : sig type t