Skip to content

Commit d86e1c6

Browse files
committed
feature: implemented shdict:lindex method.
1 parent ee47e55 commit d86e1c6

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed

README.markdown

+21
Original file line numberDiff line numberDiff line change
@@ -3185,6 +3185,7 @@ Nginx API for Lua
31853185
* [ngx.shared.DICT.lpop](#ngxshareddictlpop)
31863186
* [ngx.shared.DICT.rpop](#ngxshareddictrpop)
31873187
* [ngx.shared.DICT.llen](#ngxshareddictllen)
3188+
* [ngx.shared.DICT.lindex](#ngxshareddictlindex)
31883189
* [ngx.shared.DICT.ttl](#ngxshareddictttl)
31893190
* [ngx.shared.DICT.expire](#ngxshareddictexpire)
31903191
* [ngx.shared.DICT.flush_all](#ngxshareddictflush_all)
@@ -6235,6 +6236,7 @@ The resulting object `dict` has the following methods:
62356236
* [lpop](#ngxshareddictlpop)
62366237
* [rpop](#ngxshareddictrpop)
62376238
* [llen](#ngxshareddictllen)
6239+
* [lindex](#ngxshareddictlindex)
62386240
* [ttl](#ngxshareddictttl)
62396241
* [expire](#ngxshareddictexpire)
62406242
* [flush_all](#ngxshareddictflush_all)
@@ -6607,6 +6609,25 @@ See also [ngx.shared.DICT](#ngxshareddict).
66076609

66086610
[Back to TOC](#nginx-api-for-lua)
66096611

6612+
ngx.shared.DICT.lindex
6613+
----------------------
6614+
6615+
**syntax:** *val, err = ngx.shared.DICT:lindex(key, index)*
6616+
6617+
**context:** *init_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua**
6618+
6619+
Returns the element which at the index `index` of the list named `key` in the shm-base dictionary [ngx.shared.DICT](#ngxshareddict).
6620+
6621+
The index is zero-based, so `0` means the first element, `1` for the second element and so forth. Also, negative index can be used to designate elements starting at the tail of the list, here `-1` means the last element and `-2` means the penultimate and so on.
6622+
6623+
If `key` does not exist or `index` is out of the list bound, it will return `nil`. When the `key` already takes a value that is not a list, it will return `nil` and `"value not a list"`.
6624+
6625+
**Note:** This method requires the `resty.core.shdict` or `resty.core` modules from the [lua-resty-core](https://github.com/openresty/lua-resty-core) library.
6626+
6627+
See also [ngx.shared.DICT](#ngxshareddict).
6628+
6629+
[Back to TOC](#nginx-api-for-lua)
6630+
66106631
ngx.shared.DICT.ttl
66116632
-------------------
66126633
**syntax:** *ttl, err = ngx.shared.DICT:ttl(key)*

doc/HttpLuaModule.wiki

+17
Original file line numberDiff line numberDiff line change
@@ -5232,6 +5232,7 @@ The resulting object <code>dict</code> has the following methods:
52325232
* [[#ngx.shared.DICT.lpop|lpop]]
52335233
* [[#ngx.shared.DICT.rpop|rpop]]
52345234
* [[#ngx.shared.DICT.llen|llen]]
5235+
* [[#ngx.shared.DICT.lindex|lindex]]
52355236
* [[#ngx.shared.DICT.ttl|ttl]]
52365237
* [[#ngx.shared.DICT.expire|expire]]
52375238
* [[#ngx.shared.DICT.flush_all|flush_all]]
@@ -5553,6 +5554,22 @@ This feature was first introduced in the <code>v0.10.6</code> release.
55535554
55545555
See also [[#ngx.shared.DICT|ngx.shared.DICT]].
55555556
5557+
== ngx.shared.DICT.lindex ==
5558+
5559+
'''syntax:''' ''val, err = ngx.shared.DICT:lindex(key, index)''
5560+
5561+
'''context:''' ''init_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*''
5562+
5563+
Returns the element which at the index <code>index</code> of the list named <code>key</code> in the shm-base dictionary [[#ngx.shared.DICT|ngx.shared.DICT]].
5564+
5565+
The index is zero-based, so <code>0</code> means the first element, <code>1</code> for the second element and so forth. Also, negative index can be used to designate elements starting at the tail of the list, here <code>-1</code> means the last element and <code>-2</code> means the penultimate and so on.
5566+
5567+
If <code>key</code> does not exist or <code>index</code> is out of the list bound, it will return <code>nil</code>. When the <code>key</code> already takes a value that is not a list, it will return <code>nil</code> and <code>"value not a list"</code>.
5568+
5569+
'''Note:''' This method requires the <code>resty.core.shdict</code> or <code>resty.core</code> modules from the [https://github.com/openresty/lua-resty-core lua-resty-core] library.
5570+
5571+
See also [[#ngx.shared.DICT|ngx.shared.DICT]].
5572+
55565573
== ngx.shared.DICT.ttl ==
55575574
'''syntax:''' ''ttl, err = ngx.shared.DICT:ttl(key)''
55585575

src/ngx_http_lua_shdict.c

+133
Original file line numberDiff line numberDiff line change
@@ -3021,6 +3021,139 @@ ngx_http_lua_ffi_shdict_free_space(ngx_shm_zone_t *zone)
30213021
# endif /* nginx_version >= 1011007 */
30223022

30233023

3024+
int
3025+
ngx_http_lua_ffi_shdict_lindex(ngx_shm_zone_t *zone, u_char *key,
3026+
size_t key_len, int *value_type, u_char **str_value_buf,
3027+
size_t *str_value_len, double *num_value, int index, char **err)
3028+
{
3029+
int i;
3030+
uint32_t hash;
3031+
ngx_int_t rc;
3032+
ngx_str_t name, value;
3033+
ngx_queue_t *queue;
3034+
ngx_http_lua_shdict_ctx_t *ctx;
3035+
ngx_http_lua_shdict_node_t *sd;
3036+
ngx_http_lua_shdict_list_node_t *lnode;
3037+
3038+
ctx = zone->data;
3039+
name = ctx->name;
3040+
3041+
hash = ngx_crc32_short(key, key_len);
3042+
3043+
ngx_shmtx_lock(&ctx->shpool->mutex);
3044+
3045+
#if 1
3046+
ngx_http_lua_shdict_expire(ctx, 1);
3047+
#endif
3048+
3049+
rc = ngx_http_lua_shdict_lookup(zone, hash, key, key_len, &sd);
3050+
3051+
dd("shdict lookup returned %d", (int) rc);
3052+
3053+
if (rc == NGX_DECLINED || rc == NGX_DONE) {
3054+
ngx_shmtx_unlock(&ctx->shpool->mutex);
3055+
3056+
*value_type = LUA_TNIL;
3057+
return NGX_OK;
3058+
}
3059+
3060+
/* rc == NGX_OK */
3061+
3062+
if (sd->value_type != SHDICT_TLIST) {
3063+
ngx_shmtx_unlock(&ctx->shpool->mutex);
3064+
3065+
*err = "value not a list";
3066+
return NGX_ERROR;
3067+
}
3068+
3069+
ngx_queue_remove(&sd->queue);
3070+
ngx_queue_insert_head(&ctx->sh->lru_queue, &sd->queue);
3071+
3072+
if (index >= (int) sd->value_len || -index > (int) sd->value_len) {
3073+
ngx_shmtx_unlock(&ctx->shpool->mutex);
3074+
3075+
*value_type = LUA_TNIL;
3076+
return NGX_OK;
3077+
}
3078+
3079+
queue = ngx_http_lua_shdict_get_list_head(sd, key_len);
3080+
3081+
if (index >= 0) { /* forward */
3082+
3083+
for (i = 0; i <= index; i++) {
3084+
queue = ngx_queue_next(queue);
3085+
}
3086+
3087+
} else { /* backward */
3088+
3089+
for (i = -1; i >= index; i--) {
3090+
queue = ngx_queue_prev(queue);
3091+
}
3092+
}
3093+
3094+
lnode = ngx_queue_data(queue, ngx_http_lua_shdict_list_node_t, queue);
3095+
3096+
*value_type = lnode->value_type;
3097+
3098+
dd("data: %p", lnode->data);
3099+
dd("value len: %d", (int) lnode->value_len);
3100+
3101+
value.data = lnode->data;
3102+
value.len = (size_t) lnode->value_len;
3103+
3104+
if (*str_value_len < (size_t) value.len) {
3105+
if (*value_type == SHDICT_TSTRING) {
3106+
*str_value_buf = malloc(value.len);
3107+
if (*str_value_buf == NULL) {
3108+
ngx_shmtx_unlock(&ctx->shpool->mutex);
3109+
return NGX_ERROR;
3110+
}
3111+
}
3112+
}
3113+
3114+
switch (*value_type) {
3115+
3116+
case SHDICT_TSTRING:
3117+
*str_value_len = value.len;
3118+
ngx_memcpy(*str_value_buf, lnode->data, value.len);
3119+
break;
3120+
3121+
case SHDICT_TNUMBER:
3122+
3123+
if (value.len != sizeof(double)) {
3124+
ngx_shmtx_unlock(&ctx->shpool->mutex);
3125+
3126+
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
3127+
"bad lua list node number value size found "
3128+
"for key %*s in shared_dict %V: %z",
3129+
key_len, key, &name, value.len);
3130+
3131+
return NGX_ERROR;
3132+
}
3133+
3134+
*str_value_len = value.len;
3135+
ngx_memcpy(num_value, value.data, sizeof(double));
3136+
3137+
break;
3138+
3139+
default:
3140+
3141+
ngx_shmtx_unlock(&ctx->shpool->mutex);
3142+
3143+
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
3144+
"bad list node value type found "
3145+
"for key %*s in shared_dict %V: %d",
3146+
key_len, key, &name, *value_type);
3147+
3148+
return NGX_ERROR;
3149+
}
3150+
3151+
ngx_shmtx_unlock(&ctx->shpool->mutex);
3152+
3153+
return NGX_OK;
3154+
}
3155+
3156+
30243157
#endif /* NGX_LUA_NO_FFI_API */
30253158

30263159

0 commit comments

Comments
 (0)