summaryrefslogtreecommitdiff
path: root/src/http_header.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-05-25 05:04:36 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2021-08-27 02:16:53 -0400
commitf8bd028dc0a99afeed68e6c3bf28ce6faf3012e2 (patch)
tree4911a165baaa103a015dbf698dfe0e93d3c339fc /src/http_header.c
parentfbefda35240856630b0b388304ba5713af34ff54 (diff)
downloadlighttpd-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.c48
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;
}