tree data REFACTOR recursive default node creation
Avoid multiple schema/data tree traversals when
creating default nodes.
diff --git a/src/tree_data_new.c b/src/tree_data_new.c
index 1ecc9f3..cd5d63b 100644
--- a/src/tree_data_new.c
+++ b/src/tree_data_new.c
@@ -1876,7 +1876,7 @@
}
LY_ERR
-lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
+lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
const struct lys_module *mod, struct ly_set *node_when, struct ly_set *node_types, struct ly_set *ext_node,
uint32_t impl_opts, struct lyd_node **diff)
{
@@ -1910,12 +1910,12 @@
node = lys_getnext_data(NULL, *first, NULL, iter, NULL);
if (!node && ((struct lysc_node_choice *)iter)->dflt) {
/* create default case data */
- LY_CHECK_RET(lyd_new_implicit_r(parent, first, &((struct lysc_node_choice *)iter)->dflt->node,
+ LY_CHECK_RET(lyd_new_implicit(parent, first, &((struct lysc_node_choice *)iter)->dflt->node,
NULL, node_when, node_types, ext_node, impl_opts, diff));
} else if (node) {
/* create any default data in the existing case */
assert(node->schema->parent->nodetype == LYS_CASE);
- LY_CHECK_RET(lyd_new_implicit_r(parent, first, node->schema->parent, NULL, node_when, node_types,
+ LY_CHECK_RET(lyd_new_implicit(parent, first, node->schema->parent, NULL, node_when, node_types,
ext_node, impl_opts, diff));
}
break;
@@ -1938,10 +1938,6 @@
/* add into diff */
LY_CHECK_RET(lyd_val_diff_add(node, LYD_DIFF_OP_CREATE, diff));
}
-
- /* create any default children */
- LY_CHECK_RET(lyd_new_implicit_r(node, lyd_node_child_p(node), NULL, NULL, node_when, node_types,
- ext_node, impl_opts, diff));
}
break;
case LYS_LEAF:
@@ -2016,6 +2012,28 @@
return LY_SUCCESS;
}
+LY_ERR
+lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
+ const struct lys_module *mod, struct ly_set *node_when, struct ly_set *node_types, struct ly_set *ext_node,
+ uint32_t impl_opts, struct lyd_node **diff)
+{
+ struct lyd_node *child;
+
+ /* parent children */
+ LY_CHECK_RET(lyd_new_implicit(parent, first, sparent, mod, node_when, node_types, ext_node,
+ impl_opts, diff));
+
+ LY_LIST_FOR(parent ? lyd_child_no_keys(parent) : *first, child) {
+ /* recursively for all the containers */
+ if ((child->flags & LYD_DEFAULT) && (child->schema->nodetype == LYS_CONTAINER)) {
+ LY_CHECK_RET(lyd_new_implicit_r(child, lyd_node_child_p(child), NULL, mod, node_when, node_types, ext_node,
+ impl_opts, diff));
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
LIBYANG_API_DEF LY_ERR
lyd_new_implicit_tree(struct lyd_node *tree, uint32_t implicit_options, struct lyd_node **diff)
{
@@ -2030,7 +2048,7 @@
LYD_TREE_DFS_BEGIN(tree, node) {
if (node->schema && (node->schema->nodetype & LYD_NODE_INNER)) {
- LY_CHECK_GOTO(ret = lyd_new_implicit_r(node, lyd_node_child_p(node), NULL, NULL, &node_when, NULL,
+ LY_CHECK_GOTO(ret = lyd_new_implicit(node, lyd_node_child_p(node), NULL, NULL, &node_when, NULL,
NULL, implicit_options, diff), cleanup);
}
@@ -2105,14 +2123,14 @@
}
/* add all top-level defaults for this module */
- LY_CHECK_GOTO(ret = lyd_new_implicit_r(NULL, tree, NULL, module, &node_when, NULL, NULL, implicit_options, diff),
+ LY_CHECK_GOTO(ret = lyd_new_implicit(NULL, tree, NULL, module, &node_when, NULL, NULL, implicit_options, diff),
cleanup);
/* resolve when and remove any invalid defaults */
LY_CHECK_GOTO(ret = lyd_validate_unres(tree, module, 0, &node_when, LYXP_IGNORE_WHEN, NULL, NULL, NULL, NULL,
0, diff), cleanup);
- /* process nested nodes */
+ /* process top-level (and nested) nodes */
LY_LIST_FOR(*tree, root) {
LY_CHECK_GOTO(ret = lyd_new_implicit_tree(root, implicit_options, diff ? &d : NULL), cleanup);