Skip to content

Commit e4c281e

Browse files
authored
Merge pull request #195 from oxcaml/index-lazily
Index lazily
2 parents d1cb27e + 6e7fc02 commit e4c281e

File tree

4 files changed

+81
-72
lines changed

4 files changed

+81
-72
lines changed

src/analysis/index_occurrences.ml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ let should_ignore_lid (lid : Longident.t Location.loc) =
4444
*)
4545
Location.is_none lid.loc
4646

47-
let iterator ~current_buffer_path ~index ~stamp ~reduce_for_uid =
48-
let add uid loc = Stamped_hashtable.add index ~stamp (uid, loc) () in
47+
let iterator ~current_buffer_path ~index ~reduce_for_uid =
48+
let add uid loc = index := Shape.Uid.Map.add_to_list uid loc !index in
4949
let f ~namespace env path (lid : Longident.t Location.loc) =
5050
log ~title:"index_buffer" "Path: %a" Logger.fmt (Fun.flip Path.print path);
5151
let lid = { lid with loc = set_fname ~file:current_buffer_path lid.loc } in
@@ -89,7 +89,7 @@ let iterator ~current_buffer_path ~index ~stamp ~reduce_for_uid =
8989
in
9090
Ast_iterators.iterator_on_usages ~include_hidden:true ~f
9191

92-
let items ~index ~stamp (config : Mconfig.t) items =
92+
let items index (config : Mconfig.t) items =
9393
let module Shape_reduce = Shape_reduce.Make (struct
9494
let fuel () = Misc_stdlib.Maybe_bounded.of_int 10
9595

@@ -123,7 +123,11 @@ let items ~index ~stamp (config : Mconfig.t) items =
123123
Filename.concat config.query.directory config.query.filename
124124
in
125125
let reduce_for_uid = Shape_reduce.reduce_for_uid in
126-
let iterator = iterator ~current_buffer_path ~index ~stamp ~reduce_for_uid in
127-
match items with
128-
| `Impl items -> List.iter ~f:(iterator.structure_item iterator) items
129-
| `Intf items -> List.iter ~f:(iterator.signature_item iterator) items
126+
let index = ref index in
127+
let iterator = iterator ~current_buffer_path ~index ~reduce_for_uid in
128+
let () =
129+
match items with
130+
| `Impl items -> List.iter ~f:(iterator.structure_item iterator) items
131+
| `Intf items -> List.iter ~f:(iterator.signature_item iterator) items
132+
in
133+
!index

src/analysis/occurrences.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,11 @@ end = struct
186186
end
187187

188188
let get_buffer_locs result uid =
189-
Stamped_hashtable.fold
190-
(fun (uid', loc) () acc ->
189+
Shape.Uid.Map.fold
190+
(fun uid' lids acc ->
191191
if Shape.Uid.equal uid uid' then
192-
Lid_set.add (Index_format.Lid.of_lid loc) acc
192+
List.fold_left lids ~init:acc ~f:(fun acc lid ->
193+
Lid_set.add (Index_format.Lid.of_lid lid) acc)
193194
else acc)
194195
(Mtyper.get_index result) Lid_set.empty
195196

src/kernel/mtyper.ml

Lines changed: 62 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,17 @@ open Local_store
33

44
let { Logger.log } = Logger.for_section "Mtyper"
55

6-
let index_changelog = Local_store.s_table Stamped_hashtable.create_changelog ()
7-
8-
type index_tbl =
9-
(Shape.Uid.t * Longident.t Location.loc, unit) Stamped_hashtable.t
6+
type index = Longident.t Location.loc list Shape.Uid.Map.t
107

118
(* Forward ref to be filled by analysis.Occurrences *)
129
let index_items :
13-
(index:index_tbl ->
14-
stamp:int ->
10+
(index ->
1511
Mconfig.t ->
1612
[ `Impl of Typedtree.structure_item list
1713
| `Intf of Typedtree.signature_item list ] ->
18-
unit)
14+
index)
1915
ref =
20-
ref (fun ~index:_ ~stamp:_ _config _item -> ())
16+
ref (fun acc _config _item -> acc)
2117
let set_index_items f = index_items := f
2218

2319
type ('p, 't) item =
@@ -30,7 +26,8 @@ type ('p, 't) item =
3026
part_rev_sg : Types.signature_item list;
3127
part_errors : exn list;
3228
part_checks : Typecore.delayed_check list;
33-
part_warnings : Warnings.state
29+
part_warnings : Warnings.state;
30+
part_index : index lazy_t
3431
}
3532

3633
type typedtree =
@@ -53,8 +50,7 @@ type 'a cache_result =
5350
snapshot : Types.snapshot;
5451
ident_stamp : int;
5552
uid_stamp : int;
56-
value : 'a;
57-
index : (Shape.Uid.t * Longident.t Location.loc, unit) Stamped_hashtable.t
53+
value : 'a
5854
}
5955

6056
let cache : typedtree_items option cache_result option ref = s_ref None
@@ -72,8 +68,7 @@ let get_cache config =
7268
| Some ({ snapshot; _ } as c) when Types.is_valid snapshot -> c
7369
| Some _ | None ->
7470
let env, snapshot, ident_stamp, uid_stamp = fresh_env config in
75-
let index = Stamped_hashtable.create !index_changelog 256 in
76-
{ env; snapshot; ident_stamp; uid_stamp; value = None; index }
71+
{ env; snapshot; ident_stamp; uid_stamp; value = None }
7772

7873
let return_and_cache status =
7974
cache := Some { status with value = Some status.value };
@@ -87,7 +82,6 @@ type result =
8782
stamp : int;
8883
initial_uid_stamp : int;
8984
typedtree : typedtree_items;
90-
index : (Shape.Uid.t * Longident.t Location.loc, unit) Stamped_hashtable.t;
9185
cache_stat : typer_cache_stats
9286
}
9387

@@ -111,11 +105,14 @@ let compatible_prefix_rev result_items tree_items =
111105
in
112106
aux [] (result_items, tree_items)
113107

114-
let[@tail_mod_cons] rec type_structure caught env sg = function
108+
let[@tail_mod_cons] rec type_structure config caught env index sg = function
115109
| parsetree_item :: rest ->
116110
let items, sg', part_env =
117111
Typemod.merlin_type_structure env sg [ parsetree_item ]
118112
in
113+
let part_index =
114+
lazy (!index_items (Lazy.force index) config (`Impl items.str_items))
115+
in
119116
let typedtree_items =
120117
(items.Typedtree.str_items, items.Typedtree.str_type)
121118
in
@@ -130,14 +127,15 @@ let[@tail_mod_cons] rec type_structure caught env sg = function
130127
part_uid = Shape.Uid.get_current_stamp ();
131128
part_errors = !caught;
132129
part_checks = !Typecore.delayed_checks;
133-
part_warnings = Warnings.backup ()
130+
part_warnings = Warnings.backup ();
131+
part_index
134132
}
135133
in
136-
item :: type_structure caught part_env part_rev_sg rest
134+
item :: type_structure config caught part_env part_index part_rev_sg rest
137135
| [] -> []
138136

139-
let[@tail_mod_cons] rec type_signature caught env sg psg_modalities psg_loc =
140-
function
137+
let[@tail_mod_cons] rec type_signature config caught env index sg psg_modalities
138+
psg_loc = function
141139
| parsetree_item :: rest ->
142140
let { Typedtree.sig_final_env = part_env;
143141
sig_items;
@@ -150,6 +148,9 @@ let[@tail_mod_cons] rec type_signature caught env sg psg_modalities psg_loc =
150148
[ parsetree_item ])
151149
in
152150
let part_rev_sg = List.rev_append sig_type sg in
151+
let part_index =
152+
lazy (!index_items (Lazy.force index) config (`Intf sig_items))
153+
in
153154
let item =
154155
{ parsetree_item;
155156
typedtree_items = (sig_items, sig_type);
@@ -160,26 +161,34 @@ let[@tail_mod_cons] rec type_signature caught env sg psg_modalities psg_loc =
160161
part_uid = Shape.Uid.get_current_stamp ();
161162
part_errors = !caught;
162163
part_checks = !Typecore.delayed_checks;
163-
part_warnings = Warnings.backup ()
164+
part_warnings = Warnings.backup ();
165+
part_index
164166
}
165167
in
166168
item
167-
:: type_signature caught part_env part_rev_sg psg_modalities psg_loc rest
169+
:: type_signature config caught part_env part_index part_rev_sg
170+
psg_modalities psg_loc rest
168171
| [] -> []
169172

170173
let type_implementation config caught parsetree =
171-
let { env; snapshot; ident_stamp; uid_stamp; value = cached_value; index; _ }
172-
=
174+
let { env; snapshot; ident_stamp; uid_stamp; value = cached_value; _ } =
173175
get_cache config
174176
in
175177
let rev_prefix, parsetree_suffix, cache_stats =
176178
match cached_value with
177179
| Some (Implementation_items items) -> compatible_prefix_rev items parsetree
178180
| Some (Interface_items _) | None -> ([], parsetree, Miss)
179181
in
180-
let env', sg', snap', stamp', uid_stamp', warn' =
182+
let env', sg', snap', stamp', uid_stamp', warn', index' =
181183
match rev_prefix with
182-
| [] -> (env, [], snapshot, ident_stamp, uid_stamp, Warnings.backup ())
184+
| [] ->
185+
( env,
186+
[],
187+
snapshot,
188+
ident_stamp,
189+
uid_stamp,
190+
Warnings.backup (),
191+
lazy Shape.Uid.Map.empty )
183192
| x :: _ ->
184193
caught := x.part_errors;
185194
Typecore.delayed_checks := x.part_checks;
@@ -188,30 +197,21 @@ let type_implementation config caught parsetree =
188197
x.part_snapshot,
189198
x.part_stamp,
190199
x.part_uid,
191-
x.part_warnings )
200+
x.part_warnings,
201+
x.part_index )
192202
in
193203
Btype.backtrack snap';
194204
Warnings.restore warn';
195205
Env.cleanup_functor_caches ~stamp:stamp';
196-
let stamp = List.length rev_prefix - 1 in
197-
Stamped_hashtable.backtrack !index_changelog ~stamp;
198206
Env.cleanup_usage_tables ~stamp:uid_stamp';
199207
Shape.Uid.restore_stamp uid_stamp';
200-
let suffix = type_structure caught env' sg' parsetree_suffix in
201-
let () =
202-
List.iteri
203-
~f:(fun i { typedtree_items = items, _; _ } ->
204-
let stamp = stamp + i + 1 in
205-
!index_items ~index ~stamp config (`Impl items))
206-
suffix
207-
in
208+
let suffix = type_structure config caught env' index' sg' parsetree_suffix in
208209
let value = Implementation_items (List.rev_append rev_prefix suffix) in
209-
( return_and_cache { env; snapshot; ident_stamp; uid_stamp; value; index },
210+
( return_and_cache { env; snapshot; ident_stamp; uid_stamp; value },
210211
cache_stats )
211212

212213
let type_interface config caught (parsetree : Parsetree.signature) =
213-
let { env; snapshot; ident_stamp; uid_stamp; value = cached_value; index; _ }
214-
=
214+
let { env; snapshot; ident_stamp; uid_stamp; value = cached_value; _ } =
215215
get_cache config
216216
in
217217
let rev_prefix, parsetree_suffix, cache_stats =
@@ -230,9 +230,16 @@ let type_interface config caught (parsetree : Parsetree.signature) =
230230
| Some (Interface_items _) | Some (Implementation_items _) | None ->
231231
([], parsetree.psg_items, Miss)
232232
in
233-
let env', sg', snap', stamp', uid_stamp', warn' =
233+
let env', sg', snap', stamp', uid_stamp', warn', index' =
234234
match rev_prefix with
235-
| [] -> (env, [], snapshot, ident_stamp, uid_stamp, Warnings.backup ())
235+
| [] ->
236+
( env,
237+
[],
238+
snapshot,
239+
ident_stamp,
240+
uid_stamp,
241+
Warnings.backup (),
242+
lazy Shape.Uid.Map.empty )
236243
| x :: _ ->
237244
caught := x.part_errors;
238245
Typecore.delayed_checks := x.part_checks;
@@ -241,25 +248,17 @@ let type_interface config caught (parsetree : Parsetree.signature) =
241248
x.part_snapshot,
242249
x.part_stamp,
243250
x.part_uid,
244-
x.part_warnings )
251+
x.part_warnings,
252+
x.part_index )
245253
in
246254
Btype.backtrack snap';
247255
Warnings.restore warn';
248256
Env.cleanup_functor_caches ~stamp:stamp';
249-
let stamp = List.length rev_prefix in
250-
Stamped_hashtable.backtrack !index_changelog ~stamp;
251257
Env.cleanup_usage_tables ~stamp:uid_stamp';
252258
Shape.Uid.restore_stamp uid_stamp';
253259
let suffix =
254-
type_signature caught env' sg' parsetree.psg_modalities parsetree.psg_loc
255-
parsetree_suffix
256-
in
257-
let () =
258-
List.iteri
259-
~f:(fun i { typedtree_items = items, _; _ } ->
260-
let stamp = stamp + i + 1 in
261-
!index_items ~index ~stamp config (`Intf items))
262-
suffix
260+
type_signature config caught env' index' sg' parsetree.psg_modalities
261+
parsetree.psg_loc parsetree_suffix
263262
in
264263
(* transl an empty signature to get the sig_modalities and sig_sloc *)
265264
let ({ sig_final_env = _;
@@ -281,7 +280,7 @@ let type_interface config caught (parsetree : Parsetree.signature) =
281280
sig_sloc
282281
}
283282
in
284-
( return_and_cache { env; snapshot; ident_stamp; uid_stamp; value; index },
283+
( return_and_cache { env; snapshot; ident_stamp; uid_stamp; value },
285284
cache_stats )
286285

287286
let run config parsetree =
@@ -313,7 +312,6 @@ let run config parsetree =
313312
stamp;
314313
initial_uid_stamp = cached_result.uid_stamp;
315314
typedtree = cached_result.value;
316-
index = cached_result.index;
317315
cache_stat
318316
}
319317

@@ -362,7 +360,15 @@ let get_typedtree t =
362360
sig_sloc
363361
}
364362

365-
let get_index t = t.index
363+
let get_index t =
364+
let of_items items =
365+
List.last items
366+
|> Option.value_map ~default:Shape.Uid.Map.empty
367+
~f:(fun { part_index; _ } -> Lazy.force part_index)
368+
in
369+
match t.typedtree with
370+
| Implementation_items items -> of_items items
371+
| Interface_items { items; _ } -> of_items items
366372

367373
let get_stamp t = t.stamp
368374

src/kernel/mtyper.mli

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,14 @@ type typedtree =
1414

1515
type typer_cache_stats = Miss | Hit of { reused : int; typed : int }
1616

17-
type index_tbl =
18-
(Shape.Uid.t * Longident.t Location.loc, unit) Stamped_hashtable.t
17+
type index = Longident.t Location.loc list Shape.Uid.Map.t
1918

2019
val set_index_items :
21-
(index:index_tbl ->
22-
stamp:int ->
20+
(index ->
2321
Mconfig.t ->
2422
[ `Impl of Typedtree.structure_item list
2523
| `Intf of Typedtree.signature_item list ] ->
26-
unit) ->
24+
index) ->
2725
unit
2826

2927
val run : Mconfig.t -> Mreader.parsetree -> result
@@ -32,7 +30,7 @@ val get_env : ?pos:Msource.position -> result -> Env.t
3230

3331
val get_typedtree : result -> typedtree
3432

35-
val get_index : result -> index_tbl
33+
val get_index : result -> index
3634

3735
val get_stamp : result -> int
3836

0 commit comments

Comments
 (0)