tree REFACTOR basic adjustments based on new strict ordering

Redundant functions removed, it is no longer
needed to search data siblings without hashes,
ever. But a macro was added for easier iterating
over all instances of a schema node.
diff --git a/src/path.c b/src/path.c
index eb72c2f..4017be7 100644
--- a/src/path.c
+++ b/src/path.c
@@ -25,6 +25,7 @@
 #include "log.h"
 #include "plugins_types.h"
 #include "set.h"
+#include "tree.h"
 #include "tree_data_internal.h"
 #include "tree_schema.h"
 #include "tree_schema_internal.h"
@@ -793,8 +794,7 @@
         case LY_PATH_PREDTYPE_POSITION:
             /* we cannot use hashes and want an instance on a specific position */
             pos = 1;
-            node = (struct lyd_node *)start;
-            while (!lyd_find_sibling_next2(node, path[u].node, NULL, 0, &node)) {
+            LYD_LIST_FOR_INST(start, path[u].node, node) {
                 if (pos == path[u].predicates[0].position) {
                     break;
                 }
diff --git a/src/tree.h b/src/tree.h
index 11df43d..0fe7264 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -134,6 +134,31 @@
          (ELEM) = (NEXT))
 
 /**
+ * @brief Macro to iterate via all schema node data instances in data siblings.
+ *
+ * @param START Pointer to the starting sibling. Even if it is not first, all the siblings are searched.
+ * @param SCHEMA Schema node of the searched instances.
+ * @param ELEM Iterator.
+ */
+#define LYD_LIST_FOR_INST(START, SCHEMA, ELEM) \
+    for (lyd_find_sibling_val(START, SCHEMA, NULL, 0, &(ELEM)); \
+         (ELEM) && ((ELEM)->schema == (SCHEMA)); \
+         (ELEM) = (ELEM)->next)
+
+/**
+ * @brief Macro to iterate via all schema node data instances in data siblings allowing to modify the list itself.
+ *
+ * @param START Pointer to the starting sibling. Even if it is not first, all the siblings are searched.
+ * @param SCHEMA Schema node of the searched instances.
+ * @param NEXT Temporary storage to allow removing of the current iterator content.
+ * @param ELEM Iterator.
+ */
+#define LYD_LIST_FOR_INST_SAFE(START, SCHEMA, NEXT, ELEM) \
+    for (lyd_find_sibling_val(START, SCHEMA, NULL, 0, &(ELEM)); \
+         (ELEM) && ((ELEM)->schema == (SCHEMA)) ? ((NEXT) = (ELEM)->next, 1) : 0; \
+         (ELEM) = (NEXT))
+
+/**
  * @brief YANG built-in types
  */
 typedef enum
diff --git a/src/tree_data.c b/src/tree_data.c
index 72e8c7b..8de7ba2 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -2413,8 +2413,6 @@
     const struct lyd_node *child_src, *tmp, *sibling_src;
     struct lyd_node *match_trg, *dup_src, *next, *elem;
     struct lysc_type *type;
-    LYD_ANYDATA_VALUETYPE tmp_val_type;
-    union lyd_any_value tmp_val;
 
     sibling_src = *sibling_src_p;
     if (sibling_src->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) {
@@ -2442,27 +2440,12 @@
                 match_trg->flags = sibling_src->flags | LYD_NEW;
             }
         } else if ((match_trg->schema->nodetype & LYS_ANYDATA) && lyd_compare(sibling_src, match_trg, 0)) {
-            if (options & LYD_MERGE_DESTRUCT) {
-                dup_src = (struct lyd_node *)sibling_src;
-                lyd_unlink_tree(dup_src);
-                /* spend it */
-                *sibling_src_p = NULL;
-            } else {
-                LY_CHECK_RET(lyd_dup_single(sibling_src, NULL, 0, &dup_src));
-            }
-            /* just switch values */
-            tmp_val_type = ((struct lyd_node_any *)match_trg)->value_type;
-            tmp_val = ((struct lyd_node_any *)match_trg)->value;
-            ((struct lyd_node_any *)match_trg)->value_type = ((struct lyd_node_any *)sibling_src)->value_type;
-            ((struct lyd_node_any *)match_trg)->value = ((struct lyd_node_any *)sibling_src)->value;
-            ((struct lyd_node_any *)sibling_src)->value_type = tmp_val_type;
-            ((struct lyd_node_any *)sibling_src)->value = tmp_val;
+            /* update value */
+            LY_CHECK_RET(lyd_any_copy_value(match_trg, &((struct lyd_node_any *)sibling_src)->value,
+                                            ((struct lyd_node_any *)sibling_src)->value_type));
 
             /* copy flags and add LYD_NEW */
             match_trg->flags = sibling_src->flags | LYD_NEW;
-
-            /* dup_src is not needed, actually */
-            lyd_free_tree(dup_src);
         } else {
             /* check descendants, recursively */
             LY_LIST_FOR_SAFE(LYD_CHILD(sibling_src), tmp, child_src) {
@@ -2810,135 +2793,6 @@
     return ret;
 }
 
-LY_ERR
-lyd_find_sibling_next2(const struct lyd_node *first, const struct lysc_node *schema, const char *key_or_value,
-                       size_t val_len, struct lyd_node **match)
-{
-    LY_ERR rc;
-    const struct lyd_node *node = NULL;
-    struct lyd_node_term *term;
-    struct lyxp_expr *expr = NULL;
-    uint16_t exp_idx = 0;
-    struct ly_path_predicate *predicates = NULL;
-    enum ly_path_pred_type pred_type = 0;
-    struct lyd_value val = {0};
-    LY_ARRAY_COUNT_TYPE u;
-
-    LY_CHECK_ARG_RET(NULL, schema, LY_EINVAL);
-
-    if (!first) {
-        /* no data */
-        if (match) {
-            *match = NULL;
-        }
-        return LY_ENOTFOUND;
-    }
-
-    if (key_or_value && !val_len) {
-        val_len = strlen(key_or_value);
-    }
-
-    if (key_or_value && (schema->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
-        /* store the value */
-        LY_CHECK_GOTO(rc = lyd_value_store(&val, schema, key_or_value, val_len, 0, lydjson_resolve_prefix, NULL, LYD_JSON), cleanup);
-    } else if (key_or_value && (schema->nodetype == LYS_LIST)) {
-        /* parse keys */
-        LY_CHECK_GOTO(rc = ly_path_parse_predicate(schema->module->ctx, key_or_value, val_len, LY_PATH_PREFIX_OPTIONAL,
-                                                   LY_PATH_PRED_KEYS, &expr), cleanup);
-
-        /* compile them */
-        LY_CHECK_GOTO(rc = ly_path_compile_predicate(schema->module->ctx, NULL, schema, expr, &exp_idx, lydjson_resolve_prefix,
-                                                     NULL, LYD_JSON, &predicates, &pred_type), cleanup);
-    }
-
-    /* find first matching value */
-    LY_LIST_FOR(first, node) {
-        if (node->schema != schema) {
-            continue;
-        }
-
-        if ((schema->nodetype == LYS_LIST) && predicates) {
-            /* compare all set keys */
-            LY_ARRAY_FOR(predicates, u) {
-                /* find key */
-                rc = lyd_find_sibling_val(lyd_node_children(node, 0), predicates[u].key, NULL, 0, (struct lyd_node **)&term);
-                if (rc == LY_ENOTFOUND) {
-                    /* all keys must always exist */
-                    LOGINT_RET(schema->module->ctx);
-                }
-                LY_CHECK_GOTO(rc, cleanup);
-
-                /* compare values */
-                if (!term->value.realtype->plugin->compare(&term->value, &predicates[u].value)) {
-                    break;
-                }
-            }
-
-            if (u < LY_ARRAY_COUNT(predicates)) {
-                /* not a match */
-                continue;
-            }
-        } else if ((schema->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && val.realtype) {
-            term = (struct lyd_node_term *)node;
-
-            /* compare values */
-            if (!term->value.realtype->plugin->compare(&term->value, &val)) {
-                /* not a match */
-                continue;
-            }
-        }
-
-        /* all criteria passed */
-        break;
-    }
-
-    if (!node) {
-        rc = LY_ENOTFOUND;
-        if (match) {
-            *match = NULL;
-        }
-        goto cleanup;
-    }
-
-    /* success */
-    if (match) {
-        *match = (struct lyd_node *)node;
-    }
-    rc = LY_SUCCESS;
-
-cleanup:
-    ly_path_predicates_free(schema->module->ctx, pred_type, NULL, predicates);
-    lyxp_expr_free(schema->module->ctx, expr);
-    if (val.realtype) {
-        val.realtype->plugin->free(schema->module->ctx, &val);
-    }
-    return rc;
-}
-
-API LY_ERR
-lyd_find_sibling_next(const struct lyd_node *first, const struct lys_module *module, const char *name, size_t name_len,
-                      const char *key_or_value, size_t val_len, struct lyd_node **match)
-{
-    const struct lysc_node *schema;
-
-    LY_CHECK_ARG_RET(NULL, module, name, match, LY_EINVAL);
-
-    if (!first) {
-        /* no data */
-        *match = NULL;
-        return LY_ENOTFOUND;
-    }
-
-    /* find schema */
-    schema = lys_find_child(first->parent ? first->parent->schema : NULL, module, name, name_len, 0, 0);
-    if (!schema) {
-        LOGERR(module->ctx, LY_EINVAL, "Schema node not found.");
-        return LY_EINVAL;
-    }
-
-    return lyd_find_sibling_next2(first, schema, key_or_value, val_len, match);
-}
-
 API LY_ERR
 lyd_find_sibling_first(const struct lyd_node *siblings, const struct lyd_node *target, struct lyd_node **match)
 {
@@ -3002,92 +2856,6 @@
     return LY_SUCCESS;
 }
 
-API LY_ERR
-lyd_find_sibling_set(const struct lyd_node *siblings, const struct lyd_node *target, struct ly_set **set)
-{
-    struct lyd_node_inner *parent;
-    struct lyd_node *match;
-    struct lyd_node **match_p;
-    struct ly_set *ret;
-
-    LY_CHECK_ARG_RET(NULL, target, set, LY_EINVAL);
-
-    if (!siblings || (lysc_data_parent(siblings->schema) != lysc_data_parent(target->schema))) {
-        /* no data or schema mismatch */
-        return LY_ENOTFOUND;
-    }
-
-    ret = ly_set_new();
-    LY_CHECK_ERR_RET(!ret, LOGMEM(target->schema->module->ctx), LY_EMEM);
-
-    /* find first sibling */
-    if (siblings->parent) {
-        siblings = siblings->parent->child;
-    } else {
-        while (siblings->prev->next) {
-            siblings = siblings->prev;
-        }
-    }
-
-    parent = (struct lyd_node_inner *)siblings->parent;
-    if (parent && parent->children_ht) {
-        assert(target->hash);
-
-        /* find by hash */
-        if (!lyht_find(parent->children_ht, &target, target->hash, (void **)&match_p)) {
-            /* check even value when needed */
-            if (!(target->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) || !lyd_compare(target, *match_p, 0)) {
-                match = *match_p;
-            } else {
-                match = NULL;
-            }
-        } else {
-            /* not found */
-            match = NULL;
-        }
-        while (match) {
-            /* add all found nodes into the return set */
-            if (ly_set_add(ret, match, LY_SET_OPT_USEASLIST) == -1) {
-                goto error;
-            }
-
-            /* find next instance */
-            if (lyht_find_next(parent->children_ht, &match, match->hash, (void **)&match_p)) {
-                match = NULL;
-            } else {
-                /* check even value when needed */
-                if (!(match->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) || !lyd_compare(match, *match_p, 0)) {
-                    match = *match_p;
-                } else {
-                    match = NULL;
-                }
-            }
-        }
-    } else {
-        /* no children hash table */
-        for (; siblings; siblings = siblings->next) {
-            if (!lyd_compare(siblings, target, 0)) {
-                /* a match */
-                if (ly_set_add(ret, (struct lyd_node *)siblings, LY_SET_OPT_USEASLIST) == -1) {
-                    goto error;
-                }
-            }
-        }
-    }
-
-    if (!ret->count) {
-        ly_set_free(ret, NULL);
-        return LY_ENOTFOUND;
-    }
-
-    *set = ret;
-    return LY_SUCCESS;
-
-error:
-    ly_set_free(ret, NULL);
-    return LY_EMEM;
-}
-
 static int
 lyd_hash_table_schema_val_equal(void *val1_p, void *val2_p, int UNUSED(mod), void *UNUSED(cb_data))
 {
@@ -3174,15 +2942,7 @@
     LY_ERR rc;
     struct lyd_node *target = NULL;
 
-    LY_CHECK_ARG_RET(NULL, schema, LY_EINVAL);
-    if ((schema->nodetype == LYS_LIST) && (schema->flags & LYS_KEYLESS)) {
-        LOGERR(schema->module->ctx, LY_EINVAL, "Invalid arguments - key-less list (%s()).", __func__);
-        return LY_EINVAL;
-    } else if (schema->nodetype & (LYS_CHOICE | LYS_CASE)) {
-        LOGERR(schema->module->ctx, LY_EINVAL, "Invalid arguments - schema type %s (%s()).",
-               lys_nodetype2str(schema->nodetype), __func__);
-        return LY_EINVAL;
-    }
+    LY_CHECK_ARG_RET(NULL, schema, !(schema->nodetype & (LYS_CHOICE | LYS_CASE)), LY_EINVAL);
 
     if (!siblings || (lysc_data_parent(siblings->schema) != lysc_data_parent(schema))) {
         /* no data or schema mismatch */
diff --git a/src/tree_data.h b/src/tree_data.h
index fd7d421..dd69444 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -1180,41 +1180,6 @@
 struct lyd_meta *lyd_find_meta(const struct lyd_meta *first, const struct lys_module *module, const char *name);
 
 /**
- * @brief Find the node, in the list, satisfying the given restrictions.
- * Does **not** use hashes - should not be used unless necessary for best performance.
- *
- * @param[in] first Starting sibling node for search, only succeeding ones are searched.
- * @param[in] module Module of the node to find.
- * @param[in] name Name of the node to find.
- * @param[in] name_len Optional length of @p name in case it is not 0-terminated string.
- * @param[in] key_or_value Expected value depends on the type of @p name node:
- *              LYS_CONTAINER:
- *              LYS_ANYXML:
- *              LYS_ANYDATA:
- *              LYS_NOTIF:
- *              LYS_RPC:
- *              LYS_ACTION:
- *                  NULL should be always set, will be ignored.
- *              LYS_LEAF:
- *              LYS_LEAFLIST:
- *                  Optional restriction on the specific leaf(-list) value.
- *              LYS_LIST:
- *                  Optional keys values of the matching list instances in the form of "[key1='val1'][key2='val2']...".
- *                  The keys do not have to be ordered and not all keys need to be specified.
- *
- *              Note that any explicit values (leaf, leaf-list or list key values) will be canonized first
- *              before comparison. But values that do not have a canonical value are expected to be in the
- *              JSON format!
- * @param[in] val_len Optional length of @p key_or_value in case it is not a 0-terminated string.
- * @param[out] match Found data node.
- * @return LY_SUCCESS on success, @p match set.
- * @return LY_ENOTFOUND if not found, @p match set to NULL.
- * @return LY_ERR value if another error occurred.
- */
-LY_ERR lyd_find_sibling_next(const struct lyd_node *first, const struct lys_module *module, const char *name,
-                             size_t name_len, const char *key_or_value, size_t val_len, struct lyd_node **match);
-
-/**
  * @brief Search in the given siblings (NOT recursively) for the first target instance with the same value.
  * Uses hashes - should be used whenever possible for best performance.
  *
@@ -1228,20 +1193,6 @@
 LY_ERR lyd_find_sibling_first(const struct lyd_node *siblings, const struct lyd_node *target, struct lyd_node **match);
 
 /**
- * @brief Search in the given siblings for all target instances with the same value.
- * Uses hashes - should be used whenever possible for best performance.
- *
- * @param[in] siblings Siblings to search in including preceding and succeeding nodes.
- * @param[in] target Target node to find. Key-less lists are compared based on
- * all its descendants (both direct and indirect).
- * @param[out] set Found nodes in a set in case of success.
- * @return LY_SUCCESS on success.
- * @return LY_ENOTFOUND if no matching siblings found.
- * @return LY_ERR value if another error occurred.
- */
-LY_ERR lyd_find_sibling_set(const struct lyd_node *siblings, const struct lyd_node *target, struct ly_set **set);
-
-/**
  * @brief Search in the given siblings for the first schema instance.
  * Uses hashes - should be used whenever possible for best performance.
  *
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index 2271c4b..980af5e 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -421,39 +421,6 @@
 /** @} datahash */
 
 /**
- * @brief Find the node, in the list, satisfying the given restrictions.
- * Does **not** use hashes - should not be used unless necessary for best performance.
- *
- * @param[in] first Starting sibling node for search, only succeeding ones are searched.
- * @param[in] schema Schema node of the data node to find.
- * @param[in] key_or_value Expected value depends on the type of @p schema:
- *              LYS_CONTAINER:
- *              LYS_ANYXML:
- *              LYS_ANYDATA:
- *              LYS_NOTIF:
- *              LYS_RPC:
- *              LYS_ACTION:
- *                  NULL should be always set, will be ignored.
- *              LYS_LEAF:
- *              LYS_LEAFLIST:
- *                  Optional restriction on the specific leaf(-list) value.
- *              LYS_LIST:
- *                  Optional keys values of the matching list instances in the form of "[key1='val1'][key2='val2']...".
- *                  The keys do not have to be ordered and not all keys need to be specified.
- *
- *              Note that any explicit values (leaf, leaf-list or list key values) will be canonized first
- *              before comparison. But values that do not have a canonical value are expected to be in the
- *              JSON format!
- * @param[in] val_len Optional length of the @p key_or_value argument in case it is not NULL-terminated string.
- * @param[out] match Can be NULL, otherwise the found data node.
- * @return LY_SUCCESS on success, @p match set.
- * @return LY_ENOTFOUND if not found, @p match set to NULL.
- * @return LY_ERR value if another error occurred.
- */
-LY_ERR lyd_find_sibling_next2(const struct lyd_node *first, const struct lysc_node *schema, const char *key_or_value,
-                              size_t val_len, struct lyd_node **match);
-
-/**
  * @brief Iterate over implemented modules for functions that accept specific modules or the whole context.
  *
  * @param[in] tree Data tree.
diff --git a/src/validation.c b/src/validation.c
index 437ce21..1c4bc45 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -60,33 +60,14 @@
         siter = *slast;
     }
 
-    if (last && last->next) {
-        /* find next data instance */
-        lyd_find_sibling_next2(last->next, siter, NULL, 0, &match);
-        if (match) {
-            return match;
-        }
+    if (last && last->next && (last->next->schema == siter)) {
+        /* return next data instance */
+        return last->next;
     }
 
     /* find next schema node data instance */
     while ((siter = lys_getnext(siter, parent, module, 0))) {
-        switch (siter->nodetype) {
-        case LYS_CONTAINER:
-        case LYS_ANYXML:
-        case LYS_ANYDATA:
-        case LYS_LEAF:
-            lyd_find_sibling_val(sibling, siter, NULL, 0, &match);
-            break;
-        case LYS_LIST:
-        case LYS_LEAFLIST:
-            lyd_find_sibling_next2(sibling, siter, NULL, 0, &match);
-            break;
-        default:
-            assert(0);
-            LOGINT(NULL);
-        }
-
-        if (match) {
+        if (!lyd_find_sibling_val(sibling, siter, NULL, 0, &match)) {
             break;
         }
     }
@@ -450,14 +431,7 @@
 
     if (lyd_val_has_default(node->schema)) {
         assert(node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CONTAINER));
-        if (node->schema->nodetype == LYS_LEAFLIST) {
-            lyd_find_sibling_next2(*first, node->schema, NULL, 0, &match);
-        } else {
-            lyd_find_sibling_val(*first, node->schema, NULL, 0, &match);
-        }
-
-        while (match) {
-            next = match->next;
+        LYD_LIST_FOR_INST_SAFE(*first, node->schema, next, match) {
             if ((match->flags & LYD_DEFAULT) && !(match->flags & LYD_NEW)) {
                 /* default instance found, remove it */
                 if (LYD_DEL_IS_ROOT(*first, match)) {
@@ -484,8 +458,6 @@
                     break;
                 }
             }
-
-            lyd_find_sibling_next2(next, node->schema, NULL, 0, &match);
         }
     }
 }
@@ -572,27 +544,25 @@
 lyd_validate_minmax(const struct lyd_node *first, const struct lysc_node *snode, uint32_t min, uint32_t max)
 {
     uint32_t count = 0;
-    const struct lyd_node *iter;
+    struct lyd_node *iter;
 
     assert(min || max);
 
-    LY_LIST_FOR(first, iter) {
-        if (iter->schema == snode) {
-            ++count;
+    LYD_LIST_FOR_INST(first, snode, iter) {
+        ++count;
 
-            if (min && (count == min)) {
-                /* satisfied */
-                min = 0;
-                if (!max) {
-                    /* nothing more to check */
-                    break;
-                }
-            }
-            if (max && (count > max)) {
-                /* not satisifed */
+        if (min && (count == min)) {
+            /* satisfied */
+            min = 0;
+            if (!max) {
+                /* nothing more to check */
                 break;
             }
         }
+        if (max && (count > max)) {
+            /* not satisifed */
+            break;
+        }
     }
 
     if (min) {
@@ -1160,7 +1130,7 @@
             }
             break;
         case LYS_LEAFLIST:
-            if (((struct lysc_node_leaflist *)iter)->dflts && lyd_find_sibling_next2(*first, iter, NULL, 0, NULL)) {
+            if (((struct lysc_node_leaflist *)iter)->dflts && lyd_find_sibling_val(*first, iter, NULL, 0, NULL)) {
                 /* create all default leaf-lists */
                 dflts = ((struct lysc_node_leaflist *)iter)->dflts;
                 LY_ARRAY_FOR(dflts, u) {