]> git.kaiwu.me - njs.git/commitdiff
Modules: fixed clear() method of a shared dictionary without timeout.
authorVadim Zhestikov <v.zhestikov@f5.com>
Tue, 19 Dec 2023 20:37:05 +0000 (12:37 -0800)
committerVadim Zhestikov <v.zhestikov@f5.com>
Tue, 19 Dec 2023 20:37:05 +0000 (12:37 -0800)
This fixes #690 issue on Github.

nginx/ngx_js_shared_dict.c
nginx/t/js_shared_dict.t

index e9acd9f7e8d490292a3d141264b57b525389d703..66227428f355450711cd183abed01f788d9b63a6 100644 (file)
@@ -109,6 +109,8 @@ static njs_int_t ngx_js_dict_shared_error_name(njs_vm_t *vm,
 static ngx_int_t ngx_js_dict_init_zone(ngx_shm_zone_t *shm_zone, void *data);
 static njs_int_t ngx_js_shared_dict_preinit(njs_vm_t *vm);
 static njs_int_t ngx_js_shared_dict_init(njs_vm_t *vm);
+static void ngx_js_dict_node_free(ngx_js_dict_t *dict,
+    ngx_js_dict_node_t *node);
 
 
 static njs_external_t  ngx_js_ext_shared_dict[] = {
@@ -454,8 +456,10 @@ static njs_int_t
 njs_js_ext_shared_dict_clear(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    ngx_js_dict_t   *dict;
-    ngx_shm_zone_t  *shm_zone;
+    ngx_rbtree_t       *rbtree;
+    ngx_js_dict_t      *dict;
+    ngx_shm_zone_t     *shm_zone;
+    ngx_rbtree_node_t  *rn, *next;
 
     shm_zone = njs_vm_external(vm, ngx_js_shared_dict_proto_id,
                                njs_argument(args, 0));
@@ -468,7 +472,27 @@ njs_js_ext_shared_dict_clear(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     ngx_rwlock_wlock(&dict->sh->rwlock);
 
-    ngx_js_dict_evict(dict, 0x7fffffff /* INT_MAX */);
+    if (dict->timeout) {
+        ngx_js_dict_evict(dict, 0x7fffffff /* INT_MAX */);
+
+    } else {
+        rbtree = &dict->sh->rbtree;
+
+        if (rbtree->root == rbtree->sentinel) {
+            return NJS_OK;
+        }
+
+        for (rn = ngx_rbtree_min(rbtree->root, rbtree->sentinel);
+             rn != NULL;
+             rn = next)
+        {
+            next = ngx_rbtree_next(rbtree, rn);
+
+            ngx_rbtree_delete(rbtree, rn);
+
+            ngx_js_dict_node_free(dict, (ngx_js_dict_node_t *) rn);
+        }
+    }
 
     ngx_rwlock_unlock(&dict->sh->rwlock);
 
index 1cf794ce093903a120bc17ac7a21a1e98db77f21..bfa45c60e75811a1d2b7625005c0b1fb0afef6fa 100644 (file)
@@ -41,6 +41,7 @@ http {
     js_shared_dict_zone zone=foo:32k timeout=2s evict;
     js_shared_dict_zone zone=bar:64k type=string;
     js_shared_dict_zone zone=waka:32k type=number;
+    js_shared_dict_zone zone=no_timeout:32k;
 
     server {
         listen       127.0.0.1:8080;
@@ -110,6 +111,10 @@ http {
             js_content test.set;
         }
 
+        location /set_clear {
+            js_content test.set_clear;
+        }
+
         location /size {
             js_content test.size;
         }
@@ -259,16 +264,25 @@ $t->write_file('test.js', <<'EOF');
         r.return(200, `size: ${dict.size()}`);
     }
 
+    function set_clear(r) {
+        var dict = ngx.shared.no_timeout;
+        dict.set("test", "test value");
+        dict.set("test1", "test1 value");
+        dict.clear();
+        r.return(200, `size: ${dict.size()}`);
+    }
+
+
     function zones(r) {
         r.return(200, Object.keys(ngx.shared).sort());
     }
 
     export default { add, capacity, chain, clear, del, free_space, get, has,
                      incr, items, keys, name, njs: test_njs, pop, replace, set,
-                     size, zones };
+                     set_clear, size, zones };
 EOF
 
-$t->try_run('no js_shared_dict_zone')->plan(43);
+$t->try_run('no js_shared_dict_zone')->plan(44);
 
 ###############################################################################
 
@@ -339,7 +353,10 @@ like(http_get('/pop?dict=bar&key=FOO'), qr/zzz/, 'pop bar.FOO');
 like(http_get('/pop?dict=bar&key=FOO'), qr/undefined/, 'pop deleted bar.FOO');
 http_get('/set?dict=foo&key=BAR&value=xxx');
 like(http_get('/clear?dict=foo'), qr/undefined/, 'clear foo');
+
 like(http_get('/size?dict=foo'), qr/size: 0/, 'no of items in foo after clear');
+like(http_get('/set_clear'), qr/size: 0/,
+       'no of items in no_timeout after clear');
 
 ###############################################################################