Skip to content

Commit 39c2ead

Browse files
committed
optimize: improved code cache lookup performance by using 'luaL_ref()' to avoid the costly 'lj_str_new()'.
1 parent bf11f67 commit 39c2ead

16 files changed

+179
-66
lines changed

src/ngx_http_lua_accessby.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ ngx_http_lua_access_handler_inline(ngx_http_request_t *r)
179179
rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
180180
llcf->access_src.value.data,
181181
llcf->access_src.value.len,
182+
&llcf->access_src_ref,
182183
llcf->access_src_key,
183184
(const char *) llcf->access_chunkname);
184185

@@ -217,6 +218,7 @@ ngx_http_lua_access_handler_file(ngx_http_request_t *r)
217218

218219
/* load Lua script file (w/ cache) sp = 1 */
219220
rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path,
221+
&llcf->access_src_ref,
220222
llcf->access_src_key);
221223
if (rc != NGX_OK) {
222224
if (rc < NGX_HTTP_SPECIAL_RESPONSE) {

src/ngx_http_lua_balancer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ ngx_http_lua_balancer_handler_file(ngx_http_request_t *r,
6666

6767
rc = ngx_http_lua_cache_loadfile(r->connection->log, L,
6868
lscf->balancer.src.data,
69+
&lscf->balancer.src_ref,
6970
lscf->balancer.src_key);
7071
if (rc != NGX_OK) {
7172
return rc;
@@ -87,6 +88,7 @@ ngx_http_lua_balancer_handler_inline(ngx_http_request_t *r,
8788
rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
8889
lscf->balancer.src.data,
8990
lscf->balancer.src.len,
91+
&lscf->balancer.src_ref,
9092
lscf->balancer.src_key,
9193
"=balancer_by_lua");
9294
if (rc != NGX_OK) {

src/ngx_http_lua_bodyfilterby.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ ngx_http_lua_body_filter_inline(ngx_http_request_t *r, ngx_chain_t *in)
162162
rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
163163
llcf->body_filter_src.value.data,
164164
llcf->body_filter_src.value.len,
165+
&llcf->body_filter_src_ref,
165166
llcf->body_filter_src_key,
166167
"=body_filter_by_lua");
167168
if (rc != NGX_OK) {
@@ -209,6 +210,7 @@ ngx_http_lua_body_filter_file(ngx_http_request_t *r, ngx_chain_t *in)
209210

210211
/* load Lua script file (w/ cache) sp = 1 */
211212
rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path,
213+
&llcf->body_filter_src_ref,
212214
llcf->body_filter_src_key);
213215
if (rc != NGX_OK) {
214216
return NGX_ERROR;

src/ngx_http_lua_cache.c

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* */
3434
static ngx_int_t
3535
ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
36-
const char *key)
36+
int *ref, const char *key)
3737
{
3838
#ifndef OPENRESTY_LUAJIT
3939
int rc;
@@ -45,16 +45,45 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
4545
code_cache_key));
4646
lua_rawget(L, LUA_REGISTRYINDEX); /* sp++ */
4747

48-
dd("Code cache table to load: %p", lua_topointer(L, -1));
48+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
49+
"code cache lookup (key='%s', ref=%d)", key, *ref);
50+
51+
dd("code cache table to load: %p", lua_topointer(L, -1));
4952

5053
if (!lua_istable(L, -1)) {
5154
dd("Error: code cache table to load did not exist!!");
5255
return NGX_ERROR;
5356
}
5457

55-
lua_getfield(L, -1, key); /* sp++ */
58+
ngx_http_lua_assert(key != NULL);
59+
60+
if (*ref == LUA_NOREF) {
61+
lua_getfield(L, -1, key); /* cache closure */
62+
63+
} else {
64+
if (*ref == LUA_REFNIL) {
65+
lua_getfield(L, -1, key); /* cache ref */
66+
67+
if (!lua_isnumber(L, -1)) {
68+
goto not_found;
69+
}
70+
71+
*ref = lua_tonumber(L, -1);
72+
73+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
74+
"code cache setting ref (key='%s', ref=%d)",
75+
key, *ref);
76+
77+
lua_pop(L, 1); /* cache */
78+
}
79+
80+
lua_rawgeti(L, -1, *ref); /* cache closure */
81+
}
5682

5783
if (lua_isfunction(L, -1)) {
84+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
85+
"code cache hit (key='%s', ref=%d)", key, *ref);
86+
5887
#ifdef OPENRESTY_LUAJIT
5988
lua_remove(L, -2); /* sp-- */
6089
return NGX_OK;
@@ -83,13 +112,18 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
83112
#endif /* OPENRESTY_LUAJIT */
84113
}
85114

115+
not_found:
116+
86117
dd("Value associated with given key in code cache table is not code "
87118
"chunk: stack top=%d, top value type=%s\n",
88119
lua_gettop(L), lua_typename(L, -1));
89120

90121
/* remove cache table and value from stack */
91122
lua_pop(L, 2); /* sp-=2 */
92123

124+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
125+
"code cache miss (key='%s', ref=%d)", key, *ref);
126+
93127
return NGX_DECLINED;
94128
}
95129

@@ -108,7 +142,7 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
108142
*
109143
* */
110144
static ngx_int_t
111-
ngx_http_lua_cache_store_code(lua_State *L, const char *key)
145+
ngx_http_lua_cache_store_code(lua_State *L, int *ref, const char *key)
112146
{
113147
#ifndef OPENRESTY_LUAJIT
114148
int rc;
@@ -126,8 +160,22 @@ ngx_http_lua_cache_store_code(lua_State *L, const char *key)
126160
return NGX_ERROR;
127161
}
128162

163+
ngx_http_lua_assert(key != NULL);
164+
129165
lua_pushvalue(L, -2); /* closure cache closure */
130-
lua_setfield(L, -2, key); /* closure cache */
166+
167+
if (*ref == LUA_NOREF) {
168+
/* cache closure by cache key */
169+
lua_setfield(L, -2, key); /* closure cache */
170+
171+
} else {
172+
/* cache closure with reference */
173+
*ref = luaL_ref(L, -2); /* closure cache */
174+
175+
/* cache reference by cache key */
176+
lua_pushnumber(L, *ref); /* closure cache ref */
177+
lua_setfield(L, -2, key); /* closure cache */
178+
}
131179

132180
/* remove cache table, leave closure factory at top of stack */
133181
lua_pop(L, 1); /* closure */
@@ -147,7 +195,7 @@ ngx_http_lua_cache_store_code(lua_State *L, const char *key)
147195

148196
ngx_int_t
149197
ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
150-
const u_char *src, size_t src_len, const u_char *cache_key,
198+
const u_char *src, size_t src_len, int *cache_ref, const u_char *cache_key,
151199
const char *name)
152200
{
153201
int n;
@@ -156,14 +204,8 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
156204

157205
n = lua_gettop(L);
158206

159-
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
160-
"looking up Lua code cache with key '%s'", cache_key);
161-
162-
rc = ngx_http_lua_cache_load_code(log, L, (char *) cache_key);
207+
rc = ngx_http_lua_cache_load_code(log, L, cache_ref, (char *) cache_key);
163208
if (rc == NGX_OK) {
164-
/* code chunk loaded from cache, sp++ */
165-
dd("Code cache hit! cache key='%s', stack top=%d, script='%.*s'",
166-
cache_key, lua_gettop(L), (int) src_len, src);
167209
return NGX_OK;
168210
}
169211

@@ -173,9 +215,6 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
173215

174216
/* rc == NGX_DECLINED */
175217

176-
dd("Code cache missed! cache key='%s', stack top=%d, script='%.*s'",
177-
cache_key, lua_gettop(L), (int) src_len, src);
178-
179218
/* load closure factory of inline script to the top of lua stack, sp++ */
180219
rc = ngx_http_lua_clfactory_loadbuffer(L, (char *) src, src_len, name);
181220

@@ -198,7 +237,7 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
198237

199238
/* store closure factory and gen new closure at the top of lua stack to
200239
* code cache */
201-
rc = ngx_http_lua_cache_store_code(L, (char *) cache_key);
240+
rc = ngx_http_lua_cache_store_code(L, cache_ref, (char *) cache_key);
202241
if (rc != NGX_OK) {
203242
err = "fail to generate new closure from the closure factory";
204243
goto error;
@@ -217,7 +256,7 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
217256

218257
ngx_int_t
219258
ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
220-
const u_char *script, const u_char *cache_key)
259+
const u_char *script, int *cache_ref, const u_char *cache_key)
221260
{
222261
int n;
223262
ngx_int_t rc, errcode = NGX_ERROR;
@@ -230,25 +269,22 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
230269
/* calculate digest of script file path */
231270
if (cache_key == NULL) {
232271
dd("CACHE file key not pre-calculated...calculating");
233-
p = ngx_copy(buf, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN);
234272

273+
p = ngx_copy(buf, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN);
235274
p = ngx_http_lua_digest_hex(p, script, ngx_strlen(script));
236-
237275
*p = '\0';
276+
238277
cache_key = buf;
278+
*cache_ref = LUA_NOREF;
239279

240280
} else {
241281
dd("CACHE file key already pre-calculated");
242-
}
243282

244-
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
245-
"looking up Lua code cache with key '%s'", cache_key);
283+
ngx_http_lua_assert(cache_ref != NULL && *cache_ref != LUA_NOREF);
284+
}
246285

247-
rc = ngx_http_lua_cache_load_code(log, L, (char *) cache_key);
286+
rc = ngx_http_lua_cache_load_code(log, L, cache_ref, (char *) cache_key);
248287
if (rc == NGX_OK) {
249-
/* code chunk loaded from cache, sp++ */
250-
dd("Code cache hit! cache key='%s', stack top=%d, file path='%s'",
251-
cache_key, lua_gettop(L), script);
252288
return NGX_OK;
253289
}
254290

@@ -258,9 +294,6 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
258294

259295
/* rc == NGX_DECLINED */
260296

261-
dd("Code cache missed! cache key='%s', stack top=%d, file path='%s'",
262-
cache_key, lua_gettop(L), script);
263-
264297
/* load closure factory of script file to the top of lua stack, sp++ */
265298
rc = ngx_http_lua_clfactory_loadfile(L, (char *) script);
266299

@@ -291,7 +324,7 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
291324

292325
/* store closure factory and gen new closure at the top of lua stack
293326
* to code cache */
294-
rc = ngx_http_lua_cache_store_code(L, (char *) cache_key);
327+
rc = ngx_http_lua_cache_store_code(L, cache_ref, (char *) cache_key);
295328
if (rc != NGX_OK) {
296329
err = "fail to generate new closure from the closure factory";
297330
goto error;

src/ngx_http_lua_cache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313

1414

1515
ngx_int_t ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
16-
const u_char *src, size_t src_len, const u_char *cache_key,
16+
const u_char *src, size_t src_len, int *cache_ref, const u_char *cache_key,
1717
const char *name);
1818
ngx_int_t ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
19-
const u_char *script, const u_char *cache_key);
19+
const u_char *script, int *cache_ref, const u_char *cache_key);
2020

2121

2222
#endif /* _NGX_HTTP_LUA_CACHE_H_INCLUDED_ */

src/ngx_http_lua_common.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
#if defined(NDK) && NDK
103103
typedef struct {
104104
size_t size;
105+
int ref;
105106
u_char *key;
106107
ngx_str_t script;
107108
} ngx_http_lua_set_var_data_t;
@@ -281,22 +282,25 @@ union ngx_http_lua_srv_conf_u {
281282
ngx_http_lua_srv_conf_handler_pt ssl_cert_handler;
282283
ngx_str_t ssl_cert_src;
283284
u_char *ssl_cert_src_key;
285+
int ssl_cert_src_ref;
284286

285287
ngx_http_lua_srv_conf_handler_pt ssl_sess_store_handler;
286288
ngx_str_t ssl_sess_store_src;
287289
u_char *ssl_sess_store_src_key;
290+
int ssl_sess_store_src_ref;
288291

289292
ngx_http_lua_srv_conf_handler_pt ssl_sess_fetch_handler;
290293
ngx_str_t ssl_sess_fetch_src;
291294
u_char *ssl_sess_fetch_src_key;
295+
int ssl_sess_fetch_src_ref;
292296
} srv;
293297
#endif
294298

295299
struct {
300+
ngx_http_lua_srv_conf_handler_pt handler;
296301
ngx_str_t src;
297302
u_char *src_key;
298-
299-
ngx_http_lua_srv_conf_handler_pt handler;
303+
int src_ref;
300304
} balancer;
301305
};
302306

@@ -333,38 +337,44 @@ typedef struct {
333337
file path */
334338

335339
u_char *rewrite_src_key; /* cached key for rewrite_src */
340+
int rewrite_src_ref;
336341

337342
u_char *access_chunkname;
338343
ngx_http_complex_value_t access_src; /* access_by_lua
339344
inline script/script
340345
file path */
341346

342347
u_char *access_src_key; /* cached key for access_src */
348+
int access_src_ref;
343349

344350
u_char *content_chunkname;
345351
ngx_http_complex_value_t content_src; /* content_by_lua
346352
inline script/script
347353
file path */
348354

349355
u_char *content_src_key; /* cached key for content_src */
356+
int content_src_ref;
350357

351358

352359
u_char *log_chunkname;
353360
ngx_http_complex_value_t log_src; /* log_by_lua inline script/script
354361
file path */
355362

356363
u_char *log_src_key; /* cached key for log_src */
364+
int log_src_ref;
357365

358366
ngx_http_complex_value_t header_filter_src; /* header_filter_by_lua
359367
inline script/script
360368
file path */
361369

362370
u_char *header_filter_src_key;
363371
/* cached key for header_filter_src */
372+
int header_filter_src_ref;
364373

365374

366375
ngx_http_complex_value_t body_filter_src;
367376
u_char *body_filter_src_key;
377+
int body_filter_src_ref;
368378

369379
ngx_msec_t keepalive_timeout;
370380
ngx_msec_t connect_timeout;

src/ngx_http_lua_contentby.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ ngx_http_lua_content_handler_file(ngx_http_request_t *r)
271271

272272
/* load Lua script file (w/ cache) sp = 1 */
273273
rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path,
274+
&llcf->content_src_ref,
274275
llcf->content_src_key);
275276
if (rc != NGX_OK) {
276277
if (rc < NGX_HTTP_SPECIAL_RESPONSE) {
@@ -302,6 +303,7 @@ ngx_http_lua_content_handler_inline(ngx_http_request_t *r)
302303
rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
303304
llcf->content_src.value.data,
304305
llcf->content_src.value.len,
306+
&llcf->content_src_ref,
305307
llcf->content_src_key,
306308
(const char *)
307309
llcf->content_chunkname);

src/ngx_http_lua_directive.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ ngx_http_lua_set_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
278278
}
279279

280280
filter_data->key = p;
281+
filter_data->ref = LUA_REFNIL;
281282

282283
p = ngx_copy(p, "set_by_lua", sizeof("set_by_lua") - 1);
283284
p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
@@ -361,6 +362,7 @@ ngx_http_lua_filter_set_by_lua_inline(ngx_http_request_t *r, ngx_str_t *val,
361362
rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
362363
filter_data->script.data,
363364
filter_data->script.len,
365+
&filter_data->ref,
364366
filter_data->key, "=set_by_lua");
365367
if (rc != NGX_OK) {
366368
return NGX_ERROR;
@@ -413,6 +415,7 @@ ngx_http_lua_filter_set_by_lua_file(ngx_http_request_t *r, ngx_str_t *val,
413415

414416
/* load Lua script file (w/ cache) sp = 1 */
415417
rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path,
418+
&filter_data->ref,
416419
filter_data->key);
417420
if (rc != NGX_OK) {
418421
return NGX_ERROR;

0 commit comments

Comments
 (0)