C-API: Added specialized xml_child_each_attr function to counter perf issue

This commit is contained in:
Olof hagsand 2023-05-29 12:25:36 +02:00
parent 86ef8053a2
commit b3a7e39d26
5 changed files with 45 additions and 9 deletions

View file

@ -59,7 +59,7 @@ Developers may need to change their code
### Minor features
* Performance: A change in the `merge` code made "co-located" config and non-config get retrieval go considerable faster.
* Performance: A change in the `merge` code made "co-located" config and non-config get retrieval go considerable faster. This is done by a specialized `xml_child_each_attr()` function.
* CLI: Added `show statistics` example code for backend and CLI memory stats
* [Support yang type union with are same subtypes with SNMP](https://github.com/clicon/clixon/pull/427)
* Removed obsolete compile options introduced in 6.1:

View file

@ -246,6 +246,7 @@ cxobj *xml_child_i_type(cxobj *xn, int i, enum cxobj_type type);
cxobj *xml_child_i_set(cxobj *xt, int i, cxobj *xc);
int xml_child_order(cxobj *xn, cxobj *xc);
cxobj *xml_child_each(cxobj *xparent, cxobj *xprev, enum cxobj_type type);
cxobj *xml_child_each_attr(cxobj *xparent, cxobj *xprev);
int xml_child_insert_pos(cxobj *x, cxobj *xc, int i);
int xml_childvec_set(cxobj *x, int len);
cxobj **xml_childvec_get(cxobj *x);

View file

@ -972,8 +972,8 @@ xml_child_order(cxobj *xp,
* xprev = x;
* }
* @endcode
* @note Assumes attributes are first in list
* @see xml_child_index_each
* @see xml_child_each_attr hardcoded for sorted list and attributes
*/
cxobj *
xml_child_each(cxobj *xparent,
@ -991,10 +991,45 @@ xml_child_each(cxobj *xparent,
xn = xparent->x_childvec[i];
if (xn == NULL)
continue;
if (type != CX_ERROR && xml_type(xn) != type){
if (type == CX_ATTR) /* Assume sorted attributes are first */
return NULL;
if (type != CX_ERROR && xml_type(xn) != type)
continue;
break; /* this is next object after previous */
}
if (i < xparent->x_childvec_len) /* found */
xn->_x_vector_i = i;
else
xn = NULL;
return xn;
}
/*! Same as xml_child_each but hard-coded for attributes
*
* Assumes attributes are first in list, which they are if they are sorted, but there are
* situations where the children have not (yet) been sorted, in which case you need to use the
* original function.
* @param[in] xparent xml tree node whose children should be iterated
* @param[in] xprev previous child, or NULL on init
* @retval xn Next XML node
* @retval NULL End of list
* @see xml_child_each
*/
cxobj *
xml_child_each_attr(cxobj *xparent,
cxobj *xprev)
{
int i;
cxobj *xn = NULL;
if (xparent == NULL)
return NULL;
if (!is_element(xparent))
return NULL;
for (i=xprev?xprev->_x_vector_i+1:0; i<xparent->x_childvec_len; i++){
xn = xparent->x_childvec[i];
if (xn == NULL)
continue;
if (xml_type(xn) != CX_ATTR){
return NULL;
}
break; /* this is next object after previous */
}

View file

@ -1021,7 +1021,7 @@ assign_namespace_body(cxobj *x0, /* source */
cxobj *xa;
xa = NULL;
while ((xa = xml_child_each(x0, xa, CX_ATTR)) != NULL) {
while ((xa = xml_child_each_attr(x0, xa)) != NULL) {
prefix0 = xml_prefix(xa);
name = xml_name(xa);
namespace = xml_value(xa);
@ -1478,7 +1478,7 @@ xml_copy_marked(cxobj *x0,
/* Copy all attributes */
x = NULL;
while ((x = xml_child_each(x0, x, CX_ATTR)) != NULL) {
while ((x = xml_child_each_attr(x0, x)) != NULL) {
name = xml_name(x);
if ((xcopy = xml_new(name, x1, CX_ATTR)) == NULL)
goto done;

View file

@ -230,7 +230,7 @@ xml_nsctx_node1(cxobj *xn,
/* xmlns:t="<ns1>" prefix:xmlns, name:t
* xmlns="<ns2>" prefix:NULL name:xmlns
*/
while ((xa = xml_child_each(xn, xa, CX_ATTR)) != NULL){
while ((xa = xml_child_each_attr(xn, xa)) != NULL){
pf = xml_prefix(xa);
nm = xml_name(xa);
if (pf == NULL){
@ -674,7 +674,7 @@ xml2prefix(cxobj *xn,
if (nscache_get_prefix(xn, namespace, &prefix) == 1) /* found */
goto found;
xa = NULL;
while ((xa = xml_child_each(xn, xa, CX_ATTR)) != NULL) {
while ((xa = xml_child_each_attr(xn, xa)) != NULL) {
/* xmlns=namespace */
if (strcmp("xmlns", xml_name(xa)) == 0){
if (strcmp(xml_value(xa), namespace) == 0){