Removed O(n^2) in cli expand/completion code

This commit is contained in:
Olof hagsand 2019-05-16 20:08:25 +02:00
parent 47889a9b0a
commit c17784cfe9
2 changed files with 9 additions and 35 deletions

View file

@ -42,6 +42,7 @@
* CLICON_XML_CHANGELOG enables the yang changelog feature * CLICON_XML_CHANGELOG enables the yang changelog feature
* CLICON_XML_CHANGELOG_FILE where the changelog resides * CLICON_XML_CHANGELOG_FILE where the changelog resides
* Optimization work * Optimization work
* Removed O(n^2) in cli expand/completion code
* Improved performance of validation of (large) lists * Improved performance of validation of (large) lists
* A scaling of [large lists](doc/scaling) report is added * A scaling of [large lists](doc/scaling) report is added
* New xmldb_get1() returning actual cache - not a copy. This has lead to some householding instead of just deleting the copy * New xmldb_get1() returning actual cache - not a copy. This has lead to some householding instead of just deleting the copy

View file

@ -108,8 +108,7 @@ expand_dbvar(void *h,
cxobj *x; cxobj *x;
char *bodystr; char *bodystr;
int i; int i;
int j; char *bodystr0 = NULL; /* previous */
int k;
cg_var *cv; cg_var *cv;
yang_stmt *yspec; yang_stmt *yspec;
cxobj *xtop = NULL; /* xpath root */ cxobj *xtop = NULL; /* xpath root */
@ -153,9 +152,8 @@ expand_dbvar(void *h,
goto done; goto done;
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0) if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
goto done; goto done;
/* Get configuration */
/* XXX read whole configuration, why not send xpath? */ if (clicon_rpc_get_config(h, dbstr, xpath, &xt) < 0)
if (clicon_rpc_get_config(h, dbstr, "/", &xt) < 0)
goto done; goto done;
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr); clicon_rpc_generate_error("Get configuration", xerr);
@ -200,45 +198,20 @@ expand_dbvar(void *h,
goto done; goto done;
} }
} }
/* One round to detect duplicates
*/
j = 0;
if (xpath_vec(xcur, "%s", &xvec, &xlen, xpathcur) < 0) if (xpath_vec(xcur, "%s", &xvec, &xlen, xpathcur) < 0)
goto done; goto done;
bodystr0 = NULL; /* Assume sorted XML where duplicates are adjacent */
for (i = 0; i < xlen; i++) { for (i = 0; i < xlen; i++) {
char *str;
x = xvec[i]; x = xvec[i];
if (xml_type(x) == CX_BODY) if (xml_type(x) == CX_BODY)
bodystr = xml_value(x); bodystr = xml_value(x);
else else
bodystr = xml_body(x); bodystr = xml_body(x);
if (bodystr == NULL){ if (bodystr == NULL)
continue; /* no body, cornercase */ continue; /* no body, cornercase */
} if (bodystr0 && strcmp(bodystr, bodystr0) == 0)
/* detect duplicates */ continue; /* duplicate, assume sorted */
for (k=0; k<j; k++){ /* RFC3986 decode */
if (xml_type(xvec[k]) == CX_BODY)
str = xml_value(xvec[k]);
else
str = xml_body(xvec[k]);
if (strcmp(str, bodystr)==0)
break;
}
if (k==j) /* not duplicate */
xvec[j++] = x;
}
xlen = j;
for (i = 0; i < xlen; i++) {
x = xvec[i];
if (xml_type(x) == CX_BODY)
bodystr = xml_value(x);
else
bodystr = xml_body(x);
if (bodystr == NULL){
clicon_err(OE_CFG, 0, "No xml body");
goto done;
}
/* XXX RFC3986 decode */
cvec_add_string(commands, NULL, bodystr); cvec_add_string(commands, NULL, bodystr);
} }
ok: ok: