Skip to content

Commit 93549e9

Browse files
committed
Remove most backtracking from lockdir parser
To parse both portable and non-portable lockdirs with mostly the same code, the parser would attempt to parse fields with the non-portable lockdir syntax and fall back to the portable syntax should parsing fail. This led to the generation of parse errors when the first attempt at parsing a field would fail, and even though these errors are discarded, generating them took a noticeable amount of time. This changes the parsing logic to only attempt to parse fields in a single syntax, determined by the presence of the `solved_for_platforms` field in the lockdir metadata file. This field is present precisely when a lockdir is portable. Signed-off-by: Stephen Sherratt <[email protected]>
1 parent 0e2194e commit 93549e9

File tree

2 files changed

+41
-38
lines changed

2 files changed

+41
-38
lines changed

src/dune_pkg/lock_dir.ml

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -375,13 +375,15 @@ module Build_command = struct
375375
]
376376
;;
377377

378-
let decode_fields_backwards_compatible =
378+
let decode_fields ~portable_lock_dir =
379379
let open Decoder in
380380
let parse_action =
381-
(let+ action = Action.decode_pkg in
382-
Conditional_choice_or_all_platforms.Choice
383-
(Conditional_choice.singleton_all_platforms (Action action)))
384-
<|> Conditional_choice_or_all_platforms.decode decode_portable
381+
if portable_lock_dir
382+
then Conditional_choice_or_all_platforms.decode decode_portable
383+
else
384+
let+ action = Action.decode_pkg in
385+
Conditional_choice_or_all_platforms.Choice
386+
(Conditional_choice.singleton_all_platforms (Action action))
385387
in
386388
fields_mutually_exclusive
387389
~default:None
@@ -617,38 +619,40 @@ module Pkg = struct
617619
let enabled_on_platforms = "enabled_on_platforms"
618620
end
619621

620-
let decode =
622+
let decode ~portable_lock_dir =
621623
let open Decoder in
622-
let parse_install_command_backwards_compatible =
623-
(let+ action = Action.decode_pkg in
624-
Conditional_choice_or_all_platforms.Choice
625-
(Conditional_choice.singleton_all_platforms action))
626-
<|> Conditional_choice_or_all_platforms.decode Action.decode_pkg
624+
let parse_install_command =
625+
if portable_lock_dir
626+
then Conditional_choice_or_all_platforms.decode Action.decode_pkg
627+
else
628+
let+ action = Action.decode_pkg in
629+
Conditional_choice_or_all_platforms.Choice
630+
(Conditional_choice.singleton_all_platforms action)
627631
in
628-
let parse_depends_backwards_compatible =
629-
(let+ depends = repeat Dependency.decode in
630-
Conditional_choice_or_all_platforms.Choice
631-
(Conditional_choice.singleton_all_platforms depends))
632-
<|> Conditional_choice_or_all_platforms.decode (enter @@ repeat Dependency.decode)
632+
let parse_depends =
633+
if portable_lock_dir
634+
then Conditional_choice_or_all_platforms.decode (enter @@ repeat Dependency.decode)
635+
else
636+
let+ depends = repeat Dependency.decode in
637+
Conditional_choice_or_all_platforms.Choice
638+
(Conditional_choice.singleton_all_platforms depends)
633639
in
634-
let parse_depexts_backwards_compatible =
635-
(let+ external_package_names = repeat string in
636-
[ { Depexts.external_package_names; enabled_if = `Always } ])
637-
<|> repeat Depexts.decode
640+
let parse_depexts =
641+
if portable_lock_dir
642+
then repeat Depexts.decode
643+
else
644+
let+ external_package_names = repeat string in
645+
[ { Depexts.external_package_names; enabled_if = `Always } ]
638646
in
639647
let empty_choice = Conditional_choice_or_all_platforms.Choice [] in
640648
enter
641649
@@ fields
642650
@@ let+ version = field Fields.version Package_version.decode
643651
and+ install_command =
644-
field
645-
~default:empty_choice
646-
Fields.install
647-
parse_install_command_backwards_compatible
648-
and+ build_command = Build_command.decode_fields_backwards_compatible
649-
and+ depends =
650-
field ~default:empty_choice Fields.depends parse_depends_backwards_compatible
651-
and+ depexts = field ~default:[] Fields.depexts parse_depexts_backwards_compatible
652+
field ~default:empty_choice Fields.install parse_install_command
653+
and+ build_command = Build_command.decode_fields ~portable_lock_dir
654+
and+ depends = field ~default:empty_choice Fields.depends parse_depends
655+
and+ depexts = field ~default:[] Fields.depexts parse_depexts
652656
and+ source = field_o Fields.source Source.decode
653657
and+ dev = field_b Fields.dev
654658
and+ avoid = field_b Fields.avoid
@@ -1198,10 +1202,7 @@ let decode_metadata =
11981202
~default:Solver_stats.Expanded_variable_bindings.empty
11991203
Solver_stats.Expanded_variable_bindings.decode
12001204
and+ solved_for_platforms =
1201-
field
1202-
"solved_for_platforms"
1203-
~default:(Loc.none, [])
1204-
(located (repeat (enter Solver_env.decode)))
1205+
field_o "solved_for_platforms" (located (repeat (enter Solver_env.decode)))
12051206
in
12061207
( ocaml
12071208
, dependency_hash
@@ -1464,6 +1465,7 @@ struct
14641465
;;
14651466

14661467
let load_pkg
1468+
~portable_lock_dir
14671469
~version
14681470
~lock_dir_path
14691471
~solved_for_platforms
@@ -1482,7 +1484,7 @@ struct
14821484
let parser =
14831485
let env = Pform.Env.pkg Dune_lang.Pkg.syntax version in
14841486
let decode =
1485-
Syntax.set Dune_lang.Pkg.syntax (Active version) Pkg.decode
1487+
Syntax.set Dune_lang.Pkg.syntax (Active version) (Pkg.decode ~portable_lock_dir)
14861488
|> Syntax.set Dune_lang.Stanza.syntax (Active Dune_lang.Stanza.latest_version)
14871489
in
14881490
String_with_vars.set_decoding_env env decode
@@ -1572,6 +1574,11 @@ struct
15721574
=
15731575
load_metadata (Path.relative lock_dir_path metadata_filename)
15741576
in
1577+
let portable_lock_dir, solved_for_platforms =
1578+
match solved_for_platforms with
1579+
| Some x -> true, x
1580+
| None -> false, (Loc.none, [])
1581+
in
15751582
let+ packages =
15761583
Io.readdir_with_kinds lock_dir_path
15771584
>>| List.filter_map ~f:(fun (name, (kind : Unix.file_kind)) ->
@@ -1584,6 +1591,7 @@ struct
15841591
let _loc, solved_for_platforms = solved_for_platforms in
15851592
let+ pkg =
15861593
load_pkg
1594+
~portable_lock_dir
15871595
~version
15881596
~lock_dir_path
15891597
~solved_for_platforms

src/dune_pkg/lock_dir.mli

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,6 @@ module Pkg : sig
6868
val equal : t -> t -> bool
6969
val hash : t -> int
7070
val to_dyn : t -> Dyn.t
71-
72-
val decode
73-
: (lock_dir:Path.t -> solved_for_platforms:Solver_env.t list -> Package_name.t -> t)
74-
Decoder.t
75-
7671
val files_dir : Package_name.t -> Package_version.t option -> lock_dir:Path.t -> Path.t
7772
end
7873

0 commit comments

Comments
 (0)