* Performance improvement
* Added ancestor config cache indicating wether the node or an ancestor is config false or true * Improved yang cardinality lookup * Added yang_init(), called from all apps using yang
This commit is contained in:
parent
0626de9431
commit
b91ce762d5
19 changed files with 415 additions and 63 deletions
|
|
@ -3190,11 +3190,29 @@ yang_config_ancestor(yang_stmt *ys)
|
|||
|
||||
yp = ys;
|
||||
do {
|
||||
if (yang_config(yp) == 0)
|
||||
#ifdef USE_CONFIG_FLAG_CACHE
|
||||
if (yang_flag_get(yp, YANG_FLAG_CONFIG_CACHE))
|
||||
return yang_flag_get(yp, YANG_FLAG_CONFIG_VALUE)?1:0;
|
||||
#endif
|
||||
if (yang_config(yp) == 0){
|
||||
#ifdef USE_CONFIG_FLAG_CACHE
|
||||
yang_flag_set(yp, YANG_FLAG_CONFIG_CACHE);
|
||||
yang_flag_reset(yp, YANG_FLAG_CONFIG_VALUE);
|
||||
#endif
|
||||
return 0;
|
||||
if (yang_keyword_get(yp) == Y_INPUT || yang_keyword_get(yp) == Y_OUTPUT || yang_keyword_get(yp) == Y_NOTIFICATION)
|
||||
}
|
||||
if (yang_keyword_get(yp) == Y_INPUT || yang_keyword_get(yp) == Y_OUTPUT || yang_keyword_get(yp) == Y_NOTIFICATION){
|
||||
#ifdef USE_CONFIG_FLAG_CACHE
|
||||
yang_flag_set(yp, YANG_FLAG_CONFIG_CACHE);
|
||||
yang_flag_reset(yp, YANG_FLAG_CONFIG_VALUE);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
} while((yp = yang_parent_get(yp)) != NULL);
|
||||
#ifdef USE_CONFIG_FLAG_CACHE
|
||||
yang_flag_set(ys, YANG_FLAG_CONFIG_CACHE);
|
||||
yang_flag_set(ys, YANG_FLAG_CONFIG_VALUE);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -3678,6 +3696,12 @@ yang_sort_subelements(yang_stmt *ys)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
yang_init(clicon_handle h)
|
||||
{
|
||||
return yang_cardinality_init(h);
|
||||
}
|
||||
|
||||
#ifdef XML_EXPLICIT_INDEX
|
||||
/*! Mark element as search_index in list
|
||||
* @retval 0 OK
|
||||
|
|
|
|||
|
|
@ -111,11 +111,11 @@ struct ycard{
|
|||
* 1 10
|
||||
* 0..1 149
|
||||
* 0..n 176 (no restrictions)
|
||||
* @note assume array is ordered wrt parent
|
||||
* @note The array MUST be ordered wrt parent and child for ycard_find_binary to use binary search
|
||||
* @note yang-version is optional in RFC6020 but mandatory in RFC7950, if not given, it defaults to 1.
|
||||
*/
|
||||
#define NMAX 1000000 /* Just a large number */
|
||||
static const struct ycard yclist[] = {
|
||||
static const struct ycard _yclist[] = {
|
||||
{Y_ACTION, Y_DESCRIPTION, 0, 1, 0},
|
||||
{Y_ACTION, Y_GROUPING, 0, NMAX, 0},
|
||||
{Y_ACTION, Y_IF_FEATURE, 0, NMAX, 0},
|
||||
|
|
@ -176,6 +176,7 @@ static const struct ycard yclist[] = {
|
|||
{Y_CASE, Y_STATUS, 0, 1, 0},
|
||||
{Y_CASE, Y_USES, 0, NMAX, 0},
|
||||
{Y_CASE, Y_WHEN, 0, 1, 0},
|
||||
{Y_CHOICE, Y_ANYDATA, 0, NMAX, 0},
|
||||
{Y_CHOICE, Y_ANYXML, 0, NMAX, 0},
|
||||
{Y_CHOICE, Y_CASE, 0, NMAX, 0},
|
||||
{Y_CHOICE, Y_CHOICE, 0, NMAX, 0},
|
||||
|
|
@ -191,7 +192,6 @@ static const struct ycard yclist[] = {
|
|||
{Y_CHOICE, Y_REFERENCE, 0, 1, 0},
|
||||
{Y_CHOICE, Y_STATUS, 0, 1, 0},
|
||||
{Y_CHOICE, Y_WHEN, 0, 1, 0},
|
||||
{Y_CHOICE, Y_ANYDATA, 0, NMAX, 0},
|
||||
{Y_CONTAINER, Y_ACTION, 0, NMAX, 0},
|
||||
{Y_CONTAINER, Y_ANYDATA, 0, NMAX, 0},
|
||||
{Y_CONTAINER, Y_ANYXML, 0, NMAX, 0},
|
||||
|
|
@ -451,37 +451,22 @@ static const struct ycard yclist[] = {
|
|||
{Y_USES, Y_REFINE, 0, NMAX, 0},
|
||||
{Y_USES, Y_STATUS, 0, 1, 0},
|
||||
{Y_USES, Y_WHEN, 0, 1, 0},
|
||||
{Y_WHEN, Y_DESCRIPTION, 0, 1, 0},
|
||||
{Y_WHEN, Y_REFERENCE, 0, 1, 0},
|
||||
{0,}
|
||||
};
|
||||
|
||||
/*! Find yang parent and child combination in yang cardinality table
|
||||
* @param[in] parent Parent Yang spec
|
||||
* @param[in] child Child yang spec if 0 first
|
||||
* @param[in] yc Yang cardinality map
|
||||
* @param[in] p If set, quit as soon as parents dont match
|
||||
* @retval NULL Not found
|
||||
* @retval yp Found
|
||||
* @note if cardinal list above is sorted, this search could do binary
|
||||
/* Search matrix for lookups */
|
||||
static const struct ycard *_yc_search[Y_SPEC][Y_SPEC] = {0,};
|
||||
|
||||
/* Set to 1 if exists in search
|
||||
* Some yang statements are not explicitly given cardinalities in RFC7950, although they are
|
||||
* present in Section 14 BNF.
|
||||
* But since the table above is from the explicit cardinalities in the RFC the others are skipped
|
||||
* and = 0 in the following vector.
|
||||
* Example: Y_REFINE
|
||||
*/
|
||||
static const struct ycard *
|
||||
ycard_find(enum rfc_6020 parent,
|
||||
enum rfc_6020 child,
|
||||
const struct ycard *yclist,
|
||||
int p)
|
||||
{
|
||||
const struct ycard *yc;
|
||||
|
||||
for (yc = &yclist[0]; (int)yc->yc_parent; yc++){
|
||||
if (yc->yc_parent == parent){
|
||||
if (!child || yc->yc_child == child)
|
||||
return yc;
|
||||
}
|
||||
else
|
||||
if (p)
|
||||
return NULL; /* premature quit */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static int _yc_exist[Y_SPEC] = {0,};
|
||||
|
||||
/*! Check cardinality, ie if each yang node has the expected nr of children
|
||||
* @param[in] h Clicon handle
|
||||
|
|
@ -503,16 +488,14 @@ yang_cardinality(clicon_handle h,
|
|||
int pk;
|
||||
int ck;
|
||||
int i;
|
||||
int nr;
|
||||
const struct ycard *ycplist; /* ycard parent table*/
|
||||
const struct ycard *yc;
|
||||
int order;
|
||||
yang_stmt *yprev = NULL;
|
||||
int nr;
|
||||
|
||||
pk = yang_keyword_get(yt);
|
||||
/* 0) Find parent sub-parts of cardinality vector */
|
||||
if ((ycplist = ycard_find(pk, 0, yclist, 0)) == NULL)
|
||||
goto ok; /* skip */
|
||||
if (_yc_exist[pk] == 0)
|
||||
goto ok;
|
||||
/* 1) For all children, if neither in 0..n, 0..1, 1 or 1..n ->ERROR
|
||||
* Also: check monotonically increasing order
|
||||
*/
|
||||
|
|
@ -520,10 +503,10 @@ yang_cardinality(clicon_handle h,
|
|||
ys = NULL;
|
||||
while ((ys = yn_each(yt, ys)) != NULL) {
|
||||
ck = yang_keyword_get(ys);
|
||||
if (ck == Y_UNKNOWN) /* special case */
|
||||
if (pk == Y_UNKNOWN || ck == Y_UNKNOWN) /* special case */
|
||||
continue;
|
||||
/* Find entry in yang cardinality table from parent/child keyword pair */
|
||||
if ((yc = ycard_find(pk, ck, ycplist, 1)) == NULL){
|
||||
if ((yc = _yc_search[pk][ck]) == NULL){
|
||||
clicon_err(OE_YANG, 0, "%s: \"%s\"(%s) is child of \"%s\"(%s), but should not be",
|
||||
modname,
|
||||
yang_key2str(ck),
|
||||
|
|
@ -548,16 +531,16 @@ yang_cardinality(clicon_handle h,
|
|||
yprev = ys;
|
||||
}
|
||||
/* 2) For all in 1 and 1..n list, if 0 such children ->ERROR */
|
||||
for (yc = &ycplist[0]; (int)yc->yc_parent == pk; yc++){
|
||||
for (i=0; i<Y_SPEC; i++){
|
||||
yc = _yc_search[pk][i];
|
||||
if (yc == NULL)
|
||||
continue;
|
||||
if (yc->yc_min &&
|
||||
yang_find(yt, yc->yc_child, NULL) == NULL){
|
||||
clicon_err(OE_YANG, 0, "%s: \"%s\" is missing but is mandatory child of \"%s\"",
|
||||
modname, yang_key2str(yc->yc_child), yang_key2str(pk));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
/* 3) For all in 0..1 and 1 list, if >1 such children ->ERROR */
|
||||
for (yc = &ycplist[0]; (int)yc->yc_parent == pk; yc++){
|
||||
if (yc->yc_max<NMAX &&
|
||||
(nr = yang_match(yt, yc->yc_child, NULL)) > yc->yc_max){
|
||||
clicon_err(OE_YANG, 0, "%s: \"%s\" has %d children of type \"%s\", but only %d allowed",
|
||||
|
|
@ -569,7 +552,6 @@ yang_cardinality(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* 4) Recurse */
|
||||
i = 0;
|
||||
while (i< yang_len_get(yt)){ /* Note, children may be removed cant use yn_each */
|
||||
|
|
@ -601,7 +583,7 @@ yang_cardinality_interval(clicon_handle h,
|
|||
int retval = -1;
|
||||
const struct ycard *ycplist; /* ycard parent table*/
|
||||
|
||||
if ((ycplist = ycard_find(parent_key, child_key, yclist, 0)) == NULL){
|
||||
if ((ycplist = _yc_search[parent_key][child_key]) == NULL){
|
||||
clicon_err(OE_YANG, EINVAL, "keys %d %d do not have cardinality",
|
||||
parent_key, child_key);
|
||||
goto done;
|
||||
|
|
@ -612,3 +594,17 @@ yang_cardinality_interval(clicon_handle h,
|
|||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Init */
|
||||
int
|
||||
yang_cardinality_init(clicon_handle h)
|
||||
{
|
||||
const struct ycard *yc;
|
||||
|
||||
for (yc = &_yclist[0]; (int)yc->yc_parent; yc++){
|
||||
_yc_exist[yc->yc_parent] = 1;
|
||||
_yc_search[yc->yc_parent][yc->yc_child] = yc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
* Prototypes
|
||||
*/
|
||||
int yang_cardinality(clicon_handle h, yang_stmt *yt, char *modname);
|
||||
|
||||
int yang_cardinality_interval(clicon_handle h, enum rfc_6020 parent_key, enum rfc_6020 child_key, int *min, int *max);
|
||||
int yang_cardinality_init(clicon_handle h);
|
||||
|
||||
#endif /* _CLIXON_YANG_CARDINALITY_H_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue