From 429a7567fd183c018307c2a1ca2bd3ec0aa56853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C5=A1a=20Juri=C4=87?= Date: Sun, 10 Jul 2022 18:58:44 +0200 Subject: [PATCH 1/2] Support maps for definitions Passing indexed definitions improves the performance of the encoder. --- src/gpb.erl | 17 ++++++++++++----- src/gpb_defs.erl | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/gpb.erl b/src/gpb.erl index bab9591c..94a77763 100644 --- a/src/gpb.erl +++ b/src/gpb.erl @@ -1898,12 +1898,19 @@ fetch_field_by_name(Name, Fields) -> -endif. % -ifndef(NO_HAVE_MAPS). -keyfetch(Key, KVPairs) -> +keyfetch(Key, MsgDefs) -> + case keyfetch_2(Key, MsgDefs) of + undefined -> erlang:error({error, {no_such_key, Key, MsgDefs}}); + Value -> Value + end. + +keyfetch_2(Key, MsgDefs) when is_map(MsgDefs) -> + maps:get(Key, MsgDefs, undefined); + +keyfetch_2(Key, KVPairs) when is_list(KVPairs) -> case lists:keysearch(Key, 1, KVPairs) of - {value, {Key, Value}} -> - Value; - false -> - erlang:error({error, {no_such_key, Key, KVPairs}}) + {value, {Key, Value}} -> Value; + false -> undefined end. is_field_for_unknowns(#?gpb_field{type=unknown, occurrence=repeated}) -> diff --git a/src/gpb_defs.erl b/src/gpb_defs.erl index 7db17654..7d20b7f3 100644 --- a/src/gpb_defs.erl +++ b/src/gpb_defs.erl @@ -46,7 +46,7 @@ -define(is_non_empty_string(Str), (is_list(Str) andalso is_integer(hd(Str)))). --type defs() :: [def()]. +-type defs() :: [def()] | map(). -type def() :: {proto_defs_version, version()} | {{msg, Name::atom()}, [field()]} | {{group, Name::atom()}, [field()]} | From 85ae936e41f9ce174c4cd378c255463344d12f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C5=A1a=20Juri=C4=87?= Date: Tue, 12 Jul 2022 12:12:02 +0200 Subject: [PATCH 2/2] Adapt decoder MsgDefs lookups --- src/gpb.erl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gpb.erl b/src/gpb.erl index 94a77763..a47c2447 100644 --- a/src/gpb.erl +++ b/src/gpb.erl @@ -493,7 +493,7 @@ decode_type(FieldType, Bin, MsgDefs) -> {N =/= 0, Rest}; {enum, _EnumName}=Key -> {N, Rest} = decode_type(int32, Bin, MsgDefs), - {value, {Key, EnumValues}} = lists:keysearch(Key, 1, MsgDefs), + EnumValues = keyfetch(Key, MsgDefs), case lists:keyfind(N, 2, EnumValues) of {EnumName, N, _} -> {EnumName, Rest}; % proto_defs_version 3 {EnumName, N} -> {EnumName, Rest}; % proto_defs_version 2 @@ -1221,11 +1221,11 @@ encode_zigzag(N) when N < 0 -> N * -2 - 1. -spec verify_msg(tuple() | term(), gpb_defs:defs()) -> ok. verify_msg(Msg, MsgDefs) when is_tuple(Msg), tuple_size(Msg) >= 1 -> MsgName = element(1, Msg), - case lists:keysearch({msg,MsgName}, 1, MsgDefs) of - {value, _} -> - verify_msg2(Msg, MsgName, MsgDefs, [top_level]); - false -> - mk_type_error(not_a_known_message, MsgName, [top_level]) + case keyfetch_2({msg,MsgName}, MsgDefs) of + undefined -> + mk_type_error(not_a_known_message, MsgName, [top_level]); + _ -> + verify_msg2(Msg, MsgName, MsgDefs, [top_level]) end; verify_msg(Msg, _MsgDefs) -> mk_type_error(expected_a_message, Msg, []). @@ -1234,7 +1234,7 @@ verify_msg(Msg, _MsgDefs) -> verify_msg2(Msg, MsgName, MsgDefs, Path) when is_tuple(Msg), element(1, Msg) == MsgName -> MsgKey = {msg, MsgName}, - {value, {MsgKey, Fields}} = lists:keysearch(MsgKey, 1, MsgDefs), + Fields = keyfetch_2(MsgKey, MsgDefs), if tuple_size(Msg) == length(Fields) + 1 -> Path2 = if Path == [top_level] -> [MsgName]; true -> Path @@ -1249,7 +1249,7 @@ verify_msg2(V, MsgName, _MsgDefs, Path) -> verify_group(Msg, GName, MsgDefs, Path) when is_tuple(Msg), element(1, Msg) == GName -> Key = {group, GName}, - {value, {Key, Fields}} = lists:keysearch(Key, 1, MsgDefs), + Fields = keyfetch_2(Key, MsgDefs), if tuple_size(Msg) == length(Fields) + 1 -> Path2 = if Path == [top_level] -> [GName]; true -> Path