aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2017-07-08 02:06:11 +0200
committerAnders Svensson <[email protected]>2017-08-03 17:14:28 +0200
commitfa2f0572aa0604bf03d4d3eaa358719ffd877545 (patch)
tree305e5e15b565ac05b27fc2b7b1268d89dd795266 /lib
parent55e65b262cdf0b794ab443928676720a323cf6b0 (diff)
downloadotp-fa2f0572aa0604bf03d4d3eaa358719ffd877545.tar.gz
otp-fa2f0572aa0604bf03d4d3eaa358719ffd877545.tar.bz2
otp-fa2f0572aa0604bf03d4d3eaa358719ffd877545.zip
Add decode_format record_from_map
Undocumented, for transforming a map decode to record. The record decode becomes more expensive the larger the number of AVPs in the message definition in question, since the record is recreated each time an AVP value is set in it. The map decode can potentially do better.
Diffstat (limited to 'lib')
-rw-r--r--lib/diameter/src/base/diameter.erl6
-rw-r--r--lib/diameter/src/base/diameter_config.erl3
-rw-r--r--lib/diameter/src/base/diameter_gen.erl13
3 files changed, 16 insertions, 6 deletions
diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl
index 75deaad511..85a54c8e61 100644
--- a/lib/diameter/src/base/diameter.erl
+++ b/lib/diameter/src/base/diameter.erl
@@ -332,7 +332,11 @@ call(SvcName, App, Message) ->
:: 0..16#FFFFFF.
-type decode_format()
- :: record | list | map | false.
+ :: record
+ | list
+ | map
+ | false
+ | record_from_map.
%% Options passed to start_service/2
diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl
index 09018308d5..d591fa903e 100644
--- a/lib/diameter/src/base/diameter_config.erl
+++ b/lib/diameter/src/base/diameter_config.erl
@@ -771,7 +771,8 @@ opt(K, true = B)
opt(decode_format, T)
when T == record;
T == list;
- T == map ->
+ T == map;
+ T == record_from_map ->
T;
opt(restrict_connections, T)
diff --git a/lib/diameter/src/base/diameter_gen.erl b/lib/diameter/src/base/diameter_gen.erl
index 239d4a535f..78d8bd2fa3 100644
--- a/lib/diameter/src/base/diameter_gen.erl
+++ b/lib/diameter/src/base/diameter_gen.erl
@@ -186,7 +186,7 @@ decode_avps(Name, Recs, #{module := Mod, decode_format := Fmt} = Opts) ->
%% AM counts the number of top-level AVPs, which missing/4 then
%% uses when adding 5005 errors.
Arities = Mod:avp_arity(Name),
- {reformat(Rec, Arities, Fmt),
+ {reformat(Rec, Arities, Mod, Fmt),
Avps,
Failed ++ missing(Arities, Opts, Mod, AM)}.
@@ -760,12 +760,17 @@ newrec(_, Name, _) ->
newrec(Mod, Name) ->
Mod:'#new-'(Mod:name2rec(Name)).
-%% reformat/3
+%% reformat/4
-reformat(Map, Arities, list) ->
+reformat(Map, Arities, _Mod, list) ->
[{F,V} || {F,_} <- Arities, #{F := V} <- [Map]];
-reformat(Rec, _, _) ->
+reformat(Map, Arities, Mod, record_from_map) ->
+ #{':name' := Name} = Map,
+ RecName = Mod:name2rec(Name),
+ list_to_tuple([RecName | [maps:get(F, Map, def(A)) || {F,A} <- Arities]]);
+
+reformat(Rec, _, _, _) ->
Rec.
%% def/1