summaryrefslogtreecommitdiffstats
path: root/src/dict.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-17 02:59:34 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-17 02:59:54 +0000
commit5bc4f4fb5b383ca32b382b6c0d09602346064414 (patch)
treec741e5844c2815679107d648a15841653b9b01a5 /src/dict.c
parentAdding upstream version 3.1.0+dfsg. (diff)
downloadlibyang3-5bc4f4fb5b383ca32b382b6c0d09602346064414.tar.xz
libyang3-5bc4f4fb5b383ca32b382b6c0d09602346064414.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.c55
1 files changed, 48 insertions, 7 deletions
diff --git a/src/dict.c b/src/dict.c
index 9f741a2..ba574c8 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -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;
+}