Skip to content

Commit 9a27302

Browse files
authored
CVL Changes sonic-net#4: Implementation of new CVL APIs (sonic-net#22)
Implementing following CVL APIs : SortDepTables GetOrderedTables GetDepTables GetDepDataForDelete GetValidationTimeStats ClearValidationTimeStats
1 parent dbf1093 commit 9a27302

File tree

4 files changed

+574
-16
lines changed

4 files changed

+574
-16
lines changed

cvl/cvl.go

+76-6
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ var dbNameToDbNum map[string]uint8
6262
//map of lua script loaded
6363
var luaScripts map[string]*redis.Script
6464

65+
type leafRefInfo struct {
66+
path string //leafref path
67+
yangListNames []string //all yang list in path
68+
targetNodeName string //target node name
69+
}
70+
6571
//var tmpDbCache map[string]interface{} //map of table storing map of key-value pair
6672
//m["PORT_TABLE] = {"key" : {"f1": "v1"}}
6773
//Important schema information to be loaded at bootup time
@@ -74,10 +80,11 @@ type modelTableInfo struct {
7480
redisKeyDelim string
7581
redisKeyPattern string
7682
mapLeaf []string //for 'mapping list'
77-
leafRef map[string][]string //for storing all leafrefs for a leaf in a table,
83+
leafRef map[string][]*leafRefInfo //for storing all leafrefs for a leaf in a table,
7884
//multiple leafref possible for union
7985
mustExp map[string]string
8086
tablesForMustExp map[string]CVLOperation
87+
refFromTables []tblFieldPair //list of table or table/field referring to this table
8188
dfltLeafVal map[string]string //map of leaf names and default value
8289
}
8390

@@ -359,7 +366,7 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
359366
continue
360367
}
361368

362-
tableInfo.leafRef = make(map[string][]string)
369+
tableInfo.leafRef = make(map[string][]*leafRefInfo)
363370
for _, leafRefNode := range leafRefNodes {
364371
if (leafRefNode.Parent == nil || leafRefNode.FirstChild == nil) {
365372
continue
@@ -378,7 +385,7 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
378385
//Store the leafref path
379386
if (leafName != "") {
380387
tableInfo.leafRef[leafName] = append(tableInfo.leafRef[leafName],
381-
getXmlNodeAttr(leafRefNode.FirstChild, "value"))
388+
&leafRefInfo{path: getXmlNodeAttr(leafRefNode.FirstChild, "value")})
382389
}
383390
}
384391

@@ -429,6 +436,69 @@ func getYangListToRedisTbl(yangListName string) string {
429436
return yangListName
430437
}
431438

439+
//This functions build info of dependent table/fields
440+
//which uses a particular table through leafref
441+
func buildRefTableInfo() {
442+
443+
CVL_LOG(INFO_API, "Building reverse reference info from leafref")
444+
445+
for tblName, tblInfo := range modelInfo.tableInfo {
446+
if (len(tblInfo.leafRef) == 0) {
447+
continue
448+
}
449+
450+
//For each leafref update the table used through leafref
451+
for fieldName, leafRefs := range tblInfo.leafRef {
452+
for _, leafRef := range leafRefs {
453+
454+
for _, yangListName := range leafRef.yangListNames {
455+
refTblInfo := modelInfo.tableInfo[yangListName]
456+
457+
refFromTables := &refTblInfo.refFromTables
458+
*refFromTables = append(*refFromTables, tblFieldPair{tblName, fieldName})
459+
modelInfo.tableInfo[yangListName] = refTblInfo
460+
}
461+
462+
}
463+
}
464+
465+
}
466+
467+
//Now sort list 'refFromTables' under each table based on dependency among them
468+
for tblName, tblInfo := range modelInfo.tableInfo {
469+
if (len(tblInfo.refFromTables) == 0) {
470+
continue
471+
}
472+
473+
depTableList := []string{}
474+
for i:=0; i < len(tblInfo.refFromTables); i++ {
475+
depTableList = append(depTableList, tblInfo.refFromTables[i].tableName)
476+
}
477+
478+
sortedTableList, _ := cvg.cv.SortDepTables(depTableList)
479+
if (len(sortedTableList) == 0) {
480+
continue
481+
}
482+
483+
newRefFromTables := []tblFieldPair{}
484+
485+
for i:=0; i < len(sortedTableList); i++ {
486+
//Find fieldName
487+
fieldName := ""
488+
for j :=0; j < len(tblInfo.refFromTables); j++ {
489+
if (sortedTableList[i] == tblInfo.refFromTables[j].tableName) {
490+
fieldName = tblInfo.refFromTables[j].field
491+
newRefFromTables = append(newRefFromTables, tblFieldPair{sortedTableList[i], fieldName})
492+
}
493+
}
494+
}
495+
//Update sorted refFromTables
496+
tblInfo.refFromTables = newRefFromTables
497+
modelInfo.tableInfo[tblName] = tblInfo
498+
}
499+
500+
}
501+
432502
//Find the tables names in must expression, these tables data need to be fetched
433503
//during semantic validation
434504
func addTableNamesForMustExp() {
@@ -998,8 +1068,8 @@ func (c *CVL) findUsedAsLeafRef(tableName, field string) []tblFieldPair {
9981068
found := false
9991069
//Find leafref by searching table and field name
10001070
for _, leafRef := range leafRefs {
1001-
if ((strings.Contains(leafRef, tableName) == true) &&
1002-
(strings.Contains(leafRef, field) == true)) {
1071+
if ((strings.Contains(leafRef.path, tableName) == true) &&
1072+
(strings.Contains(leafRef.path, field) == true)) {
10031073
tblFieldPairArr = append(tblFieldPairArr,
10041074
tblFieldPair{tblName, fieldName})
10051075
//Found as leafref, no need to search further
@@ -1030,7 +1100,7 @@ func (c *CVL) addLeafRef(config bool, tableName string, name string, value strin
10301100
for _, leafRef := range modelInfo.tableInfo[tableName].leafRef[name] {
10311101

10321102
//Get reference table name from the path and the leaf name
1033-
matches := reLeafRef.FindStringSubmatch(leafRef)
1103+
matches := reLeafRef.FindStringSubmatch(leafRef.path)
10341104

10351105
//We have the leafref table name and the leaf name as well
10361106
if (matches != nil && len(matches) == 5) { //whole + 4 sub matches

0 commit comments

Comments
 (0)