aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/include/diameter_gen.hrl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2015-08-13 12:34:00 +0200
committerErlang/OTP <[email protected]>2015-08-13 12:34:00 +0200
commite32557afa1ad7299c821c92446265daade52879a (patch)
treef32ab6f3fab2bf014730d8d12110fac8894dbc26 /lib/diameter/include/diameter_gen.hrl
parent8929f163480085e2d2f2ab9eb14cf83080717da5 (diff)
parent9ab5d8afedc6d2f56997276e3f016ec1c6dac6a5 (diff)
downloadotp-e32557afa1ad7299c821c92446265daade52879a.tar.gz
otp-e32557afa1ad7299c821c92446265daade52879a.tar.bz2
otp-e32557afa1ad7299c821c92446265daade52879a.zip
Merge branch 'anders/diameter/decode/OTP-12891' into maint-17
* anders/diameter/decode/OTP-12891: Don't compute AVP list length unnecessarily at AVP decode
Diffstat (limited to 'lib/diameter/include/diameter_gen.hrl')
-rw-r--r--lib/diameter/include/diameter_gen.hrl32
1 files changed, 22 insertions, 10 deletions
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl
index 79b8e6ecde..ebe9e6363d 100644
--- a/lib/diameter/include/diameter_gen.hrl
+++ b/lib/diameter/include/diameter_gen.hrl
@@ -210,18 +210,27 @@ missing(Rec, Name, Failed) ->
sets:new(),
Failed),
[{5005, A} || F <- '#info-'(element(1, Rec), fields),
- not have_arity(avp_arity(Name, F), '#get-'(F, Rec)),
+ not has_arity(avp_arity(Name, F), '#get-'(F, Rec)),
#diameter_avp{code = C, vendor_id = V}
= A <- [empty_avp(F)],
not sets:is_element({C,V}, Avps)].
%% Maximum arities have already been checked in building the record.
-have_arity({Min, _}, L) ->
- Min =< length(L);
-have_arity(N, V) ->
+has_arity({Min, _}, L) ->
+ has_prefix(Min, L);
+has_arity(N, V) ->
N /= 1 orelse V /= undefined.
+%% Compare a non-negative integer and the length of a list without
+%% computing the length.
+has_prefix(0, _) ->
+ true;
+has_prefix(_, []) ->
+ false;
+has_prefix(N, L) ->
+ has_prefix(N-1, tl(L)).
+
%% empty_avp/1
empty_avp(Name) ->
@@ -589,14 +598,17 @@ pack(undefined, 1, FieldName, Avp, Acc) ->
%% AVP MUST be included and contain a copy of the first instance of
%% the offending AVP that exceeded the maximum number of occurrences
%%
+
pack(_, 1, _, Avp, {Rec, Failed}) ->
{Rec, [{5009, Avp} | Failed]};
-pack(L, {_, Max}, _, Avp, {Rec, Failed})
- when length(L) == Max ->
- {Rec, [{5009, Avp} | Failed]};
-
-pack(L, _, FieldName, Avp, Acc) ->
- p(FieldName, fun(V) -> [V|L] end, Avp, Acc).
+pack(L, {_, Max}, FieldName, Avp, Acc) ->
+ case '*' /= Max andalso has_prefix(Max, L) of
+ true ->
+ {Rec, Failed} = Acc,
+ {Rec, [{5009, Avp} | Failed]};
+ false ->
+ p(FieldName, fun(V) -> [V|L] end, Avp, Acc)
+ end.
%% p/4