[njs] Modules: fixed clear() method of a shared dictionary without timeout.

Vadim Zhestikov v.zhestikov at f5.com
Tue Dec 19 20:51:07 UTC 2023


details:   https://hg.nginx.org/njs/rev/4a15613f4e8b
branches:  
changeset: 2250:4a15613f4e8b
user:      Vadim Zhestikov <v.zhestikov at f5.com>
date:      Tue Dec 19 12:37:05 2023 -0800
description:
Modules: fixed clear() method of a shared dictionary without timeout.

This fixes #690 issue on Github.

diffstat:

 nginx/ngx_js_shared_dict.c |  30 +++++++++++++++++++++++++++---
 nginx/t/js_shared_dict.t   |  21 +++++++++++++++++++--
 2 files changed, 46 insertions(+), 5 deletions(-)

diffs (115 lines):

diff -r fc1001f6801b -r 4a15613f4e8b nginx/ngx_js_shared_dict.c
--- a/nginx/ngx_js_shared_dict.c	Thu Dec 14 22:32:02 2023 -0800
+++ b/nginx/ngx_js_shared_dict.c	Tue Dec 19 12:37:05 2023 -0800
@@ -109,6 +109,8 @@ static njs_int_t ngx_js_dict_shared_erro
 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 *v
 
     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);
 
diff -r fc1001f6801b -r 4a15613f4e8b nginx/t/js_shared_dict.t
--- a/nginx/t/js_shared_dict.t	Thu Dec 14 22:32:02 2023 -0800
+++ b/nginx/t/js_shared_dict.t	Tue Dec 19 12:37:05 2023 -0800
@@ -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 @@ 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'), 
 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');
 
 ###############################################################################
 


More information about the nginx-devel mailing list