context UPDATE support for storing leafref references (#2155)
* Adding leafref references and API to lyd_node_term
* Adjusted to require context flag
* Extended the utest for tree_data
* Fixed typo in docs
* Refactored based on PR discussion
* Refactored to use hash table for leafref nodes
diff --git a/src/context.c b/src/context.c
index 7a14203..0c41019 100644
--- a/src/context.c
+++ b/src/context.c
@@ -239,6 +239,30 @@
return !memcmp(&err1->tid, &err2->tid, sizeof err1->tid);
}
+/**
+ * @brief Hash table value-equal callback for comparing leafref links hash table record.
+ */
+static ly_bool
+ly_ctx_ht_leafref_links_equal_cb(void *val1_p, void *val2_p, ly_bool UNUSED(mod), void *UNUSED(cb_data))
+{
+ struct lyd_leafref_links_rec *rec1 = val1_p, *rec2 = val2_p;
+
+ return rec1->node == rec2->node;
+}
+
+/**
+ * @brief Callback for freeing leafref links recorcd internal resources.
+ *
+ * @param[in] val_p Pointer to leafref links record
+ */
+static void
+ly_ctx_ht_leafref_links_rec_free(void *val_p)
+{
+ struct lyd_leafref_links_rec *rec = val_p;
+
+ lyd_free_leafref_links_rec(rec);
+}
+
LIBYANG_API_DEF LY_ERR
ly_ctx_new(const char *search_dir, uint16_t options, struct ly_ctx **new_ctx)
{
@@ -262,6 +286,11 @@
/* plugins */
LY_CHECK_ERR_GOTO(lyplg_init(), LOGINT(NULL); rc = LY_EINT, cleanup);
+ if (options & LY_CTX_LEAFREF_LINKING) {
+ ctx->leafref_links_ht = lyht_new(1, sizeof(struct lyd_leafref_links_rec), ly_ctx_ht_leafref_links_equal_cb, NULL, 1);
+ LY_CHECK_ERR_GOTO(!ctx->leafref_links_ht, rc = LY_EMEM, cleanup);
+ }
+
/* initialize thread-specific error hash table */
ctx->err_ht = lyht_new(1, sizeof(struct ly_ctx_err_rec), ly_ctx_ht_err_equal_cb, NULL, 1);
LY_CHECK_ERR_GOTO(!ctx->err_ht, rc = LY_EMEM, cleanup);
@@ -588,6 +617,11 @@
LY_CHECK_ERR_RET((option & LY_CTX_NO_YANGLIBRARY) && !(ctx->flags & LY_CTX_NO_YANGLIBRARY),
LOGARG(ctx, option), LY_EINVAL);
+ if (!(ctx->flags & LY_CTX_LEAFREF_LINKING) && (option & LY_CTX_LEAFREF_LINKING)) {
+ ctx->leafref_links_ht = lyht_new(1, sizeof(struct lyd_leafref_links_rec), ly_ctx_ht_leafref_links_equal_cb, NULL, 1);
+ LY_CHECK_ERR_RET(!ctx->leafref_links_ht, LOGARG(ctx, option), LY_EMEM);
+ }
+
if (!(ctx->flags & LY_CTX_SET_PRIV_PARSED) && (option & LY_CTX_SET_PRIV_PARSED)) {
ctx->flags |= LY_CTX_SET_PRIV_PARSED;
/* recompile the whole context to set the priv pointers */
@@ -628,6 +662,11 @@
LY_CHECK_ARG_RET(ctx, ctx, LY_EINVAL);
LY_CHECK_ERR_RET(option & LY_CTX_NO_YANGLIBRARY, LOGARG(ctx, option), LY_EINVAL);
+ if ((ctx->flags & LY_CTX_LEAFREF_LINKING) && (option & LY_CTX_LEAFREF_LINKING)) {
+ lyht_free(ctx->leafref_links_ht, ly_ctx_ht_leafref_links_rec_free);
+ ctx->leafref_links_ht = NULL;
+ }
+
if ((ctx->flags & LY_CTX_SET_PRIV_PARSED) && (option & LY_CTX_SET_PRIV_PARSED)) {
struct lys_module *mod;
uint32_t index;
@@ -1318,6 +1357,11 @@
/* leftover unres */
lys_unres_glob_erase(&ctx->unres);
+ /* clean the leafref links hash table */
+ if (ctx->leafref_links_ht) {
+ lyht_free(ctx->leafref_links_ht, ly_ctx_ht_leafref_links_rec_free);
+ }
+
/* clean the error hash table */
lyht_free(ctx->err_ht, ly_ctx_ht_err_rec_free);