-
Notifications
You must be signed in to change notification settings - Fork 88
Store all incremental data into single file #748
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
a7a1d02
3878b40
472c8ef
340f63c
9a3e7a8
31a6542
3f872f3
a9dff9a
5b00f11
140fec6
c3962dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,7 @@ | ||
| open Prelude | ||
|
|
||
| (* TODO: GoblintDir *) | ||
| let version_map_filename = "version.data" | ||
| let cil_file_name = "ast.data" | ||
| let solver_data_file_name = "solver.data" | ||
| let analysis_data_file_name = "analysis.data" | ||
| let incremental_data_file_name = "analysis.data" | ||
| let results_dir = "results" | ||
| let results_tmp_dir = "results_tmp" | ||
jerhard marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
@@ -43,49 +40,78 @@ let results_exist () = | |
| let r_str = Fpath.to_string r in | ||
| Sys.file_exists r_str && Sys.is_directory r_str | ||
|
|
||
| (* Convenience enumeration of the different data types we store for incremental analysis, so file-name logic is concentrated in one place *) | ||
| type incremental_data_kind = SolverData | CilFile | VersionData | AnalysisData | ||
|
|
||
| let type_to_file_name = function | ||
| | SolverData -> solver_data_file_name | ||
| | CilFile -> cil_file_name | ||
| | VersionData -> version_map_filename | ||
| | AnalysisData -> analysis_data_file_name | ||
|
|
||
| (** Used by the server mode to avoid serializing the solver state to the filesystem *) | ||
| let server_solver_data : Obj.t option ref = ref None | ||
| let server_analysis_data : Obj.t option ref = ref None | ||
|
|
||
| (** Loads data for incremental runs from the appropriate file *) | ||
| let load_data (data_type: incremental_data_kind) = | ||
| if server () then | ||
| match data_type with | ||
| | SolverData -> !server_solver_data |> Option.get |> Obj.obj | ||
| | AnalysisData -> !server_analysis_data |> Option.get |> Obj.obj | ||
| | _ -> failwith "Can only load solver and analysis data" | ||
| else | ||
| let p = Fpath.(gob_results_dir Load / type_to_file_name data_type) in | ||
| unmarshal p | ||
|
|
||
| (** Stores data for future incremental runs at the appropriate file, given the data and what kind of data it is. *) | ||
| let store_data (data : 'a) (data_type : incremental_data_kind) = | ||
| if server () then | ||
| match data_type with | ||
| | SolverData -> server_solver_data := Some (Obj.repr data) | ||
| | AnalysisData -> server_analysis_data := Some (Obj.repr data) | ||
| | _ -> () | ||
| else ( | ||
| (** Module to cache the data for incremental analaysis during a run, before it is stored to disk, as well as the server mode *) | ||
| module Cache = struct | ||
| type t = { | ||
| solver_data: Obj.t option ref; | ||
| analysis_data: Obj.t option ref; | ||
| version_data: MaxIdUtil.max_ids option ref; | ||
| cil_file: Cil.file option ref; | ||
|
||
| } | ||
|
|
||
| let data = ref { | ||
| solver_data = ref None ; | ||
| analysis_data = ref None ; | ||
| version_data = ref None ; | ||
| cil_file = ref None ; | ||
| } | ||
|
|
||
| (* GADT that may be used to query data from the cache *) | ||
| type _ data_query = | ||
| | SolverDataRequest : Obj.t data_query | ||
| | CilFileRequest : Cil.file data_query | ||
| | VersionDataRequest : MaxIdUtil.max_ids data_query | ||
| | AnalysisDataRequest : Obj.t data_query | ||
|
|
||
| (* Data type to pass incremental data into the cache *) | ||
| type incremental_data = | ||
| | SolverData of Obj.t | ||
| | CilFile of Cil.file | ||
| | VersionData of MaxIdUtil.max_ids | ||
| | AnalysisData of Obj.t | ||
jerhard marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| (** Loads data for incremental runs from the appropriate file *) | ||
| let load_data () = | ||
| let p = Fpath.(gob_results_dir Load / incremental_data_file_name) in | ||
| let loaded_data = unmarshal p in | ||
| data := loaded_data | ||
|
|
||
| (** Stores data for future incremental runs at the appropriate file. *) | ||
| let store_data () = | ||
| GobSys.mkdir_or_exists (gob_directory Save); | ||
| let d = gob_results_tmp_dir Save in | ||
| let d = gob_results_dir Save in | ||
| GobSys.mkdir_or_exists d; | ||
| let p = Fpath.(d / type_to_file_name data_type) in | ||
| marshal data p) | ||
|
|
||
| (** Deletes previous analysis results and moves the freshly created results there.*) | ||
| let move_tmp_results_to_results () = | ||
| let op = Save in | ||
| if not (server ()) then ( | ||
| if Sys.file_exists (Fpath.to_string (gob_results_dir op)) then begin | ||
| Goblintutil.rm_rf (gob_results_dir op); | ||
| end; | ||
| Sys.rename (Fpath.to_string (gob_results_tmp_dir op)) (Fpath.to_string (gob_results_dir op))) | ||
| let p = Fpath.(d / incremental_data_file_name) in | ||
| marshal !data p | ||
|
|
||
| (** Update the some incremental data in the in-memory cache *) | ||
| let update_data (d : incremental_data) = match d with | ||
| | SolverData s -> !data.solver_data := Some s | ||
| | AnalysisData a -> !data.analysis_data := Some a | ||
| | VersionData v -> !data.version_data := Some v | ||
| | CilFile c -> !data.cil_file := Some c | ||
|
|
||
| (** Reset some incremental data in the in-memory cache to [None]*) | ||
| let reset_data : type a. a data_query -> unit = function | ||
| | SolverDataRequest -> !data.solver_data := None | ||
| | AnalysisDataRequest -> !data.analysis_data := None | ||
| | VersionDataRequest -> !data.version_data := None | ||
| | CilFileRequest -> !data.cil_file := None | ||
|
|
||
| (** Get incremental data from the in-memory cache wrapped in an optional. | ||
| To populate the in-memory cache with data, call [load_data] first. *) | ||
| let get_opt_data : type a. a data_query -> a option = function | ||
| | SolverDataRequest -> !(!data.solver_data) | ||
| | AnalysisDataRequest -> !(!data.analysis_data) | ||
| | VersionDataRequest -> !(!data.version_data) | ||
| | CilFileRequest -> !(!data.cil_file) | ||
|
|
||
| (** Get incremental data from the in-memory cache. | ||
| Same as [get_opt_data], except not yielding an optional and failing when the requested data is not present. | ||
| To populate the in-memory cache with data, call [load_data] first. *) | ||
| let get_data : type a. a data_query -> a = | ||
| fun a -> | ||
| match get_opt_data a with | ||
| | Some d -> d | ||
| | None -> failwith "Requested data is not loaded." | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.