Skip to content

Commit

Permalink
Use exceptions to break loop fast and avoid extra allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
andersfugmann committed Jan 31, 2024
1 parent c095f3a commit e03895f
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions src/ocaml_protoc_plugin/deserialize.ml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ let deserialize_full: type constr a. extension_ranges -> (constr, a) value_list

let deserialize: type constr a. (constr, a) compound_list -> constr -> Reader.t -> a = fun spec constr ->

(* Exception indicating that fast deserialization did not succeed and revert to full deserialization *)
let exception Restart_full in

let rec extension_ranges: type a b. (a, b) compound_list -> extension_ranges = function
| Nil -> []
| Nil_ext extension_ranges -> extension_ranges
Expand Down Expand Up @@ -269,9 +272,9 @@ let deserialize: type constr a. (constr, a) compound_list -> constr -> Reader.t
in
function
| VNil when idx = Int.max_int ->
Some constr
constr
| VNil_ext when idx = Int.max_int ->
Some (constr (List.rev extensions))
constr (List.rev extensions)
(* All fields read successfully. Apply extensions and return result. *)
| VCons (([index, read_f], _required, default, get), vs) when index = idx ->
(* Read all values, and apply constructor once all fields have been read.
Expand All @@ -295,7 +298,7 @@ let deserialize: type constr a. (constr, a) compound_list -> constr -> Reader.t
If all values are read, then raise, else revert to full deserialization *)
begin match (idx = Int.max_int) with
| true -> error_required_field_missing ()
| false -> None
| false -> raise Restart_full
end
| VCons ((_ :: fields, optional, default, get), vs) ->
(* Drop the field, as we dont expect to find it. *)
Expand All @@ -307,7 +310,7 @@ let deserialize: type constr a. (constr, a) compound_list -> constr -> Reader.t
(* This implies that there are still fields to be read.
Revert to full deserialization.
*)
None
raise Restart_full
in

let extension_ranges = extension_ranges spec in
Expand All @@ -316,9 +319,8 @@ let deserialize: type constr a. (constr, a) compound_list -> constr -> Reader.t
fun reader ->
let offset = Reader.offset reader in
let (tpe, idx) = next_field reader in
read_values extension_ranges tpe idx reader constr [] values
|> function
| Some t -> t
| None ->
try
read_values extension_ranges tpe idx reader constr [] values
with Restart_full ->
Reader.reset reader offset;
deserialize_full extension_ranges values constr reader

0 comments on commit e03895f

Please sign in to comment.