1- (* * Reactive analysis service using cached file processing .
1+ (* * Reactive analysis service using ReactiveFileCollection .
22
33 This module provides incremental analysis that only re-processes
4- files that have changed, caching the processed file_data for
5- unchanged files. *)
6-
7- [@@@ alert " -unsafe" ]
4+ files that have changed, using ReactiveFileCollection for efficient
5+ delta-based updates. *)
86
97type cmt_file_result = {
108 dce_data : DceFileProcessing .file_data option ;
@@ -18,19 +16,11 @@ type all_files_result = {
1816}
1917(* * Result of processing all CMT files *)
2018
21- type cached_file = {
22- path : string ;
23- file_data : DceFileProcessing .file_data option ;
24- exception_data : Exception .file_result option ;
25- }
26- (* * Cached file_data for a single CMT file.
27- We cache the processed result, not just the raw CMT data. *)
28-
29- (* * The file cache - maps CMT paths to processed results *)
30- let file_cache : (string, cached_file) Hashtbl.t = Hashtbl. create 1024
19+ type t = cmt_file_result option ReactiveFileCollection .t
20+ (* * The reactive collection type *)
3121
3222(* * Process cmt_infos into a file result *)
33- let process_cmt_infos ~config ~ cmtFilePath cmt_infos : cmt_file_result option =
23+ let process_cmt_infos ~config cmt_infos : cmt_file_result option =
3424 let excludePath sourceFile =
3525 config.DceConfig. cli.exclude_paths
3626 |> List. exists (fun prefix_ ->
@@ -64,7 +54,7 @@ let process_cmt_infos ~config ~cmtFilePath cmt_infos : cmt_file_result option =
6454 Some
6555 (cmt_infos
6656 |> DceFileProcessing. process_cmt_file ~config ~file: dce_file_context
67- ~cmt FilePath)
57+ ~cmt FilePath: " " )
6858 else None
6959 in
7060 let exception_data =
@@ -77,74 +67,63 @@ let process_cmt_infos ~config ~cmtFilePath cmt_infos : cmt_file_result option =
7767 Some {dce_data; exception_data}
7868 | _ -> None
7969
80- (* * Process a CMT file, using cached result if file unchanged.
81- Returns the cached result if the file hasn't changed since last access. *)
82- let process_cmt_cached ~config cmtFilePath : cmt_file_result option =
83- match CmtCache. read_cmt_if_changed cmtFilePath with
84- | None -> (
85- (* File unchanged - return cached result *)
86- match Hashtbl. find_opt file_cache cmtFilePath with
87- | Some cached ->
88- Some {dce_data = cached.file_data; exception_data = cached.exception_data}
89- | None ->
90- (* First time seeing this file - shouldn't happen, but handle gracefully *)
91- None )
92- | Some cmt_infos ->
93- (* File changed or new - process it *)
94- let result = process_cmt_infos ~config ~cmt FilePath cmt_infos in
95- (* Cache the result *)
96- (match result with
97- | Some r ->
98- Hashtbl. replace file_cache cmtFilePath
99- {
100- path = cmtFilePath;
101- file_data = r.dce_data;
102- exception_data = r.exception_data;
103- }
104- | None -> () );
105- result
70+ (* * Create a new reactive collection *)
71+ let create ~config : t =
72+ ReactiveFileCollection. create ~process: (process_cmt_infos ~config )
10673
107- (* * Process all files incrementally.
108- First run processes all files. Subsequent runs only process changed files. *)
109- let process_files_incremental ~config cmtFilePaths : all_files_result =
74+ (* * Process all files incrementally using ReactiveFileCollection.
75+ First run processes all files. Subsequent runs only process changed files
76+ (detected via CmtCache's file change tracking). *)
77+ let process_files ~(collection : t ) ~config cmtFilePaths : all_files_result =
11078 Timing. time_phase `FileLoading (fun () ->
111- let dce_data_list = ref [] in
112- let exception_results = ref [] in
11379 let processed = ref 0 in
11480 let from_cache = ref 0 in
11581
82+ (* Add/update all files in the collection *)
11683 cmtFilePaths
11784 |> List. iter (fun cmtFilePath ->
118- (* Check if file was in cache *before* processing *)
119- let was_cached = Hashtbl . mem file_cache cmtFilePath in
120- match process_cmt_cached ~config cmtFilePath with
121- | Some {dce_data; exception_data} ->
122- ( match dce_data with
123- | Some data -> dce_data_list := data :: ! dce_data_list
124- | None -> () );
125- ( match exception_data with
126- | Some data -> exception_results := data :: ! exception_results
127- | None -> () );
128- (* Track whether it was from cache *)
129- if was_cached then incr from_cache else incr processed
130- | None -> () );
85+ let was_in_collection =
86+ ReactiveFileCollection . mem collection cmtFilePath
87+ in
88+ (* Check if file changed using CmtCache *)
89+ match CmtCache. read_cmt_if_changed cmtFilePath with
90+ | None ->
91+ (* File unchanged - already in collection *)
92+ if was_in_collection then incr from_cache
93+ | Some cmt_infos ->
94+ (* File changed or new - process and update *)
95+ let result = process_cmt_infos ~config cmt_infos in
96+ ReactiveFileCollection. set collection cmtFilePath result;
97+ incr processed );
13198
13299 if ! Cli. timing then
133100 Printf. eprintf " Reactive: %d files processed, %d from cache\n %!"
134101 ! processed ! from_cache;
135102
103+ (* Collect results from the collection *)
104+ let dce_data_list = ref [] in
105+ let exception_results = ref [] in
106+
107+ ReactiveFileCollection. iter
108+ (fun _path result_opt ->
109+ match result_opt with
110+ | Some {dce_data; exception_data} -> (
111+ (match dce_data with
112+ | Some data -> dce_data_list := data :: ! dce_data_list
113+ | None -> () );
114+ match exception_data with
115+ | Some data -> exception_results := data :: ! exception_results
116+ | None -> () )
117+ | None -> () )
118+ collection;
119+
136120 {
137121 dce_data_list = List. rev ! dce_data_list;
138122 exception_results = List. rev ! exception_results;
139123 })
140124
141- (* * Clear all cached file data *)
142- let clear () =
143- Hashtbl. clear file_cache;
144- CmtCache. clear ()
145-
146- (* * Get cache statistics *)
147- let stats () =
148- let file_count = Hashtbl. length file_cache in
125+ (* * Get collection statistics *)
126+ let stats (collection : t ) =
127+ let file_count = ReactiveFileCollection. length collection in
149128 let cmt_stats = CmtCache. stats () in
150129 (file_count, cmt_stats)
0 commit comments