tree data OPTIMIZE diff and lyd_insert_node()
Function lyd_insert_node() has new options that ignore the ordering of
data nodes. This is used in lyd_diff_add() because the diff as such
does not need to be sorted.
diff --git a/src/diff.c b/src/diff.c
index 14d3bb6..1e74704 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -366,7 +366,7 @@
dup = diff_parent;
} else {
- diff_opts = LYD_DUP_NO_META | LYD_DUP_WITH_PARENTS | LYD_DUP_WITH_FLAGS;
+ diff_opts = LYD_DUP_NO_META | LYD_DUP_WITH_PARENTS | LYD_DUP_WITH_FLAGS | LYD_DUP_NO_LYDS;
if ((op != LYD_DIFF_OP_REPLACE) || !lysc_is_userordered(node->schema) || (node->schema->flags & LYS_CONFIG_R)) {
/* move applies only to the user-ordered list, no descendants */
diff_opts |= LYD_DUP_RECURSIVE;
diff --git a/src/parser_json.c b/src/parser_json.c
index 6d22be7..95d689a 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1073,7 +1073,8 @@
/* continue with the next instance */
LY_CHECK_GOTO(ret = lyjson_ctx_next(lydctx->jsonctx, status_inner_p), cleanup);
assert(*node_p);
- lydjson_maintain_children(parent, first_p, node_p, lydctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0, NULL);
+ lydjson_maintain_children(parent, first_p, node_p,
+ lydctx->parse_opts & LYD_PARSE_ORDERED ? LYD_INSERT_NODE_LAST : LYD_INSERT_NODE_DEFAULT, NULL);
LOG_LOCBACK(0, 1);
@@ -1742,7 +1743,8 @@
}
LY_DPARSER_ERR_GOTO(r, rc = r, lydctx, cleanup);
- lydjson_maintain_children(parent, first_p, &node, lydctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0, ext);
+ lydjson_maintain_children(parent, first_p, &node,
+ lydctx->parse_opts & LYD_PARSE_ORDERED ? LYD_INSERT_NODE_LAST : LYD_INSERT_NODE_DEFAULT, ext);
/* move after the item(s) */
r = lyjson_ctx_next(lydctx->jsonctx, &status);
@@ -1780,7 +1782,8 @@
}
/* finally connect the parsed node, is zeroed */
- lydjson_maintain_children(parent, first_p, &node, lydctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0, ext);
+ lydjson_maintain_children(parent, first_p, &node,
+ lydctx->parse_opts & LYD_PARSE_ORDERED ? LYD_INSERT_NODE_LAST : LYD_INSERT_NODE_DEFAULT, ext);
if (!parse_subtree) {
/* move after the item(s) */
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index 119b6f4..3ef1c4b 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -931,7 +931,8 @@
if (parent && (LYD_CTX(parent) != LYD_CTX(node))) {
lyplg_ext_insert(parent, node);
} else {
- lyd_insert_node(parent, first_p, node, lybctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0);
+ lyd_insert_node(parent, first_p, node,
+ lybctx->parse_opts & LYD_PARSE_ORDERED ? LYD_INSERT_NODE_LAST : LYD_INSERT_NODE_DEFAULT);
}
while (!parent && (*first_p)->prev->next) {
*first_p = (*first_p)->prev;
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 02c6be6..0db10ca 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -1121,7 +1121,8 @@
r = lyplg_ext_insert(parent, node);
LY_CHECK_ERR_GOTO(r, rc = r; lyd_free_tree(node), cleanup);
} else {
- lyd_insert_node(parent, first_p, node, lydctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0);
+ lyd_insert_node(parent, first_p, node,
+ lydctx->parse_opts & LYD_PARSE_ORDERED ? LYD_INSERT_NODE_LAST : LYD_INSERT_NODE_DEFAULT);
}
while (!parent && (*first_p)->prev->next) {
*first_p = (*first_p)->prev;
@@ -1349,7 +1350,7 @@
r = lydxml_envelope(xmlctx, "action", "urn:ietf:params:xml:ns:yang:1", 0, &child);
if (r == LY_SUCCESS) {
/* insert */
- lyd_insert_node(*envp, NULL, child, 0);
+ lyd_insert_node(*envp, NULL, child, LYD_INSERT_NODE_DEFAULT);
/* NETCONF action */
*int_opts = LYD_INTOPT_NO_SIBLINGS | LYD_INTOPT_ACTION;
@@ -1438,7 +1439,7 @@
}
/* insert */
- lyd_insert_node(parent, NULL, node, 1);
+ lyd_insert_node(parent, NULL, node, LYD_INSERT_NODE_LAST);
/* update the value */
opaq = (struct lyd_node_opaq *)node;
@@ -1572,7 +1573,7 @@
LY_CHECK_GOTO(r = lyxml_ctx_next(xmlctx), error);
/* insert */
- lyd_insert_node(parent, NULL, child, 1);
+ lyd_insert_node(parent, NULL, child, LYD_INSERT_NODE_LAST);
}
return LY_SUCCESS;
@@ -1747,7 +1748,7 @@
LY_CHECK_GOTO(r = lyxml_ctx_next(xmlctx), error);
/* insert */
- lyd_insert_node(parent, NULL, child, 1);
+ lyd_insert_node(parent, NULL, child, LYD_INSERT_NODE_LAST);
}
return LY_SUCCESS;
@@ -1791,7 +1792,7 @@
r = lydxml_envelope(xmlctx, "ok", "urn:ietf:params:xml:ns:netconf:base:1.0", 0, &child);
if (r == LY_SUCCESS) {
/* insert */
- lyd_insert_node(*envp, NULL, child, 1);
+ lyd_insert_node(*envp, NULL, child, LYD_INSERT_NODE_LAST);
/* finish child parsing */
if (xmlctx->status != LYXML_ELEM_CLOSE) {
@@ -1822,7 +1823,7 @@
}
/* insert */
- lyd_insert_node(*envp, NULL, child, 1);
+ lyd_insert_node(*envp, NULL, child, LYD_INSERT_NODE_LAST);
/* parse all children of "rpc-error" */
LY_CHECK_GOTO(rc = lydxml_env_netconf_rpc_reply_error(xmlctx, child), cleanup);
diff --git a/src/tree_data.c b/src/tree_data.c
index 5ff1715..9d9f286 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -707,13 +707,6 @@
assert(first_sibling && node);
if (*first_sibling) {
-#ifndef NDEBUG
- if (lyds_is_supported(node) && ((*first_sibling)->prev->schema == node->schema) &&
- (lyds_compare_single((*first_sibling)->prev, node) > 0)) {
- LOGWRN(LYD_CTX(node), "Data in \"%s\" are not sorted, inserted node should not be added to the end.",
- node->schema->name);
- }
-#endif
lyd_insert_after_node(first_sibling, (*first_sibling)->prev, node);
} else if (parent) {
lyd_insert_only_child(parent, node);
@@ -739,7 +732,7 @@
}
void
-lyd_insert_node(struct lyd_node *parent, struct lyd_node **first_sibling_p, struct lyd_node *node, ly_bool last)
+lyd_insert_node(struct lyd_node *parent, struct lyd_node **first_sibling_p, struct lyd_node *node, uint32_t order)
{
LY_ERR ret = LY_SUCCESS;
struct lyd_node *first_sibling, *leader;
@@ -754,8 +747,10 @@
}
first_sibling = parent ? lyd_child(parent) : *first_sibling_p;
- if (last) {
+ if (order == LYD_INSERT_NODE_LAST) {
lyd_insert_node_last(parent, &first_sibling, node);
+ } else if (order == LYD_INSERT_NODE_LAST_BY_SCHEMA) {
+ lyd_insert_node_ordby_schema(parent, &first_sibling, node);
} else if (lyds_is_supported(node) &&
(lyd_find_sibling_schema(first_sibling, node->schema, &leader) == LY_SUCCESS)) {
ret = lyds_insert(&first_sibling, &leader, node);
@@ -784,6 +779,14 @@
if (first_sibling_p) {
*first_sibling_p = first_sibling;
}
+
+#ifndef NDEBUG
+ if ((order == LYD_INSERT_NODE_LAST) && lyds_is_supported(node) &&
+ (node->prev->schema == node->schema) && (lyds_compare_single(node->prev, node) > 0)) {
+ LOGWRN(LYD_CTX(node), "Data in \"%s\" are not sorted, inserted node should not be added to the end.",
+ node->schema->name);
+ }
+#endif
}
/**
@@ -1032,7 +1035,7 @@
if (node->parent || node->prev->next || !node->next) {
LY_CHECK_RET(lyd_unlink_tree(node));
- lyd_insert_node(parent, NULL, node, 0);
+ lyd_insert_node(parent, NULL, node, LYD_INSERT_NODE_DEFAULT);
} else {
LY_CHECK_RET(lyd_move_nodes(parent, NULL, node));
}
@@ -1056,7 +1059,7 @@
while (first) {
iter = first->next;
lyd_unlink(first);
- lyd_insert_node(parent, NULL, first, 1);
+ lyd_insert_node(parent, NULL, first, LYD_INSERT_NODE_LAST);
first = iter;
}
return LY_SUCCESS;
@@ -1076,7 +1079,7 @@
first_sibling = lyd_first_sibling(sibling);
if (node->parent || node->prev->next || !node->next) {
LY_CHECK_RET(lyd_unlink_tree(node));
- lyd_insert_node(NULL, &first_sibling, node, 0);
+ lyd_insert_node(NULL, &first_sibling, node, LYD_INSERT_NODE_DEFAULT);
} else {
LY_CHECK_RET(lyd_move_nodes(NULL, &first_sibling, node));
}
@@ -2001,15 +2004,14 @@
* @param[in] node Node to duplicate.
* @param[in] trg_ctx Target context for duplicated nodes.
* @param[in] parent Parent to insert into, NULL for top-level sibling.
- * @param[in] insert_last Whether the duplicated node can be inserted as the last child of @p parent. Set for
- * recursive duplication as an optimization.
+ * @param[in] insert_order Options for inserting (sorting) duplicated node, @ref insertorder.
* @param[in,out] first First sibling, NULL if no top-level sibling exist yet. Can be also NULL if @p parent is set.
* @param[in] options Bitmask of options flags, see @ref dupoptions.
* @param[out] dup_p Pointer where the created duplicated node is placed (besides connecting it to @p parent / @p first).
* @return LY_ERR value.
*/
static LY_ERR
-lyd_dup_r(const struct lyd_node *node, const struct ly_ctx *trg_ctx, struct lyd_node *parent, ly_bool insert_last,
+lyd_dup_r(const struct lyd_node *node, const struct ly_ctx *trg_ctx, struct lyd_node *parent, uint32_t insert_order,
struct lyd_node **first, uint32_t options, struct lyd_node **dup_p)
{
LY_ERR ret;
@@ -2103,7 +2105,7 @@
if (options & LYD_DUP_RECURSIVE) {
/* duplicate all the children */
LY_LIST_FOR(orig->child, child) {
- LY_CHECK_GOTO(ret = lyd_dup_r(child, trg_ctx, dup, 1, NULL, options, NULL), error);
+ LY_CHECK_GOTO(ret = lyd_dup_r(child, trg_ctx, dup, LYD_INSERT_NODE_LAST, NULL, options, NULL), error);
}
}
LY_CHECK_GOTO(ret = lydict_insert(trg_ctx, orig->name.name, 0, &opaq->name.name), error);
@@ -2139,12 +2141,12 @@
if (options & LYD_DUP_RECURSIVE) {
/* duplicate all the children */
LY_LIST_FOR(orig->child, child) {
- LY_CHECK_GOTO(ret = lyd_dup_r(child, trg_ctx, dup, 1, NULL, options, NULL), error);
+ LY_CHECK_GOTO(ret = lyd_dup_r(child, trg_ctx, dup, LYD_INSERT_NODE_LAST, NULL, options, NULL), error);
}
} else if ((dup->schema->nodetype == LYS_LIST) && !(dup->schema->flags & LYS_KEYLESS)) {
/* always duplicate keys of a list */
for (child = orig->child; child && lysc_is_key(child->schema); child = child->next) {
- LY_CHECK_GOTO(ret = lyd_dup_r(child, trg_ctx, dup, 1, NULL, options, NULL), error);
+ LY_CHECK_GOTO(ret = lyd_dup_r(child, trg_ctx, dup, LYD_INSERT_NODE_LAST, NULL, options, NULL), error);
}
}
lyd_hash(dup);
@@ -2155,7 +2157,7 @@
}
/* insert */
- lyd_insert_node(parent, first, dup, insert_last);
+ lyd_insert_node(parent, first, dup, insert_order);
if (dup_p) {
*dup_p = dup;
@@ -2208,11 +2210,11 @@
repeat = 0;
} else {
iter = NULL;
- LY_CHECK_RET(lyd_dup_r(orig_parent, trg_ctx, NULL, 0, &iter, options, &iter));
+ LY_CHECK_RET(lyd_dup_r(orig_parent, trg_ctx, NULL, LYD_INSERT_NODE_DEFAULT, &iter, options, &iter));
/* insert into the previous duplicated parent */
if (*dup_parent) {
- lyd_insert_node(iter, NULL, *dup_parent, 0);
+ lyd_insert_node(iter, NULL, *dup_parent, LYD_INSERT_NODE_DEFAULT);
}
/* update the last duplicated parent */
@@ -2238,7 +2240,7 @@
if (*dup_parent && parent) {
/* last insert into a prevously-existing parent */
- lyd_insert_node(parent, NULL, *dup_parent, 0);
+ lyd_insert_node(parent, NULL, *dup_parent, LYD_INSERT_NODE_DEFAULT);
}
return LY_SUCCESS;
}
@@ -2271,12 +2273,14 @@
} else {
assert(!(options & LYD_DUP_WITH_PARENTS));
/* duplicating a single key, okay, I suppose... */
- rc = lyd_dup_r(orig, trg_ctx, NULL, 0, &first, options, first ? NULL : &first);
+ rc = lyd_dup_r(orig, trg_ctx, NULL, LYD_INSERT_NODE_DEFAULT, &first, options, first ? NULL : &first);
LY_CHECK_GOTO(rc, error);
}
} else {
/* if there is no local parent, it will be inserted into first */
- rc = lyd_dup_r(orig, trg_ctx, local_parent, 0, &first, options, first ? NULL : &first);
+ rc = lyd_dup_r(orig, trg_ctx, local_parent,
+ options & LYD_DUP_NO_LYDS ? LYD_INSERT_NODE_LAST_BY_SCHEMA : LYD_INSERT_NODE_DEFAULT,
+ &first, options, first ? NULL : &first);
LY_CHECK_GOTO(rc, error);
}
if (nosiblings) {
@@ -2568,7 +2572,7 @@
lyds_insert2(parent_trg, first_trg, leader_p, dup_src, lyds);
} else {
/* generic insert node */
- lyd_insert_node(parent_trg, first_trg, dup_src, 0);
+ lyd_insert_node(parent_trg, first_trg, dup_src, LYD_INSERT_NODE_DEFAULT);
}
if (first_inst) {
diff --git a/src/tree_data.h b/src/tree_data.h
index 2319655..a7ce4bf 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -2039,6 +2039,10 @@
#define LYD_DUP_NO_EXT 0x10 /**< Do not duplicate nodes with the ::LYD_EXT flag (nested extension instance data). */
#define LYD_DUP_WITH_PRIV 0x20 /**< Also copy data node private pointer. Only the pointer is copied, it still points
to the same data. */
+#define LYD_DUP_NO_LYDS 0x40 /**< The order of nodes is used the same as for copied nodes and a 'lyds_tree' is not
+ created, so the flag is suitable for optimization. If a new node is inserted into
+ such a (leaf-)list by default, the 'lyds_tree' will be created additionally and
+ the sorting will work. */
/** @} dupoptions */
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index 19fb859..57ec2c4 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -391,15 +391,34 @@
void lyd_insert_before_node(struct lyd_node *sibling, struct lyd_node *node);
/**
+ * @defgroup insertorder Data insert order.
+ *
+ * Various options for optimal node insertion.
+ * Flags that cause the order of nodes not to be checked are adapted to fast insertion but can cause
+ * nodes for (leaf-)lists with LYS_ORDBY_SYSTEM flag set to be out of order, which is an undesirable state,
+ * so these flags must be set carefully. In such exceptional cases, (leaf-)list instances may remain unsorted,
+ * in which case inserting a new node causes sorting to be invoked.
+ * @{
+ */
+
+#define LYD_INSERT_NODE_DEFAULT 0x00 /**< Default behavior. Node is inserted to preserve order. */
+#define LYD_INSERT_NODE_LAST 0x01 /**< Node inserted as last sibling. Node ordering is checked only
+ in Debug build, to detect misuse of the LYD_PARSE_ORDERED flag. */
+#define LYD_INSERT_NODE_LAST_BY_SCHEMA 0x02 /**< The node is inserted according to the schema as a last instance.
+ Node order not checked. */
+
+/** @} insertorder */
+
+/**
* @brief Insert a node into parent/siblings. Order and hashes are fully handled.
*
* @param[in] parent Parent to insert into, NULL for top-level sibling.
* @param[in,out] first_sibling First sibling, NULL if no top-level sibling exist yet. Can be also NULL if @p parent is set.
* @param[in] node Individual node (without siblings) to insert.
- * @param[in] last If set, do not search for the correct anchor but always insert at the end. Setting the flag can
- * break the ordering of nodes for (leaf-)lists that have the LYS_ORDBY_SYSTEM flag set.
+ * @param[in] order Options for inserting (sorting) the node (@ref insertorder).
*/
-void lyd_insert_node(struct lyd_node *parent, struct lyd_node **first_sibling, struct lyd_node *node, ly_bool last);
+void lyd_insert_node(struct lyd_node *parent, struct lyd_node **first_sibling, struct lyd_node *node,
+ uint32_t order);
/**
* @brief Insert a node into parent/siblings, either before the 'anchor' or as the last sibling.
diff --git a/src/tree_data_new.c b/src/tree_data_new.c
index 289d2da..bbe59f2 100644
--- a/src/tree_data_new.c
+++ b/src/tree_data_new.c
@@ -179,7 +179,7 @@
memset(&val, 0, sizeof val);
}
LY_CHECK_GOTO(ret, cleanup);
- lyd_insert_node(list, NULL, key, 0);
+ lyd_insert_node(list, NULL, key, LYD_INSERT_NODE_DEFAULT);
}
/* hash having all the keys */
@@ -503,7 +503,7 @@
ret->flags |= LYD_EXT;
}
if (parent) {
- lyd_insert_node(parent, NULL, ret, 0);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_DEFAULT);
}
if (node) {
@@ -626,11 +626,11 @@
rc = lyd_create_term(key_s, key_val, key_len, 0, NULL, format, NULL, LYD_HINT_DATA, NULL, &key);
LY_CHECK_GOTO(rc, cleanup);
- lyd_insert_node(ret, NULL, key, 1);
+ lyd_insert_node(ret, NULL, key, LYD_INSERT_NODE_LAST);
}
if (parent) {
- lyd_insert_node(parent, NULL, ret, 0);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_DEFAULT);
}
cleanup:
@@ -722,7 +722,7 @@
rc = lyd_create_term(key_s, key_val, key_val ? strlen(key_val) : 0, 0, NULL, LY_VALUE_JSON, NULL, LYD_HINT_DATA,
NULL, &key);
LY_CHECK_GOTO(rc, cleanup);
- lyd_insert_node(ret, NULL, key, 1);
+ lyd_insert_node(ret, NULL, key, LYD_INSERT_NODE_LAST);
}
cleanup:
@@ -775,7 +775,7 @@
ret->flags |= LYD_EXT;
}
if (parent) {
- lyd_insert_node(parent, NULL, ret, 0);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_DEFAULT);
}
if (node) {
@@ -829,11 +829,11 @@
rc = lyd_create_term(key_s, key_val, key_len, 0, NULL, format, NULL, LYD_HINT_DATA, NULL, &key);
LY_CHECK_GOTO(rc, cleanup);
- lyd_insert_node(ret, NULL, key, 1);
+ lyd_insert_node(ret, NULL, key, LYD_INSERT_NODE_LAST);
}
if (parent) {
- lyd_insert_node(parent, NULL, ret, 0);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_DEFAULT);
}
cleanup:
@@ -911,7 +911,7 @@
ret->flags |= LYD_EXT;
}
if (parent) {
- lyd_insert_node(parent, NULL, ret, 0);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_DEFAULT);
}
if (node) {
@@ -1001,7 +1001,7 @@
ret->flags |= LYD_EXT;
}
if (parent) {
- lyd_insert_node(parent, NULL, ret, 0);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_DEFAULT);
}
if (node) {
@@ -1140,7 +1140,7 @@
LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), prefix, prefix ? strlen(prefix) : 0, module_name,
strlen(module_name), value, strlen(value), NULL, LY_VALUE_JSON, NULL, 0, &ret));
if (parent) {
- lyd_insert_node(parent, NULL, ret, 1);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_LAST);
}
if (node) {
@@ -1168,7 +1168,7 @@
LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), prefix, prefix ? strlen(prefix) : 0, module_ns,
strlen(module_ns), value, strlen(value), NULL, LY_VALUE_XML, NULL, 0, &ret));
if (parent) {
- lyd_insert_node(parent, NULL, ret, 1);
+ lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_LAST);
}
if (node) {
@@ -1309,7 +1309,7 @@
term->value.realtype->plugin->free(LYD_CTX(term), &term->value);
term->value = *val;
/* reinserting */
- lyd_insert_node(NULL, &first, target, 0);
+ lyd_insert_node(NULL, &first, target, LYD_INSERT_NODE_DEFAULT);
} else {
/* unlink hash */
lyd_unlink_hash(target);
@@ -1835,10 +1835,10 @@
}
if (cur_parent) {
/* connect to the parent */
- lyd_insert_node(cur_parent, NULL, node, 0);
+ lyd_insert_node(cur_parent, NULL, node, LYD_INSERT_NODE_DEFAULT);
} else if (parent) {
/* connect to top-level siblings */
- lyd_insert_node(NULL, &parent, node, 0);
+ lyd_insert_node(NULL, &parent, node, LYD_INSERT_NODE_DEFAULT);
}
next_iter:
@@ -1956,7 +1956,7 @@
/* create default NP container */
LY_CHECK_RET(lyd_create_inner(iter, &node));
node->flags = LYD_DEFAULT | (lysc_has_when(iter) ? LYD_WHEN_TRUE : 0);
- lyd_insert_node(parent, first, node, 0);
+ lyd_insert_node(parent, first, node, LYD_INSERT_NODE_DEFAULT);
if (lysc_has_when(iter) && node_when) {
/* remember to resolve when */
@@ -1990,7 +1990,7 @@
return ret;
}
node->flags = LYD_DEFAULT | (lysc_has_when(iter) ? LYD_WHEN_TRUE : 0);
- lyd_insert_node(parent, first, node, 0);
+ lyd_insert_node(parent, first, node, LYD_INSERT_NODE_DEFAULT);
if (lysc_has_when(iter) && node_when) {
/* remember to resolve when */
@@ -2022,7 +2022,7 @@
return ret;
}
node->flags = LYD_DEFAULT | (lysc_has_when(iter) ? LYD_WHEN_TRUE : 0);
- lyd_insert_node(parent, first, node, 0);
+ lyd_insert_node(parent, first, node, LYD_INSERT_NODE_DEFAULT);
if (lysc_has_when(iter) && node_when) {
/* remember to resolve when */
diff --git a/src/tree_data_sorted.c b/src/tree_data_sorted.c
index cce9f9c..54ad2ff 100644
--- a/src/tree_data_sorted.c
+++ b/src/tree_data_sorted.c
@@ -968,7 +968,11 @@
/* find @p node in the Red-black tree. */
rbn = rb_find(*rbt, node);
- assert(rbn && (RBN_DNODE(rbn) == node));
+ if (!rbn) {
+ /* node was not inserted to the lyds tree due to optimization */
+ return;
+ }
+ assert(RBN_DNODE(rbn) == node);
/* remove node */
rbn = rb_remove(rbt, rbn);
@@ -1725,7 +1729,9 @@
{
assert(node1 && node2 && (node1->schema == node2->schema) && lyds_is_supported(node1));
- if (node1->schema->nodetype == LYS_LEAFLIST) {
+ if (node1 == node2) {
+ return 0;
+ } else if (node1->schema->nodetype == LYS_LEAFLIST) {
return rb_compare_leaflists(node1, node2);
} else {
return rb_compare_lists(node1, node2);
diff --git a/src/validation.c b/src/validation.c
index 1faf3f1..ecba13d 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -2047,7 +2047,7 @@
op_parent = lyd_parent(op_subtree);
lyd_unlink(op_subtree);
- lyd_insert_node(tree_parent, &tree_sibling, op_subtree, 0);
+ lyd_insert_node(tree_parent, &tree_sibling, op_subtree, LYD_INSERT_NODE_DEFAULT);
if (!dep_tree) {
dep_tree = tree_sibling;
}
@@ -2096,7 +2096,7 @@
lyd_insert_before_node(op_sibling_after, op_subtree);
lyd_insert_hash(op_subtree);
} else if (op_parent) {
- lyd_insert_node(op_parent, NULL, op_subtree, 0);
+ lyd_insert_node(op_parent, NULL, op_subtree, LYD_INSERT_NODE_DEFAULT);
}
ly_set_erase(&node_when, NULL);
diff --git a/tests/utests/data/test_diff.c b/tests/utests/data/test_diff.c
index 3c313c4..c121bc1 100644
--- a/tests/utests/data/test_diff.c
+++ b/tests/utests/data/test_diff.c
@@ -594,13 +594,13 @@
"</df>\n";
const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
" <list>\n"
- " <name>a</name>\n"
- " <value>2</value>\n"
- " </list>\n"
- " <list>\n"
" <name>b</name>\n"
" <value>-2</value>\n"
" </list>\n"
+ " <list>\n"
+ " <name>a</name>\n"
+ " <value>2</value>\n"
+ " </list>\n"
"</df>\n";
const char *out_diff_1 =
@@ -620,14 +620,14 @@
"</df>\n";
const char *out_diff_2 =
"<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
- " <list yang:operation=\"create\">\n"
- " <name>a</name>\n"
- " <value>2</value>\n"
- " </list>\n"
" <list yang:operation=\"delete\">\n"
" <name>c</name>\n"
" <value>3</value>\n"
" </list>\n"
+ " <list yang:operation=\"create\">\n"
+ " <name>a</name>\n"
+ " <value>2</value>\n"
+ " </list>\n"
"</df>\n";
const char *out_merge =
"<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"