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