Skip to content

Commit 8f2033f

Browse files
committed
xpath OPTIMIZE no ext schema nodes in xpath hash search
1 parent d4b8282 commit 8f2033f

1 file changed

Lines changed: 42 additions & 5 deletions

File tree

src/xpath.c

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8057,6 +8057,42 @@ eval_name_test_try_compile_predicates(const struct lyxp_expr *exp, uint32_t *tok
80578057
return rc;
80588058
}
80598059

8060+
/**
8061+
* @brief Find a specific child schema node. ::lys_find_child() is not used to avoid searching in extension instances.
8062+
*
8063+
* No need to find ext instance data nodes using hashes and may cause some recursive callback calls (schema-mount).
8064+
*
8065+
* @param[in] parent Parent node, if any.
8066+
* @param[in] mod Node module.
8067+
* @param[in] name Name of the node.
8068+
* @param[in] name_len Length of @p name.
8069+
* @param[in] options Getnext options.
8070+
* @return Found schema node;
8071+
* @return NULL if no node found.
8072+
*/
8073+
static const struct lysc_node *
8074+
eval_name_test_with_predicate_find_scnode(const struct lysc_node *parent, const struct lys_module *mod,
8075+
const char *name, uint32_t name_len, uint32_t options)
8076+
{
8077+
const struct lysc_node *node = NULL;
8078+
8079+
assert(mod && mod->implemented);
8080+
8081+
while ((node = lys_getnext(node, parent, mod->compiled, options))) {
8082+
/* check module */
8083+
if (node->module != mod) {
8084+
continue;
8085+
}
8086+
8087+
/* check name */
8088+
if (!ly_strncmp(node->name, name, name_len)) {
8089+
return node;
8090+
}
8091+
}
8092+
8093+
return NULL;
8094+
}
8095+
80608096
/**
80618097
* @brief Search for/check the next schema node that could be the only matching schema node meaning the
80628098
* data node(s) could be found using a single hash-based search.
@@ -8093,7 +8129,7 @@ eval_name_test_with_predicate_get_scnode(const struct ly_ctx *ctx, const struct
80938129
continue;
80948130
}
80958131

8096-
scnode = lys_find_child(NULL, NULL, mod, NULL, 0, name, name_len, 0);
8132+
scnode = eval_name_test_with_predicate_find_scnode(NULL, mod, name, name_len, 0);
80978133
if (scnode) {
80988134
/* we have found a match */
80998135
break;
@@ -8106,7 +8142,7 @@ eval_name_test_with_predicate_get_scnode(const struct ly_ctx *ctx, const struct
81068142
}
81078143
} else {
81088144
/* search in top-level */
8109-
scnode = lys_find_child(NULL, NULL, moveto_mod, NULL, 0, name, name_len, 0);
8145+
scnode = eval_name_test_with_predicate_find_scnode(NULL, moveto_mod, name, name_len, 0);
81108146
}
81118147
} else if (node->schema && (!*found || (lysc_data_parent(*found) != node->schema))) {
81128148
if ((format == LY_VALUE_JSON) && !moveto_mod) {
@@ -8117,16 +8153,17 @@ eval_name_test_with_predicate_get_scnode(const struct ly_ctx *ctx, const struct
81178153
/* search in children, do not repeat the same search */
81188154
if (node->schema->nodetype & (LYS_RPC | LYS_ACTION)) {
81198155
/* make sure the node is unique, whether in input or output */
8120-
scnode = lys_find_child(NULL, node->schema, moveto_mod, NULL, 0, name, name_len, 0);
8121-
scnode2 = lys_find_child(NULL, node->schema, moveto_mod, NULL, 0, name, name_len, LYS_GETNEXT_OUTPUT);
8156+
scnode = eval_name_test_with_predicate_find_scnode(node->schema, moveto_mod, name, name_len, 0);
8157+
scnode2 = eval_name_test_with_predicate_find_scnode(node->schema, moveto_mod, name, name_len,
8158+
LYS_GETNEXT_OUTPUT);
81228159
if (scnode && scnode2) {
81238160
/* conflict, do not use hashes */
81248161
scnode = NULL;
81258162
} else if (scnode2) {
81268163
scnode = scnode2;
81278164
}
81288165
} else {
8129-
scnode = lys_find_child(NULL, node->schema, moveto_mod, NULL, 0, name, name_len, 0);
8166+
scnode = eval_name_test_with_predicate_find_scnode(node->schema, moveto_mod, name, name_len, 0);
81308167
}
81318168
} /* else skip redundant search */
81328169

0 commit comments

Comments
 (0)