details: https://github.com/nginx/njs/commit/bc3b91cda9497717ebd1c150f53e4a37e88b3958 branches: master commit: bc3b91cda9497717ebd1c150f53e4a37e88b3958 user: Dmitry Volyntsev <xei...@nginx.com> date: Thu, 15 May 2025 17:24:25 -0700 description: Modules: engine independent method to add entries to a shared dict.
--- nginx/ngx_js_shared_dict.c | 157 +++++++++++++++++++++------------------------ 1 file changed, 74 insertions(+), 83 deletions(-) diff --git a/nginx/ngx_js_shared_dict.c b/nginx/ngx_js_shared_dict.c index d4db87d5..0a35241f 100644 --- a/nginx/ngx_js_shared_dict.c +++ b/nginx/ngx_js_shared_dict.c @@ -21,16 +21,6 @@ typedef struct { } ngx_js_dict_sh_t; -typedef struct { - ngx_str_node_t sn; - ngx_rbtree_node_t expire; - union { - ngx_str_t value; - double number; - } u; -} ngx_js_dict_node_t; - - struct ngx_js_dict_s { ngx_shm_zone_t *shm_zone; ngx_js_dict_sh_t *sh; @@ -46,6 +36,19 @@ struct ngx_js_dict_s { }; +typedef union { + ngx_str_t str; /* NGX_JS_DICT_TYPE_STRING */ + double number; /* NGX_JS_DICT_TYPE_NUMBER */ +} ngx_js_dict_value_t; + + +typedef struct { + ngx_str_node_t sn; + ngx_rbtree_node_t expire; + ngx_js_dict_value_t value; +} ngx_js_dict_node_t; + + static njs_int_t njs_js_ext_shared_dict_capacity(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); @@ -1281,7 +1284,7 @@ ngx_js_dict_node_free(ngx_js_dict_t *dict, ngx_js_dict_node_t *node) shpool = dict->shpool; if (dict->type == NGX_JS_DICT_TYPE_STRING) { - ngx_slab_free_locked(shpool, node->u.value.data); + ngx_slab_free_locked(shpool, node->value.str.data); } ngx_slab_free_locked(shpool, node); @@ -1341,12 +1344,11 @@ memory_error: static ngx_int_t -ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_str_t *key, - njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now) +ngx_js_dict_add_value(ngx_js_dict_t *dict, ngx_str_t *key, + ngx_js_dict_value_t *value, ngx_msec_t timeout, ngx_msec_t now) { size_t n; uint32_t hash; - njs_str_t string; ngx_js_dict_node_t *node; if (dict->timeout) { @@ -1364,18 +1366,17 @@ ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_str_t *key, node->sn.str.data = (u_char *) node + sizeof(ngx_js_dict_node_t); if (dict->type == NGX_JS_DICT_TYPE_STRING) { - njs_value_string_get(vm, value, &string); - node->u.value.data = ngx_js_dict_alloc(dict, string.length); - if (node->u.value.data == NULL) { + node->value.str.data = ngx_js_dict_alloc(dict, value->str.len); + if (node->value.str.data == NULL) { ngx_slab_free_locked(dict->shpool, node); return NGX_ERROR; } - ngx_memcpy(node->u.value.data, string.start, string.length); - node->u.value.len = string.length; + ngx_memcpy(node->value.str.data, value->str.data, value->str.len); + node->value.str.len = value->str.len; } else { - node->u.number = njs_value_number(value); + node->value.number = value->number; } node->sn.node.key = hash; @@ -1394,6 +1395,29 @@ ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_str_t *key, } +static ngx_int_t +ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_str_t *key, + njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now) +{ + njs_str_t string; + ngx_js_dict_value_t entry; + + if (dict->type == NGX_JS_DICT_TYPE_STRING) { + njs_value_string_get(vm, value, &string); + + entry.str.data = string.start; + entry.str.len = string.length; + + } else { + /* GCC complains about uninitialized entry.str.data. */ + entry.str.data = NULL; + entry.number = njs_value_number(value); + } + + return ngx_js_dict_add_value(dict, key, &entry, timeout, now); +} + + static ngx_int_t ngx_js_dict_update(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_js_dict_node_t *node, njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now) @@ -1409,14 +1433,14 @@ ngx_js_dict_update(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_js_dict_node_t *node, return NGX_ERROR; } - ngx_slab_free_locked(dict->shpool, node->u.value.data); + ngx_slab_free_locked(dict->shpool, node->value.str.data); ngx_memcpy(p, string.start, string.length); - node->u.value.data = p; - node->u.value.len = string.length; + node->value.str.data = p; + node->value.str.len = string.length; } else { - node->u.number = njs_value_number(value); + node->value.number = njs_value_number(value); } if (dict->timeout) { @@ -1502,8 +1526,8 @@ ngx_js_dict_incr(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_str_t *key, *value = njs_value_number(init); } else { - node->u.number += njs_value_number(delta); - *value = node->u.number; + node->value.number += njs_value_number(delta); + *value = node->value.number; if (dict->timeout) { ngx_rbtree_delete(&dict->sh->rbtree_expire, &node->expire); @@ -1568,14 +1592,14 @@ ngx_js_dict_copy_value_locked(njs_vm_t *vm, ngx_js_dict_t *dict, type = dict->type; if (type == NGX_JS_DICT_TYPE_STRING) { - ret = njs_vm_value_string_create(vm, retval, node->u.value.data, - node->u.value.len); + ret = njs_vm_value_string_create(vm, retval, node->value.str.data, + node->value.str.len); if (ret != NJS_OK) { return NGX_ERROR; } } else { - njs_value_number_set(retval, node->u.number); + njs_value_number_set(retval, node->value.number); } return NGX_OK; @@ -2625,13 +2649,13 @@ ngx_qjs_dict_copy_value_locked(JSContext *cx, ngx_js_dict_t *dict, ngx_js_dict_node_t *node) { if (dict->type == NGX_JS_DICT_TYPE_STRING) { - return JS_NewStringLen(cx, (const char *) node->u.value.data, - node->u.value.len); + return JS_NewStringLen(cx, (const char *) node->value.str.data, + node->value.str.len); } /* NGX_JS_DICT_TYPE_NUMBER */ - return JS_NewFloat64(cx, node->u.number); + return JS_NewFloat64(cx, node->value.number); } @@ -2653,64 +2677,31 @@ static ngx_int_t ngx_qjs_dict_add(JSContext *cx, ngx_js_dict_t *dict, ngx_str_t *key, JSValue value, ngx_msec_t timeout, ngx_msec_t now) { - size_t n; - uint32_t hash; - ngx_str_t string; - ngx_js_dict_node_t *node; - - if (dict->timeout) { - ngx_js_dict_expire(dict, now); - } - - n = sizeof(ngx_js_dict_node_t) + key->len; - hash = ngx_crc32_long(key->data, key->len); - - node = ngx_js_dict_alloc(dict, n); - if (node == NULL) { - return NGX_ERROR; - } - - node->sn.str.data = (u_char *) node + sizeof(ngx_js_dict_node_t); + ngx_int_t rc; + ngx_js_dict_value_t entry; if (dict->type == NGX_JS_DICT_TYPE_STRING) { - string.data = (u_char *) JS_ToCStringLen(cx, &string.len, value); - if (string.data == NULL) { - ngx_slab_free_locked(dict->shpool, node); - return NGX_ERROR; - } - - node->u.value.data = ngx_js_dict_alloc(dict, string.len); - if (node->u.value.data == NULL) { - ngx_slab_free_locked(dict->shpool, node); - JS_FreeCString(cx, (char *) string.data); + entry.str.data = (u_char *) JS_ToCStringLen(cx, &entry.str.len, value); + if (entry.str.data == NULL) { return NGX_ERROR; } - ngx_memcpy(node->u.value.data, string.data, string.len); - node->u.value.len = string.len; - - JS_FreeCString(cx, (char *) string.data); - } else { - if (JS_ToFloat64(cx, &node->u.number, value) < 0) { - ngx_slab_free_locked(dict->shpool, node); + /* GCC complains about uninitialized entry.str.data. */ + entry.str.data = NULL; + + if (JS_ToFloat64(cx, &entry.number, value) < 0) { return NGX_ERROR; } } - node->sn.node.key = hash; + rc = ngx_js_dict_add_value(dict, key, &entry, timeout, now); - ngx_memcpy(node->sn.str.data, key->data, key->len); - node->sn.str.len = key->len; - - ngx_rbtree_insert(&dict->sh->rbtree, &node->sn.node); - - if (dict->timeout) { - node->expire.key = now + timeout; - ngx_rbtree_insert(&dict->sh->rbtree_expire, &node->expire); + if (dict->type == NGX_JS_DICT_TYPE_STRING) { + JS_FreeCString(cx, (char *) entry.str.data); } - return NGX_OK; + return rc; } @@ -2824,8 +2815,8 @@ ngx_qjs_dict_incr(JSContext *cx, ngx_js_dict_t *dict, ngx_str_t *key, } } else { - node->u.number += delta; - value = JS_NewFloat64(cx, node->u.number); + node->value.number += delta; + value = JS_NewFloat64(cx, node->value.number); if (dict->timeout) { ngx_rbtree_delete(&dict->sh->rbtree_expire, &node->expire); @@ -2912,16 +2903,16 @@ ngx_qjs_dict_update(JSContext *cx, ngx_js_dict_t *dict, return NGX_ERROR; } - ngx_slab_free_locked(dict->shpool, node->u.value.data); + ngx_slab_free_locked(dict->shpool, node->value.str.data); ngx_memcpy(p, string.data, string.len); - node->u.value.data = p; - node->u.value.len = string.len; + node->value.str.data = p; + node->value.str.len = string.len; JS_FreeCString(cx, (char *) string.data); } else { - if (JS_ToFloat64(cx, &node->u.number, value) < 0) { + if (JS_ToFloat64(cx, &node->value.number, value) < 0) { return NGX_ERROR; } } _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel