MT#55283 support multiple gperf sections

Instead of lumping all strings of a file into a single hash function,
split them up into their respective sections, as there is no point in
matching against strings that aren't part of the switch statement. This
should give a bit of a performance boost.

Nested hash sections require special handling as the wrapper script
isn't smart enough to hande them automaticaly.

Change-Id: I74863dfe6ca412d58101d37f9c9c85078826f1a4
pull/1907/head
Richard Fuchs 4 months ago
parent 921afde080
commit 05cafe6c5c

@ -49,7 +49,9 @@ flags = [
'-DHAVE_CODEC_CHAIN', '-DHAVE_CODEC_CHAIN',
'-DHAVE_LIBURING', '-DHAVE_LIBURING',
'-D__csh_lookup(x)=str_hash(x)', '-D__csh_lookup(x)=str_hash(x)',
'-D__csh_lookup_n(n,x)=__csh_lookup(x)',
'-DCSH_LOOKUP(x)=' + csh_lookup_str, '-DCSH_LOOKUP(x)=' + csh_lookup_str,
'-DCSH_LOOKUP_N(n,x)=CSH_LOOKUP(x)',
'-O2', '-O2',
'-fstack-protector', '-fstack-protector',
'--param=ssp-buffer-size=4', '--param=ssp-buffer-size=4',

@ -1505,22 +1505,22 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
} }
break; break;
case CSH_LOOKUP("all"): case CSH_LOOKUP("all"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("all"): case CSH_LOOKUP_N(1, "all"):
out->all = ALL_ALL; out->all = ALL_ALL;
break; break;
case CSH_LOOKUP("none"): case CSH_LOOKUP_N(1, "none"):
out->all = ALL_NONE; out->all = ALL_NONE;
break; break;
case CSH_LOOKUP("offer-answer"): case CSH_LOOKUP_N(1, "offer-answer"):
out->all = ALL_OFFER_ANSWER; out->all = ALL_OFFER_ANSWER;
break; break;
case CSH_LOOKUP("not-offer-answer"): case CSH_LOOKUP_N(1, "not-offer-answer"):
case CSH_LOOKUP("non-offer-answer"): case CSH_LOOKUP_N(1, "non-offer-answer"):
case CSH_LOOKUP("except-offer-answer"): case CSH_LOOKUP_N(1, "except-offer-answer"):
out->all = ALL_NON_OFFER_ANSWER; out->all = ALL_NON_OFFER_ANSWER;
break; break;
case CSH_LOOKUP("flows"): case CSH_LOOKUP_N(1, "flows"):
out->all = ALL_FLOWS; out->all = ALL_FLOWS;
break; break;
default: default:
@ -1530,28 +1530,28 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
break; break;
case CSH_LOOKUP("audio-player"): case CSH_LOOKUP("audio-player"):
case CSH_LOOKUP("player"): case CSH_LOOKUP("player"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("default"): case CSH_LOOKUP_N(1, "default"):
out->audio_player = AP_DEFAULT; out->audio_player = AP_DEFAULT;
break; break;
case CSH_LOOKUP("on"): case CSH_LOOKUP_N(1, "on"):
case CSH_LOOKUP("yes"): case CSH_LOOKUP_N(1, "yes"):
case CSH_LOOKUP("enable"): case CSH_LOOKUP_N(1, "enable"):
case CSH_LOOKUP("enabled"): case CSH_LOOKUP_N(1, "enabled"):
case CSH_LOOKUP("transcode"): case CSH_LOOKUP_N(1, "transcode"):
case CSH_LOOKUP("transcoding"): case CSH_LOOKUP_N(1, "transcoding"):
out->audio_player = AP_TRANSCODING; out->audio_player = AP_TRANSCODING;
break; break;
case CSH_LOOKUP("no"): case CSH_LOOKUP_N(1, "no"):
case CSH_LOOKUP("off"): case CSH_LOOKUP_N(1, "off"):
case CSH_LOOKUP("disable"): case CSH_LOOKUP_N(1, "disable"):
case CSH_LOOKUP("disabled"): case CSH_LOOKUP_N(1, "disabled"):
out->audio_player = AP_OFF; out->audio_player = AP_OFF;
break; break;
case CSH_LOOKUP("force"): case CSH_LOOKUP_N(1, "force"):
case CSH_LOOKUP("forced"): case CSH_LOOKUP_N(1, "forced"):
case CSH_LOOKUP("always"): case CSH_LOOKUP_N(1, "always"):
case CSH_LOOKUP("everything"): case CSH_LOOKUP_N(1, "everything"):
out->audio_player = AP_FORCE; out->audio_player = AP_FORCE;
break; break;
default: default:
@ -1592,11 +1592,11 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
break; break;
case CSH_LOOKUP("drop-traffic"): case CSH_LOOKUP("drop-traffic"):
case CSH_LOOKUP("drop traffic"): case CSH_LOOKUP("drop traffic"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("start"): case CSH_LOOKUP_N(1, "start"):
out->drop_traffic_start = 1; out->drop_traffic_start = 1;
break; break;
case CSH_LOOKUP("stop"): case CSH_LOOKUP_N(1, "stop"):
out->drop_traffic_stop = 1; out->drop_traffic_stop = 1;
break; break;
default: default:
@ -1606,17 +1606,17 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
break; break;
case CSH_LOOKUP("DTLS"): case CSH_LOOKUP("DTLS"):
case CSH_LOOKUP("dtls"): case CSH_LOOKUP("dtls"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("passive"): case CSH_LOOKUP_N(1, "passive"):
out->dtls_passive = 1; out->dtls_passive = 1;
break; break;
case CSH_LOOKUP("active"): case CSH_LOOKUP_N(1, "active"):
out->dtls_passive = 0; out->dtls_passive = 0;
break; break;
case CSH_LOOKUP("no"): case CSH_LOOKUP_N(1, "no"):
case CSH_LOOKUP("off"): case CSH_LOOKUP_N(1, "off"):
case CSH_LOOKUP("disabled"): case CSH_LOOKUP_N(1, "disabled"):
case CSH_LOOKUP("disable"): case CSH_LOOKUP_N(1, "disable"):
out->dtls_off = 1; out->dtls_off = 1;
break; break;
default: default:
@ -1634,11 +1634,11 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
case CSH_LOOKUP("dtls-reverse"): case CSH_LOOKUP("dtls-reverse"):
case CSH_LOOKUP("DTLS reverse"): case CSH_LOOKUP("DTLS reverse"):
case CSH_LOOKUP("dtls reverse"): case CSH_LOOKUP("dtls reverse"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("passive"): case CSH_LOOKUP_N(1, "passive"):
out->dtls_reverse_passive = 1; out->dtls_reverse_passive = 1;
break; break;
case CSH_LOOKUP("active"): case CSH_LOOKUP_N(1, "active"):
out->dtls_reverse_passive = 0; out->dtls_reverse_passive = 0;
break; break;
default: default:
@ -1726,22 +1726,22 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
break; break;
case CSH_LOOKUP("ICE"): case CSH_LOOKUP("ICE"):
case CSH_LOOKUP("ice"): case CSH_LOOKUP("ice"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("remove"): case CSH_LOOKUP_N(1, "remove"):
out->ice_option = ICE_REMOVE; out->ice_option = ICE_REMOVE;
break; break;
case CSH_LOOKUP("force"): case CSH_LOOKUP_N(1, "force"):
out->ice_option = ICE_FORCE; out->ice_option = ICE_FORCE;
break; break;
case CSH_LOOKUP("default"): case CSH_LOOKUP_N(1, "default"):
out->ice_option = ICE_DEFAULT; out->ice_option = ICE_DEFAULT;
break; break;
case CSH_LOOKUP("optional"): case CSH_LOOKUP_N(1, "optional"):
out->ice_option = ICE_OPTIONAL; out->ice_option = ICE_OPTIONAL;
break; break;
case CSH_LOOKUP("force_relay"): case CSH_LOOKUP_N(1, "force_relay"):
case CSH_LOOKUP("force-relay"): case CSH_LOOKUP_N(1, "force-relay"):
case CSH_LOOKUP("force relay"): case CSH_LOOKUP_N(1, "force relay"):
out->ice_option = ICE_FORCE_RELAY; out->ice_option = ICE_FORCE_RELAY;
break; break;
default: default:
@ -1753,28 +1753,28 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
case CSH_LOOKUP("ice-lite"): case CSH_LOOKUP("ice-lite"):
case CSH_LOOKUP("ICE lite"): case CSH_LOOKUP("ICE lite"):
case CSH_LOOKUP("ice lite"): case CSH_LOOKUP("ice lite"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("off"): case CSH_LOOKUP_N(1, "off"):
case CSH_LOOKUP("none"): case CSH_LOOKUP_N(1, "none"):
case CSH_LOOKUP("no"): case CSH_LOOKUP_N(1, "no"):
out->ice_lite_option = ICE_LITE_OFF; out->ice_lite_option = ICE_LITE_OFF;
break; break;
case CSH_LOOKUP("forward"): case CSH_LOOKUP_N(1, "forward"):
case CSH_LOOKUP("offer"): case CSH_LOOKUP_N(1, "offer"):
case CSH_LOOKUP("fwd"): case CSH_LOOKUP_N(1, "fwd"):
case CSH_LOOKUP("fw"): case CSH_LOOKUP_N(1, "fw"):
out->ice_lite_option = ICE_LITE_FWD; out->ice_lite_option = ICE_LITE_FWD;
break; break;
case CSH_LOOKUP("backward"): case CSH_LOOKUP_N(1, "backward"):
case CSH_LOOKUP("backwards"): case CSH_LOOKUP_N(1, "backwards"):
case CSH_LOOKUP("reverse"): case CSH_LOOKUP_N(1, "reverse"):
case CSH_LOOKUP("answer"): case CSH_LOOKUP_N(1, "answer"):
case CSH_LOOKUP("back"): case CSH_LOOKUP_N(1, "back"):
case CSH_LOOKUP("bkw"): case CSH_LOOKUP_N(1, "bkw"):
case CSH_LOOKUP("bk"): case CSH_LOOKUP_N(1, "bk"):
out->ice_lite_option = ICE_LITE_BKW; out->ice_lite_option = ICE_LITE_BKW;
break; break;
case CSH_LOOKUP("both"): case CSH_LOOKUP_N(1, "both"):
out->ice_lite_option = ICE_LITE_BOTH; out->ice_lite_option = ICE_LITE_BOTH;
break; break;
default: default:
@ -1792,25 +1792,25 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
break; break;
case CSH_LOOKUP("media echo"): case CSH_LOOKUP("media echo"):
case CSH_LOOKUP("media-echo"): case CSH_LOOKUP("media-echo"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("blackhole"): case CSH_LOOKUP_N(1, "blackhole"):
case CSH_LOOKUP("sinkhole"): case CSH_LOOKUP_N(1, "sinkhole"):
out->media_echo = MEO_BLACKHOLE; out->media_echo = MEO_BLACKHOLE;
break; break;
case CSH_LOOKUP("forward"): case CSH_LOOKUP_N(1, "forward"):
case CSH_LOOKUP("fwd"): case CSH_LOOKUP_N(1, "fwd"):
case CSH_LOOKUP("fw"): case CSH_LOOKUP_N(1, "fw"):
out->media_echo = MEO_FWD; out->media_echo = MEO_FWD;
break; break;
case CSH_LOOKUP("backward"): case CSH_LOOKUP_N(1, "backward"):
case CSH_LOOKUP("backwards"): case CSH_LOOKUP_N(1, "backwards"):
case CSH_LOOKUP("reverse"): case CSH_LOOKUP_N(1, "reverse"):
case CSH_LOOKUP("back"): case CSH_LOOKUP_N(1, "back"):
case CSH_LOOKUP("bkw"): case CSH_LOOKUP_N(1, "bkw"):
case CSH_LOOKUP("bk"): case CSH_LOOKUP_N(1, "bk"):
out->media_echo = MEO_BKW; out->media_echo = MEO_BKW;
break; break;
case CSH_LOOKUP("both"): case CSH_LOOKUP_N(1, "both"):
out->media_echo = MEO_BOTH; out->media_echo = MEO_BOTH;
break; break;
default: default:
@ -1858,17 +1858,17 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
break; break;
case CSH_LOOKUP("passthrough"): case CSH_LOOKUP("passthrough"):
case CSH_LOOKUP("passthru"): case CSH_LOOKUP("passthru"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("on"): case CSH_LOOKUP_N(1, "on"):
case CSH_LOOKUP("yes"): case CSH_LOOKUP_N(1, "yes"):
case CSH_LOOKUP("enable"): case CSH_LOOKUP_N(1, "enable"):
case CSH_LOOKUP("enabled"): case CSH_LOOKUP_N(1, "enabled"):
out->passthrough_on = 1; out->passthrough_on = 1;
break; break;
case CSH_LOOKUP("no"): case CSH_LOOKUP_N(1, "no"):
case CSH_LOOKUP("off"): case CSH_LOOKUP_N(1, "off"):
case CSH_LOOKUP("disable"): case CSH_LOOKUP_N(1, "disable"):
case CSH_LOOKUP("disabled"): case CSH_LOOKUP_N(1, "disabled"):
out->passthrough_off = 1; out->passthrough_off = 1;
break; break;
default: default:
@ -1980,23 +1980,23 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
case CSH_LOOKUP("sip_message_type"): case CSH_LOOKUP("sip_message_type"):
case CSH_LOOKUP("SIP-message-type"): case CSH_LOOKUP("SIP-message-type"):
case CSH_LOOKUP("SIP_message_type"): case CSH_LOOKUP("SIP_message_type"):
switch (__csh_lookup(&s)) { switch (__csh_lookup_n(1, &s)) {
case CSH_LOOKUP("request"): case CSH_LOOKUP_N(1, "request"):
case CSH_LOOKUP("sip-request"): case CSH_LOOKUP_N(1, "sip-request"):
case CSH_LOOKUP("sip_request"): case CSH_LOOKUP_N(1, "sip_request"):
case CSH_LOOKUP("SIP-request"): case CSH_LOOKUP_N(1, "SIP-request"):
case CSH_LOOKUP("SIP_request"): case CSH_LOOKUP_N(1, "SIP_request"):
out->message_type = SIP_REQUEST; out->message_type = SIP_REQUEST;
break; break;
case CSH_LOOKUP("reply"): case CSH_LOOKUP_N(1, "reply"):
case CSH_LOOKUP("sip-response"): case CSH_LOOKUP_N(1, "sip-response"):
case CSH_LOOKUP("sip_response"): case CSH_LOOKUP_N(1, "sip_response"):
case CSH_LOOKUP("SIP-response"): case CSH_LOOKUP_N(1, "SIP-response"):
case CSH_LOOKUP("SIP_response"): case CSH_LOOKUP_N(1, "SIP_response"):
case CSH_LOOKUP("sip-reply"): case CSH_LOOKUP_N(1, "sip-reply"):
case CSH_LOOKUP("sip_reply"): case CSH_LOOKUP_N(1, "sip_reply"):
case CSH_LOOKUP("SIP-reply"): case CSH_LOOKUP_N(1, "SIP-reply"):
case CSH_LOOKUP("SIP_reply"): case CSH_LOOKUP_N(1, "SIP_reply"):
out->message_type = SIP_REPLY; out->message_type = SIP_REPLY;
break; break;
default: default:

@ -10,74 +10,106 @@ can_run('gperf') or die 'No gperf binary found, make sure to have gperf installe
print("/******** GENERATED FILE ********/\n"); print("/******** GENERATED FILE ********/\n");
my $rewritten_input = ''; my $rewritten_input = '';
my $iter = 0; my @sections;
my $keys = ''; my @slots;
my %key_vals;
# collect keywords and rewrite input file with in lookup keys # collect keywords and rewrite input file with in lookup keys
while (my $line = <STDIN>) { while (my $line = <STDIN>) {
if (!($line =~ s/CSH_LOOKUP\("(.*?)"\)/{}/)) { my $num = scalar(@sections);
my $new_section;
if (($line =~ s/(__csh_lookup)(\s*\()/$1_$num$2/)) {
$new_section = 0;
}
elsif (($line =~ s/(__csh_lookup)_n(\s*\()\s*(\d+)\s*,\s*/$1_$num$2/)) {
$new_section = $3;
}
if (defined($new_section)) {
$rewritten_input .= $line;
my $section = { keys => '', vals => {}, num => $num };
push(@sections, $section);
$slots[$new_section] = $num;
next;
}
my ($rewrite, $key);
if ($line =~ s/CSH_LOOKUP\(\s*"(.*?)"\s*\)/{}/) {
$rewrite = 0;
$key = $1;
}
elsif ($line =~ s/CSH_LOOKUP_N\(\s*(\d+)\s*,\s*"(.*?)"\s*\)/{}/) {
$rewrite = $1;
$key = $2;
}
if (!defined($rewrite)) {
$rewritten_input .= $line; $rewritten_input .= $line;
next; next;
} }
my $key = $1; my $section = $sections[$slots[$rewrite]];
if (exists($key_vals{$key})) { die unless $section;
$line =~ s/{}/$key_vals{$key}/; if (exists($section->{vals}{$key})) {
$line =~ s/{}/$section->{vals}{$key}/;
} }
else { else {
my $iter = values(%{$section->{vals}});
$line =~ s/{}/$iter/; $line =~ s/{}/$iter/;
$keys .= "$key,$iter\n"; $section->{keys} .= "$key,$iter\n";
$key_vals{$key} = $iter; $section->{vals}{$key} = $iter;
$iter++;
} }
$rewritten_input .= $line; $rewritten_input .= $line;
} }
# pass collected output to gperf # pass collected outputs to gperf
my ($rd, $wr); print "struct __csh_hash_lookup { char *name; int num; };\n";
my $pid = open2($rd, $wr, qw(gperf -t -E -l -c -I -C -H __csh_hash -N __csh_lookup_raw));
# gperf header and keys for my $section (@sections) {
my $num = $section->{num};
print { $wr } "struct __csh_hash_lookup { char *name; int num; };\n%%\n"; my ($rd, $wr);
print { $wr } $keys; my $pid = open2($rd, $wr, qw(gperf -t -E -l -c -I -C -H), "__csh_hash_$num", '-N', "__csh_lookup_raw_$num");
# read gperf output # gperf header and keys
close($wr); print { $wr } "struct __csh_hash_lookup;\n%%\n";
my $hash_func_code; print { $wr } $section->{keys};
{
local $/ = undef; # read gperf output
$hash_func_code = <$rd>;
} close($wr);
close($rd); my $hash_func_code;
waitpid($pid, 0); {
exit(1) if $?; local $/ = undef;
$hash_func_code = <$rd>;
}
close($rd);
waitpid($pid, 0);
exit(1) if $?;
# convert lookup function to static # convert lookup function to static
$hash_func_code =~ s/(^|\s)(const\s+)?struct\s+__csh_hash_lookup\s*\*/\nstatic$&/s; $hash_func_code =~ s/(^|\s)(const\s+)?struct\s+__csh_hash_lookup\s*\*/\nstatic$&/s;
# print combined output # print combined output
print "#pragma GCC diagnostic push\n"; print "#pragma GCC diagnostic push\n";
print "#pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n"; print "#pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n";
print $hash_func_code; print "#pragma GCC diagnostic ignored \"-Wshadow=global\"\n";
print "#pragma GCC diagnostic pop\n"; print $hash_func_code;
# add convenience function print "#pragma GCC diagnostic pop\n";
print <<END; # add convenience function
print <<END;
#include "str.h" #include "str.h"
static int __csh_lookup(const str *s) { static int __csh_lookup_$num(const str *s) {
if (!s->s) if (!s->s)
return -1; return -1;
const struct __csh_hash_lookup *h = __csh_lookup_raw(s->s, s->len); const struct __csh_hash_lookup *h = __csh_lookup_raw_$num(s->s, s->len);
if (!h) if (!h)
return -1; return -1;
return h->num; return h->num;
} }
END END
}
# adjust diagnostic line numbers and originating file # adjust diagnostic line numbers and originating file
print $ARGV[0] ? "#line 1 \"$ARGV[0]\"\n" : "#line 1\n"; print $ARGV[0] ? "#line 1 \"$ARGV[0]\"\n" : "#line 1\n";
print $rewritten_input; print $rewritten_input;

Loading…
Cancel
Save