Skip to content

Commit 12a535a

Browse files
committed
feature: add an option init arg in ffi shdict.incr
1 parent b2aa910 commit 12a535a

File tree

1 file changed

+125
-4
lines changed

1 file changed

+125
-4
lines changed

src/ngx_http_lua_shdict.c

Lines changed: 125 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,16 +1923,26 @@ ngx_http_lua_ffi_shdict_get(ngx_shm_zone_t *zone, u_char *key,
19231923

19241924
int
19251925
ngx_http_lua_ffi_shdict_incr(ngx_shm_zone_t *zone, u_char *key,
1926-
size_t key_len, double *value, char **err)
1926+
size_t key_len, double *value, char **err, int arg_num, double init,
1927+
int *forcible)
19271928
{
1929+
int i, n;
19281930
uint32_t hash;
19291931
ngx_int_t rc;
19301932
ngx_http_lua_shdict_ctx_t *ctx;
19311933
ngx_http_lua_shdict_node_t *sd;
19321934
double num;
1935+
ngx_rbtree_node_t *node;
19331936
u_char *p;
19341937

1938+
if (zone == NULL) {
1939+
return NGX_ERROR;
1940+
}
1941+
19351942
ctx = zone->data;
1943+
1944+
*forcible = 0;
1945+
19361946
hash = ngx_crc32_short(key, key_len);
19371947

19381948
dd("looking up key %.*s in shared dict %.*s", (int) key_len, key,
@@ -1947,9 +1957,35 @@ ngx_http_lua_ffi_shdict_incr(ngx_shm_zone_t *zone, u_char *key,
19471957
dd("shdict lookup returned %d", (int) rc);
19481958

19491959
if (rc == NGX_DECLINED || rc == NGX_DONE) {
1950-
ngx_shmtx_unlock(&ctx->shpool->mutex);
1951-
*err = "not found";
1952-
return NGX_ERROR;
1960+
if (arg_num == 0) {
1961+
ngx_shmtx_unlock(&ctx->shpool->mutex);
1962+
*err = "not found";
1963+
return NGX_ERROR;
1964+
}
1965+
1966+
/* add value */
1967+
num = *value + init;
1968+
1969+
if (rc == NGX_DONE) {
1970+
1971+
if ((size_t) sd->value_len == sizeof(double)) {
1972+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1973+
"lua shared dict incr: found old entry and value "
1974+
"size matched, reusing it");
1975+
1976+
ngx_queue_remove(&sd->queue);
1977+
ngx_queue_insert_head(&ctx->sh->queue, &sd->queue);
1978+
1979+
dd("go to setvalue");
1980+
goto setvalue;
1981+
}
1982+
1983+
dd("go to remove");
1984+
goto remove;
1985+
}
1986+
1987+
dd("go to insert");
1988+
goto insert;
19531989
}
19541990

19551991
/* rc == NGX_OK */
@@ -1974,6 +2010,91 @@ ngx_http_lua_ffi_shdict_incr(ngx_shm_zone_t *zone, u_char *key,
19742010

19752011
ngx_shmtx_unlock(&ctx->shpool->mutex);
19762012

2013+
*value = num;
2014+
return NGX_OK;
2015+
2016+
remove:
2017+
2018+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
2019+
"lua shared dict incr: found old entry but value size "
2020+
"NOT matched, removing it first");
2021+
2022+
ngx_queue_remove(&sd->queue);
2023+
2024+
node = (ngx_rbtree_node_t *)
2025+
((u_char *) sd - offsetof(ngx_rbtree_node_t, color));
2026+
2027+
ngx_rbtree_delete(&ctx->sh->rbtree, node);
2028+
2029+
ngx_slab_free_locked(ctx->shpool, node);
2030+
2031+
insert:
2032+
2033+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
2034+
"lua shared dict incr: creating a new entry");
2035+
2036+
n = offsetof(ngx_rbtree_node_t, color)
2037+
+ offsetof(ngx_http_lua_shdict_node_t, data)
2038+
+ key_len
2039+
+ sizeof(double);
2040+
2041+
node = ngx_slab_alloc_locked(ctx->shpool, n);
2042+
2043+
if (node == NULL) {
2044+
2045+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
2046+
"lua shared dict incr: overriding non-expired items "
2047+
"due to memory shortage for entry \"%*s\"", key_len,
2048+
key);
2049+
2050+
for (i = 0; i < 30; i++) {
2051+
if (ngx_http_lua_shdict_expire(ctx, 0) == 0) {
2052+
break;
2053+
}
2054+
2055+
*forcible = 1;
2056+
2057+
node = ngx_slab_alloc_locked(ctx->shpool, n);
2058+
if (node != NULL) {
2059+
goto allocated;
2060+
}
2061+
}
2062+
2063+
ngx_shmtx_unlock(&ctx->shpool->mutex);
2064+
2065+
*err = "no memory";
2066+
return NGX_ERROR;
2067+
}
2068+
2069+
allocated:
2070+
2071+
sd = (ngx_http_lua_shdict_node_t *) &node->color;
2072+
2073+
node->key = hash;
2074+
2075+
sd->key_len = (u_short) key_len;
2076+
2077+
sd->value_len = (uint32_t) sizeof(double);
2078+
2079+
ngx_rbtree_insert(&ctx->sh->rbtree, node);
2080+
2081+
ngx_queue_insert_head(&ctx->sh->queue, &sd->queue);
2082+
2083+
setvalue:
2084+
2085+
sd->user_flags = 0;
2086+
2087+
sd->expires = 0;
2088+
2089+
dd("setting value type to %d", LUA_TNUMBER);
2090+
2091+
sd->value_type = (uint8_t) LUA_TNUMBER;
2092+
2093+
p = ngx_copy(sd->data, key, key_len);
2094+
ngx_memcpy(p, (double *) &num, sizeof(double));
2095+
2096+
ngx_shmtx_unlock(&ctx->shpool->mutex);
2097+
19772098
*value = num;
19782099
return NGX_OK;
19792100
}

0 commit comments

Comments
 (0)