diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-17 02:59:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-17 02:59:54 +0000 |
commit | 5bc4f4fb5b383ca32b382b6c0d09602346064414 (patch) | |
tree | c741e5844c2815679107d648a15841653b9b01a5 /src/dict.c | |
parent | Adding upstream version 3.1.0+dfsg. (diff) | |
download | libyang3-upstream.tar.xz libyang3-upstream.zip |
Adding upstream version 3.4.2+dfsg.upstream/3.4.2+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/dict.c')
-rw-r--r-- | src/dict.c | 55 |
1 files changed, 48 insertions, 7 deletions
@@ -104,9 +104,6 @@ lydict_resize_val_eq(void *val1_p, void *val2_p, ly_bool mod, void *UNUSED(cb_da str1 = ((struct ly_dict_rec *)val1_p)->value; str2 = ((struct ly_dict_rec *)val2_p)->value; - LY_CHECK_ERR_RET(!str1, LOGARG(NULL, val1_p), 0); - LY_CHECK_ERR_RET(!str2, LOGARG(NULL, val2_p), 0); - if (mod) { /* used when inserting new values */ if (strcmp(str1, str2) == 0) { @@ -177,7 +174,7 @@ finish: return ret; } -LY_ERR +static LY_ERR dict_insert(const struct ly_ctx *ctx, char *value, size_t len, ly_bool zerocopy, const char **str_p) { LY_ERR ret = LY_SUCCESS; @@ -221,9 +218,7 @@ dict_insert(const struct ly_ctx *ctx, char *value, size_t len, ly_bool zerocopy, return ret; } - if (str_p) { - *str_p = match->value; - } + *str_p = match->value; return ret; } @@ -269,3 +264,49 @@ lydict_insert_zc(const struct ly_ctx *ctx, char *value, const char **str_p) return result; } + +static LY_ERR +dict_dup(const struct ly_ctx *ctx, char *value, const char **str_p) +{ + LY_ERR ret = LY_SUCCESS; + struct ly_dict_rec *match = NULL, rec; + uint32_t hash; + + /* set new callback to only compare memory addresses */ + lyht_value_equal_cb prev = lyht_set_cb(ctx->dict.hash_tab, lydict_resize_val_eq); + + LOGDBG(LY_LDGDICT, "duplicating %s", value); + hash = lyht_hash(value, strlen(value)); + rec.value = value; + + ret = lyht_find(ctx->dict.hash_tab, (void *)&rec, hash, (void **)&match); + if (ret == LY_SUCCESS) { + /* record found, increase refcount */ + match->refcount++; + *str_p = match->value; + } + + /* restore callback */ + lyht_set_cb(ctx->dict.hash_tab, prev); + + return ret; +} + +LIBYANG_API_DEF LY_ERR +lydict_dup(const struct ly_ctx *ctx, const char *value, const char **str_p) +{ + LY_ERR result; + + LY_CHECK_ARG_RET(ctx, ctx, str_p, LY_EINVAL); + + if (!value) { + *str_p = NULL; + return LY_SUCCESS; + } + + pthread_mutex_lock((pthread_mutex_t *)&ctx->dict.lock); + result = dict_dup(ctx, (char *)value, str_p); + pthread_mutex_unlock((pthread_mutex_t *)&ctx->dict.lock); + + return result; +} |