From 0d3b29b7b37e7a7a0cf0201494d974e0fe1f24de Mon Sep 17 00:00:00 2001 From: Qi Date: Wed, 31 Jan 2024 16:24:52 +0800 Subject: [PATCH] perf(router): remove NYI to be more JIT-friendly --- changelog/unreleased/kong/speed_up_router.yml | 3 + kong/router/fields.lua | 103 ++++++++++-------- 2 files changed, 60 insertions(+), 46 deletions(-) create mode 100644 changelog/unreleased/kong/speed_up_router.yml diff --git a/changelog/unreleased/kong/speed_up_router.yml b/changelog/unreleased/kong/speed_up_router.yml new file mode 100644 index 000000000000..c6d1b5fab9ab --- /dev/null +++ b/changelog/unreleased/kong/speed_up_router.yml @@ -0,0 +1,3 @@ +message: Speed up the router matching when the `router_flavor` is `traditional_compatible` or `expressions`. +type: performance +scope: Performance diff --git a/kong/router/fields.lua b/kong/router/fields.lua index 40dd85609f7f..d970e74b187a 100644 --- a/kong/router/fields.lua +++ b/kong/router/fields.lua @@ -261,56 +261,29 @@ if is_http then return params end + local function gen_http_headers_field_accessor(name) + return function(params) + if not params.headers then + params.headers = get_http_params(get_headers, "headers", "lua_max_req_headers") + end - get_field_accessor = function(funcs, field) - local f = FIELDS_FUNCS[field] or funcs[field] - if f then - return f + return params.headers[name] end + end - local prefix = field:sub(1, PREFIX_LEN) - - -- generate for http.headers.* - - if prefix == HTTP_HEADERS_PREFIX then - local name = field:sub(PREFIX_LEN + 1) - - f = function(params) - if not params.headers then - params.headers = get_http_params(get_headers, "headers", "lua_max_req_headers") - end - - return params.headers[name] - end -- f - - funcs[field] = f - return f - end -- if prefix == HTTP_HEADERS_PREFIX - - -- generate for http.queries.* - - if prefix == HTTP_QUERIES_PREFIX then - local name = field:sub(PREFIX_LEN + 1) - - f = function(params) - if not params.queries then - params.queries = get_http_params(get_uri_args, "queries", "lua_max_uri_args") - end - - return params.queries[name] - end -- f - - funcs[field] = f - return f - end -- if prefix == HTTP_QUERIES_PREFIX - - -- generate for http.path.segments.* + local function gen_http_queries_field_accessor(name) + return function(params) + if not params.queries then + params.queries = get_http_params(get_uri_args, "queries", "lua_max_uri_args") + end - if field:sub(1, HTTP_SEGMENTS_PREFIX_LEN) == HTTP_SEGMENTS_PREFIX then - local range = field:sub(HTTP_SEGMENTS_PREFIX_LEN + 1) + return params.queries[name] + end + end - f = function(params) - local segments = get_http_segments(params) + local function gen_http_segments_field_accessor(range) + return function(params) + local segments = get_http_segments(params) local value = segments[range] @@ -359,9 +332,47 @@ if is_http then segments[range] = value return value - end -- f + end + end + + get_field_accessor = function(funcs, field) + local f = FIELDS_FUNCS[field] or funcs[field] + if f then + return f + end + local prefix = field:sub(1, PREFIX_LEN) + + -- generate for http.headers.* + + if prefix == HTTP_HEADERS_PREFIX then + local name = field:sub(PREFIX_LEN + 1) + + f = gen_http_headers_field_accessor(name) funcs[field] = f + + return f + end -- if prefix == HTTP_HEADERS_PREFIX + + -- generate for http.queries.* + + if prefix == HTTP_QUERIES_PREFIX then + local name = field:sub(PREFIX_LEN + 1) + + f = gen_http_queries_field_accessor(name) + funcs[field] = f + + return f + end -- if prefix == HTTP_QUERIES_PREFIX + + -- generate for http.path.segments.* + + if field:sub(1, HTTP_SEGMENTS_PREFIX_LEN) == HTTP_SEGMENTS_PREFIX then + local range = field:sub(HTTP_SEGMENTS_PREFIX_LEN + 1) + + f = gen_http_segments_field_accessor(range) + funcs[field] = f + return f end -- if field:sub(1, HTTP_SEGMENTS_PREFIX_LEN)