diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-05-25 05:04:36 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2021-08-27 02:16:53 -0400 |
commit | f8bd028dc0a99afeed68e6c3bf28ce6faf3012e2 (patch) | |
tree | 4911a165baaa103a015dbf698dfe0e93d3c339fc /src/http_header.c | |
parent | fbefda35240856630b0b388304ba5713af34ff54 (diff) | |
download | lighttpd-git-f8bd028dc0a99afeed68e6c3bf28ce6faf3012e2.tar.gz |
[core] http_header_hkey_get() perf (better asm)
Diffstat (limited to 'src/http_header.c')
-rw-r--r-- | src/http_header.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/http_header.c b/src/http_header.c index 66609372..dc20e0c0 100644 --- a/src/http_header.c +++ b/src/http_header.c @@ -94,25 +94,41 @@ static const keyvlenvalue http_headers[] = { ,{ HTTP_HEADER_OTHER, 0, "" } }; -enum http_header_e http_header_hkey_get(const char * const s, const uint32_t slen) { - const struct keyvlenvalue * const kv = http_headers; - int i = slen < sizeof(http_headers_off) ? http_headers_off[slen] : -1; - if (i < 0) return HTTP_HEADER_OTHER; - do { - if (buffer_eq_icase_ssn(s, kv[i].value, slen)) - return (enum http_header_e)kv[i].key; - } while (slen == kv[++i].vlen); +enum http_header_e http_header_hkey_get(const char * const s, const size_t slen) { + if (__builtin_expect( (slen < sizeof(http_headers_off)), 1)) { + const int i = http_headers_off[slen]; + /*(lowercase first char as all recognized headers start w/ alpha char)*/ + const int c = s[0] | 0x20; + const struct keyvlenvalue * restrict kv = http_headers + i; + if (__builtin_expect( (i != -1), 1)) { + do { + if (__builtin_expect( (c != kv->value[0]), 1)) + continue; + if (buffer_eq_icase_ssn(s+1, kv->value+1, slen-1)) + return (enum http_header_e)kv->key; + } while (slen == (++kv)->vlen); + } + } return HTTP_HEADER_OTHER; } -enum http_header_e http_header_hkey_get_lc(const char * const s, const uint32_t slen) { - const struct keyvlenvalue * const kv = http_headers; - int i = slen < sizeof(http_headers_off) ? http_headers_off[slen] : -1; - if (i < 0) return HTTP_HEADER_OTHER; - do { - if (0 == memcmp(s, kv[i].value, slen)) - return (enum http_header_e)kv[i].key; - } while (slen == kv[++i].vlen); +enum http_header_e http_header_hkey_get_lc(const char * const s, const size_t slen) { + /* XXX: might not provide much real performance over http_header_hkey_get() + * (since the first-char comparision optimization was added) + * (and since well-known h2 headers are already mapped to hkey) */ + if (__builtin_expect( (slen < sizeof(http_headers_off)), 1)) { + const int i = http_headers_off[slen]; + const int c = s[0]; + const struct keyvlenvalue * restrict kv = http_headers + i; + if (__builtin_expect( (i != -1), 1)) { + do { + if (__builtin_expect( (c != kv->value[0]), 1)) + continue; + if (0 == memcmp(s+1, kv->value+1, slen-1)) + return (enum http_header_e)kv->key; + } while (slen == (++kv)->vlen); + } + } return HTTP_HEADER_OTHER; } |