Skip to content

Commit d959374

Browse files
optimize: use ngx_hash_t to optimize the built-in header look-up process for ngx.header.HEADER.
1 parent 974d5d1 commit d959374

7 files changed

+110
-42
lines changed

README.markdown

+1-1
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ TODO
973973
* cosocket: review and merge aviramc's [patch](https://github.com/openresty/lua-nginx-module/pull/290) for adding the `bsdrecv` method.
974974
* cosocket: add configure options for different strategies of handling the cosocket connection exceeding in the pools.
975975
* review and apply vadim-pavlov's patch for [ngx.location.capture](#ngxlocationcapture)'s `extra_headers` option
976-
* use `ngx_hash_t` to optimize the built-in header look-up process for [ngx.req.set_header](#ngxreqset_header), [ngx.header.HEADER](#ngxheaderheader), and etc.
976+
* use `ngx_hash_t` to optimize the built-in header look-up process for [ngx.req.set_header](#ngxreqset_header), and etc.
977977
* add `ignore_resp_headers`, `ignore_resp_body`, and `ignore_resp` options to [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi) methods, to allow micro performance tuning on the user side.
978978
* add automatic Lua code time slicing support by yielding and resuming the Lua VM actively via Lua's debug hooks.
979979
* add `stat` mode similar to [mod_lua](https://httpd.apache.org/docs/trunk/mod/mod_lua.html).

doc/HttpLuaModule.wiki

+1-1
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ phases.
808808
* cosocket: review and merge aviramc's [https://github.com/openresty/lua-nginx-module/pull/290 patch] for adding the <code>bsdrecv</code> method.
809809
* cosocket: add configure options for different strategies of handling the cosocket connection exceeding in the pools.
810810
* review and apply vadim-pavlov's patch for [[#ngx.location.capture|ngx.location.capture]]'s <code>extra_headers</code> option
811-
* use <code>ngx_hash_t</code> to optimize the built-in header look-up process for [[#ngx.req.set_header|ngx.req.set_header]], [[#ngx.header.HEADER|ngx.header.HEADER]], and etc.
811+
* use <code>ngx_hash_t</code> to optimize the built-in header look-up process for [[#ngx.req.set_header|ngx.req.set_header]], and etc.
812812
* add <code>ignore_resp_headers</code>, <code>ignore_resp_body</code>, and <code>ignore_resp</code> options to [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] methods, to allow micro performance tuning on the user side.
813813
* add automatic Lua code time slicing support by yielding and resuming the Lua VM actively via Lua's debug hooks.
814814
* add <code>stat</code> mode similar to [https://httpd.apache.org/docs/trunk/mod/mod_lua.html mod_lua].

src/ngx_http_lua_common.h

+2
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ struct ngx_http_lua_main_conf_s {
214214

215215
ngx_int_t lua_thread_cache_max_entries;
216216

217+
ngx_hash_t builtin_headers_out;
218+
217219
#if (NGX_PCRE)
218220
ngx_int_t regex_cache_entries;
219221
ngx_int_t regex_cache_max_entries;

src/ngx_http_lua_headers_out.c

+57-40
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,9 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx,
486486
ngx_str_t key, ngx_str_t value, unsigned override)
487487
{
488488
ngx_http_lua_header_val_t hv;
489-
ngx_http_lua_set_header_t *handlers = ngx_http_lua_set_handlers;
490-
ngx_uint_t i;
489+
ngx_http_lua_main_conf_t *lmcf;
490+
ngx_http_lua_set_header_t *lsh;
491+
ngx_hash_t *hash;
491492

492493
dd("set header value: %.*s", (int) value.len, value.data);
493494

@@ -499,53 +500,25 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx,
499500
return NGX_ERROR;
500501
}
501502

502-
if (value.len > 0) {
503-
hv.hash = ngx_hash_key_lc(key.data, key.len);
504-
505-
} else {
506-
hv.hash = 0;
507-
}
508-
503+
hv.hash = ngx_hash_key_lc(key.data, key.len);
509504
hv.key = key;
510505

511506
hv.offset = 0;
512507
hv.no_override = !override;
513-
hv.handler = NULL;
514-
515-
for (i = 0; handlers[i].name.len; i++) {
516-
if (hv.key.len != handlers[i].name.len
517-
|| ngx_strncasecmp(hv.key.data, handlers[i].name.data,
518-
handlers[i].name.len) != 0)
519-
{
520-
dd("hv key comparison: %s <> %s", handlers[i].name.data,
521-
hv.key.data);
522-
523-
continue;
524-
}
525-
526-
dd("Matched handler: %s %s", handlers[i].name.data, hv.key.data);
527-
528-
hv.offset = handlers[i].offset;
529-
hv.handler = handlers[i].handler;
530-
508+
hv.handler = ngx_http_set_header;
509+
510+
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
511+
hash = &lmcf->builtin_headers_out;
512+
lsh = ngx_http_lua_hash_find_lc(hash, hv.hash, hv.key.data, hv.key.len);
513+
if (lsh) {
514+
dd("Matched handler: %s %s", lsh->name.data, hv.key.data);
515+
hv.offset = lsh->offset;
516+
hv.handler = lsh->handler;
531517
if (hv.handler == ngx_http_set_content_type_header) {
532518
ctx->mime_set = 1;
533519
}
534-
535-
break;
536-
}
537-
538-
if (handlers[i].name.len == 0 && handlers[i].handler) {
539-
hv.offset = handlers[i].offset;
540-
hv.handler = handlers[i].handler;
541520
}
542521

543-
#if 1
544-
if (hv.handler == NULL) {
545-
return NGX_ERROR;
546-
}
547-
#endif
548-
549522
return hv.handler(r, &hv, &value);
550523
}
551524

@@ -658,4 +631,48 @@ ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
658631
return 1;
659632
}
660633

634+
635+
ngx_int_t
636+
ngx_http_lua_init_builtin_headers_out(ngx_conf_t *cf,
637+
ngx_http_lua_main_conf_t *lmcf)
638+
{
639+
ngx_array_t headers;
640+
ngx_hash_key_t *hk;
641+
ngx_hash_init_t hash;
642+
ngx_http_lua_set_header_t *handlers = ngx_http_lua_set_handlers;
643+
ngx_uint_t count;
644+
645+
count = sizeof(ngx_http_lua_set_handlers)
646+
/ sizeof(ngx_http_lua_set_header_t);
647+
648+
if (ngx_array_init(&headers, cf->temp_pool, count, sizeof(ngx_hash_key_t))
649+
!= NGX_OK)
650+
{
651+
return NGX_ERROR;
652+
}
653+
654+
while (handlers->name.data) {
655+
hk = ngx_array_push(&headers);
656+
if (hk == NULL) {
657+
return NGX_ERROR;
658+
}
659+
660+
hk->key = handlers->name;
661+
hk->key_hash = ngx_hash_key_lc(handlers->name.data, handlers->name.len);
662+
hk->value = (void *) handlers;
663+
664+
handlers++;
665+
}
666+
667+
hash.hash = &lmcf->builtin_headers_out;
668+
hash.key = ngx_hash_key_lc;
669+
hash.max_size = 512;
670+
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
671+
hash.name = "builtin_headers_out_hash";
672+
hash.pool = cf->pool;
673+
hash.temp_pool = NULL;
674+
675+
return ngx_hash_init(&hash, headers.elts, headers.nelts);
676+
}
677+
661678
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

src/ngx_http_lua_headers_out.h

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ ngx_int_t ngx_http_lua_set_output_header(ngx_http_request_t *r,
1616
ngx_http_lua_ctx_t *ctx, ngx_str_t key, ngx_str_t value, unsigned override);
1717
int ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
1818
ngx_http_lua_ctx_t *ctx, ngx_str_t *key);
19+
ngx_int_t ngx_http_lua_init_builtin_headers_out(ngx_conf_t *cf,
20+
ngx_http_lua_main_conf_t *lmcf);
1921

2022

2123
#endif /* _NGX_HTTP_LUA_HEADERS_OUT_H_INCLUDED_ */

src/ngx_http_lua_module.c

+10
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "ngx_http_lua_ssl_session_storeby.h"
3232
#include "ngx_http_lua_ssl_session_fetchby.h"
3333
#include "ngx_http_lua_headers.h"
34+
#include "ngx_http_lua_headers_out.h"
3435
#include "ngx_http_lua_pipe.h"
3536

3637

@@ -1086,6 +1087,15 @@ ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf)
10861087
lmcf->worker_thread_vm_pool_size = 100;
10871088
}
10881089

1090+
if (ngx_http_lua_init_builtin_headers_out(cf, lmcf) != NGX_OK) {
1091+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "init header out error");
1092+
1093+
return NGX_CONF_ERROR;
1094+
}
1095+
1096+
dd("init built in headers out hash size: %ld",
1097+
lmcf->builtin_headers_out.size);
1098+
10891099
return NGX_CONF_OK;
10901100
}
10911101

src/ngx_http_lua_util.h

+37
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,43 @@ ngx_http_lua_new_cached_thread(lua_State *L, lua_State **out_co,
685685
}
686686

687687

688+
static ngx_inline void *
689+
ngx_http_lua_hash_find_lc(ngx_hash_t *hash, ngx_uint_t key, u_char *name,
690+
size_t len)
691+
{
692+
ngx_uint_t i;
693+
ngx_hash_elt_t *elt;
694+
695+
elt = hash->buckets[key % hash->size];
696+
697+
if (elt == NULL) {
698+
return NULL;
699+
}
700+
701+
while (elt->value) {
702+
if (len != (size_t) elt->len) {
703+
goto next;
704+
}
705+
706+
for (i = 0; i < len; i++) {
707+
if (ngx_tolower(name[i]) != elt->name[i]) {
708+
goto next;
709+
}
710+
}
711+
712+
return elt->value;
713+
714+
next:
715+
716+
elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len,
717+
sizeof(void *));
718+
continue;
719+
}
720+
721+
return NULL;
722+
}
723+
724+
688725
extern ngx_uint_t ngx_http_lua_location_hash;
689726
extern ngx_uint_t ngx_http_lua_content_length_hash;
690727

0 commit comments

Comments
 (0)