@@ -1923,16 +1923,26 @@ ngx_http_lua_ffi_shdict_get(ngx_shm_zone_t *zone, u_char *key,
1923
1923
1924
1924
int
1925
1925
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 )
1927
1928
{
1929
+ int i , n ;
1928
1930
uint32_t hash ;
1929
1931
ngx_int_t rc ;
1930
1932
ngx_http_lua_shdict_ctx_t * ctx ;
1931
1933
ngx_http_lua_shdict_node_t * sd ;
1932
1934
double num ;
1935
+ ngx_rbtree_node_t * node ;
1933
1936
u_char * p ;
1934
1937
1938
+ if (zone == NULL ) {
1939
+ return NGX_ERROR ;
1940
+ }
1941
+
1935
1942
ctx = zone -> data ;
1943
+
1944
+ * forcible = 0 ;
1945
+
1936
1946
hash = ngx_crc32_short (key , key_len );
1937
1947
1938
1948
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,
1947
1957
dd ("shdict lookup returned %d" , (int ) rc );
1948
1958
1949
1959
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 ;
1953
1989
}
1954
1990
1955
1991
/* rc == NGX_OK */
@@ -1974,6 +2010,91 @@ ngx_http_lua_ffi_shdict_incr(ngx_shm_zone_t *zone, u_char *key,
1974
2010
1975
2011
ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1976
2012
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
+
1977
2098
* value = num ;
1978
2099
return NGX_OK ;
1979
2100
}
0 commit comments