details: https://hg.nginx.org/njs/rev/f5428bc87159 branches: changeset: 2194:f5428bc87159 user: Dmitry Volyntsev <xei...@nginx.com> date: Thu Sep 07 16:12:40 2023 -0700 description: Modules: implemented items() method of a shared dictionary.
diffstat: nginx/ngx_js_shared_dict.c | 120 +++++++++++++++++++++++++++++++++++++++++++++ nginx/t/js_shared_dict.t | 27 +++++++++- 2 files changed, 144 insertions(+), 3 deletions(-) diffs (204 lines): diff -r 5b52293ad769 -r f5428bc87159 nginx/ngx_js_shared_dict.c --- a/nginx/ngx_js_shared_dict.c Thu Sep 07 16:12:31 2023 -0700 +++ b/nginx/ngx_js_shared_dict.c Thu Sep 07 16:12:40 2023 -0700 @@ -64,6 +64,8 @@ static njs_int_t njs_js_ext_shared_dict_ njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_incr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); +static njs_int_t njs_js_ext_shared_dict_items(njs_vm_t *vm, njs_value_t *args, + njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); @@ -186,6 +188,17 @@ static njs_external_t ngx_js_ext_shared { .flags = NJS_EXTERN_METHOD, + .name.string = njs_str("items"), + .writable = 1, + .configurable = 1, + .enumerable = 1, + .u.method = { + .native = njs_js_ext_shared_dict_items, + } + }, + + { + .flags = NJS_EXTERN_METHOD, .name.string = njs_str("get"), .writable = 1, .configurable = 1, @@ -739,6 +752,113 @@ njs_js_ext_shared_dict_incr(njs_vm_t *vm static njs_int_t +njs_js_ext_shared_dict_items(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, + njs_index_t unused, njs_value_t *retval) +{ + njs_int_t rc; + ngx_int_t max_count; + ngx_msec_t now; + ngx_time_t *tp; + njs_value_t *value, *kv; + ngx_rbtree_t *rbtree; + ngx_js_dict_t *dict; + ngx_shm_zone_t *shm_zone; + ngx_rbtree_node_t *rn; + ngx_js_dict_node_t *node; + + shm_zone = njs_vm_external(vm, ngx_js_shared_dict_proto_id, + njs_argument(args, 0)); + if (shm_zone == NULL) { + njs_vm_type_error(vm, "\"this\" is not a shared dict"); + return NJS_ERROR; + } + + dict = shm_zone->data; + + max_count = 1024; + + if (nargs > 1) { + if (ngx_js_integer(vm, njs_arg(args, nargs, 1), &max_count) != NGX_OK) { + return NJS_ERROR; + } + } + + rc = njs_vm_array_alloc(vm, retval, 8); + if (rc != NJS_OK) { + return NJS_ERROR; + } + + ngx_rwlock_rlock(&dict->sh->rwlock); + + if (dict->timeout) { + tp = ngx_timeofday(); + now = tp->sec * 1000 + tp->msec; + ngx_js_dict_expire(dict, now); + } + + rbtree = &dict->sh->rbtree; + + if (rbtree->root == rbtree->sentinel) { + goto done; + } + + for (rn = ngx_rbtree_min(rbtree->root, rbtree->sentinel); + rn != NULL; + rn = ngx_rbtree_next(rbtree, rn)) + { + if (max_count-- == 0) { + break; + } + + node = (ngx_js_dict_node_t *) rn; + + kv = njs_vm_array_push(vm, retval); + if (kv == NULL) { + goto fail; + } + + rc = njs_vm_array_alloc(vm, kv, 2); + if (rc != NJS_OK) { + return NJS_ERROR; + } + + value = njs_vm_array_push(vm, kv); + if (value == NULL) { + goto fail; + } + + rc = njs_vm_value_string_set(vm, value, node->sn.str.data, + node->sn.str.len); + if (rc != NJS_OK) { + goto fail; + } + + value = njs_vm_array_push(vm, kv); + if (value == NULL) { + goto fail; + } + + rc = ngx_js_dict_copy_value_locked(vm, dict, node, value); + if (rc != NJS_OK) { + goto fail; + } + } + +done: + + ngx_rwlock_unlock(&dict->sh->rwlock); + + return NJS_OK; + +fail: + + ngx_rwlock_unlock(&dict->sh->rwlock); + + return NJS_ERROR; +} + + +static njs_int_t njs_js_ext_shared_dict_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { diff -r 5b52293ad769 -r f5428bc87159 nginx/t/js_shared_dict.t --- a/nginx/t/js_shared_dict.t Thu Sep 07 16:12:31 2023 -0700 +++ b/nginx/t/js_shared_dict.t Thu Sep 07 16:12:40 2023 -0700 @@ -86,6 +86,10 @@ http { js_content test.incr; } + location /items { + js_content test.items; + } + location /keys { js_content test.keys; } @@ -208,6 +212,19 @@ EOF r.return(200, `[${ks.toSorted()}]`); } + function items(r) { + var kvs; + + if (r.args.max) { + kvs = ngx.shared[r.args.dict].items(parseInt(r.args.max)); + + } else { + kvs = ngx.shared[r.args.dict].items(); + } + + r.return(200, njs.dump(kvs.toSorted())); + } + function name(r) { r.return(200, ngx.shared[r.args.dict].name); } @@ -247,11 +264,11 @@ EOF } export default { add, capacity, chain, clear, del, free_space, get, has, - incr, keys, name, njs: test_njs, pop, replace, set, size, - zones }; + incr, items, keys, name, njs: test_njs, pop, replace, set, + size, zones }; EOF -$t->try_run('no js_shared_dict_zone')->plan(41); +$t->try_run('no js_shared_dict_zone')->plan(43); ############################################################################### @@ -311,6 +328,10 @@ like(http_get('/keys?dict=foo'), qr/\[]/ like(http_get('/keys?dict=bar'), qr/\[FOO\,FOO2]/, 'bar keys after a delay'); like(http_get('/size?dict=foo'), qr/size: 0/, 'no of items in foo after expire'); +like(http_get('/items?dict=bar'), qr/\[\['FOO','zzz'],\['FOO2','aaa']]/, + 'bar items'); +like(http_get('/items?dict=waka'), + qr/\[\['FOO',47],\['FOO2',7779],\['FOO3',3338]]/, 'waka items'); } _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel