Age | Commit message (Collapse) | Author |
|
That dialyzer hasn't noticed is broken.
|
|
Despite what the Efficiency Guide says about match being more efficient,
split_binary appears to be slightly faster. (Although this one
extraction is a drop in the bucket.) Binary optimizations aren't an
issue during decode.
|
|
Since messages are accumulated by appending binaries as of three
commits back, the accumulated binary is prone to being copied, as
discussed in the Efficiency Guide. Matching the Message Length header
as bytes are being accumulated is one cause of this, so work around it
by splitting the binary and extracting the length without a match.
This doesn't feel like something that should be necessary: that matching
a binary would cause an append to copy isn't obvious. The first attempt
at simplifying the accumulation was simply to append an incoming binary
to the current fragment, match against <<_, Len:24, _/binary>> to
extract the length, and then test if there are enough bytes for a
message. This lead to horrible performance (response times for 2 MB
messages approximately 100 times worse than previously), and it wasn't
at all obvious that the reason was the accumulated binary being copied
with each append as a result of the match. Using split_binary avoids the
match context that forces the copying.
|
|
Not with each setopts to re-activate the socket.
|
|
Only reset the fragment after all messages have been extracted.
|
|
Appending to a binary is efficient, so just append message fragments
Only match out the length once per message since doing so for every
packet from TCP causes the binary to be copied.
|
|
Create less garbage.
|
|
|
|
Which has had no negative effect.
|
|
That dialyzer hasn't noticed is broken.
|
|
Also inline incr/8 and associated functions that were needed for the
compiler to accept the optimization, since this does make for a
measuable improvement.
|
|
With ERL_COMPILER_OPTIONS=bin_opt_info, before:
base/diameter_codec.erl:508: Warning: NOT OPTIMIZED: the binary matching instruction that follows in the same function have problems that prevent delayed sub binary optimization (probably indicated by INFO warnings)
And after:
base/diameter_codec.erl:508: Warning: OPTIMIZED: creation of sub binary delayed
This has a surprisingly large impact on the performance of
diameter_codec:collect_avps/2: about 15% faster in one testcase on a RAR
with 7 AVPs.
|
|
The index field in record diameter_avp was previously used to enumerate
AVPs so that the list could be returned in some cases, since
diameter_codec:collect_avps/2 (now /1) reversed the order. That's no
longer the case as of the grandparent commit, so use the field to
enumerate instances of the same AVP instead, and only when arities are
being checked, to save having to look them up in the map when checking
for 5009 errors, or counting AVPs at all in diameter_codec:collect_avps/1.
|
|
Extract strict_arities once and pass it through as an argument.
|
|
Decode has previously been two passes: first chunk the message into a
reversed list of toplevel diameter_avp records, then fold through the
reversed list to build the full result. Various workarounds have made it
a bit more convoluted than it should be however. Rework it completely,
turning the previous 2-pass tail-recursive implementation into a 1-pass
body recursive one.
The relay decode still exists in diameter_codec, as a stripped down
version of the full decode in diameter_gen.
|
|
|
|
|
|
To be able to disable the relatively expensive check that the number of
AVPs received in a message or grouped AVP agrees with the dictionary in
question. The may well be easier for the user in handle_request/answer
callbacks, when digesting the received message, and in some cases may
not be important.
The check at encode can also be disabled, allowing messages that don't
agree with the dictionary in question to be sent, which can be useful in
test (at least).
|
|
As noted in the parent commit, the wrong AVPs were reported, being
counted from the back of the message instead of the front. Both 5005 and
5009 errors are now detected after the message is decoded.
|
|
Aka DIAMETER_AVP_OCCURS_TOO_MANY_TIMES.
This reveals a fault. The RFC says this:
A message was received that included an AVP that appeared more
often than permitted in the message definition. The Failed-AVP
AVP MUST be included and contain a copy of the first instance of
the offending AVP that exceeded the maximum number of occurrences.
The list of AVPs is reversed when diameter checks arities, so Failed-AVP
contains the wrong AVP, causing the new testcase to fail.
|
|
Stop counting when there can be no arity errors.
|
|
|
|
Since the number is now under 50K again. Also make testing of individual
groups or testcases easier.
|
|
Count as AVPs are encoded instead.
|
|
Use the same [MsgName | Avps] representation as for the list decode, but
with Avps a map instead of a AVP name/values list. As a result, don't
set the message/AVP name on an additional key in the map, which felt a
bit odd. Messages are [MsgName :: atom() | map()], Grouped AVPs are just
map().
Fix at least one problem in the traffic suite along the way: with
decode_format false, the own decode in to_map/2 didn't know whether or
not to decode strings, resulting on some failures.
|
|
For slightly better readability in the ct logs
|
|
To reduce the number of combinations tested, as in the parent commit.
|
|
To reduce the number of config combinations that are tested. The
encoding is the format in which messages are provided to diameter for
encode (to binary), and if there is any difference in the end result
then the peer will detect this at decode, independently of its encoding
format.
|
|
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.
|
|
{record_decode, map} is a bit too quirky.
|
|
One for each server decoding/encoding/container combination is overkill.
Just want a few from which one can be chosen in the pick_peer callback.
|
|
|
|
Instead of to lists, to simplify matching.
|
|
|
|
That is, decode to the same format that encode already accepts. Only a
message has its name at the head of the list since AVPs are already
name/value pairs.
|
|
With {record_decode, map}. The option name is arguably a bit misleading
now, but not too objectionable given that the encode/decode in question
has historically only been of records.
One advantage of the map decode is that the map only contains values for
those AVPs existing in the message or grouped AVP in question. The name
of the message or grouped AVP is stored in with key ':name', the leading
colon ensuring that the key isn't a diameter-name.
Decoding to maps makes the hrl files generated from dictionary files
largely irrelevant. There are value defines generated into these, but
they're typically so long as to be unusable.
|
|
To control whether or not messages and grouped AVPs are decoded to
records, in #diameter_packet.msg and #diameter_avp.value respectively.
The decode became unnecessary for diameter's needs in parent commit,
which decoupled it from the checking of AVP arities.
|
|
Instead of after, during the check that AVPs have sufficient arity.
This makes the arity checks independent of the record decode, which
will allow the latter to be made optional.
|
|
Most of the contents were moved to module diameter_gen in commit
205521d3.
|
|
Matched a byte instead of a bit, and increment/decrement wasn't
symmetric. Allow more requests since some requests timeout.
Bungled in commit 09089872.
|
|
Only exercising the standard dictionaries has missed some problems in
the past.
|
|
|
|
|
|
|
|
|
|
|
|
Print function names and registered names with ~tw.
Open dump file with encoding utf8.
|
|
This allows the use of ~ts/~tp/~tw in the formatting fun to
sys:handle_debug/4.
|
|
This allows the use of ~ts/~tp/~tw in calls to error_logger:format/2,
error_logger:error_msg/2 and error_logger:info_msg/2.
|
|
|