@@ -62,6 +62,12 @@ var dbNameToDbNum map[string]uint8
62
62
//map of lua script loaded
63
63
var luaScripts map [string ]* redis.Script
64
64
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
+
65
71
//var tmpDbCache map[string]interface{} //map of table storing map of key-value pair
66
72
//m["PORT_TABLE] = {"key" : {"f1": "v1"}}
67
73
//Important schema information to be loaded at bootup time
@@ -74,10 +80,11 @@ type modelTableInfo struct {
74
80
redisKeyDelim string
75
81
redisKeyPattern string
76
82
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,
78
84
//multiple leafref possible for union
79
85
mustExp map [string ]string
80
86
tablesForMustExp map [string ]CVLOperation
87
+ refFromTables []tblFieldPair //list of table or table/field referring to this table
81
88
dfltLeafVal map [string ]string //map of leaf names and default value
82
89
}
83
90
@@ -359,7 +366,7 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
359
366
continue
360
367
}
361
368
362
- tableInfo .leafRef = make (map [string ][]string )
369
+ tableInfo .leafRef = make (map [string ][]* leafRefInfo )
363
370
for _ , leafRefNode := range leafRefNodes {
364
371
if (leafRefNode .Parent == nil || leafRefNode .FirstChild == nil ) {
365
372
continue
@@ -378,7 +385,7 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
378
385
//Store the leafref path
379
386
if (leafName != "" ) {
380
387
tableInfo .leafRef [leafName ] = append (tableInfo .leafRef [leafName ],
381
- getXmlNodeAttr (leafRefNode .FirstChild , "value" ))
388
+ & leafRefInfo { path : getXmlNodeAttr (leafRefNode .FirstChild , "value" )} )
382
389
}
383
390
}
384
391
@@ -429,6 +436,69 @@ func getYangListToRedisTbl(yangListName string) string {
429
436
return yangListName
430
437
}
431
438
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
+
432
502
//Find the tables names in must expression, these tables data need to be fetched
433
503
//during semantic validation
434
504
func addTableNamesForMustExp () {
@@ -998,8 +1068,8 @@ func (c *CVL) findUsedAsLeafRef(tableName, field string) []tblFieldPair {
998
1068
found := false
999
1069
//Find leafref by searching table and field name
1000
1070
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 )) {
1003
1073
tblFieldPairArr = append (tblFieldPairArr ,
1004
1074
tblFieldPair {tblName , fieldName })
1005
1075
//Found as leafref, no need to search further
@@ -1030,7 +1100,7 @@ func (c *CVL) addLeafRef(config bool, tableName string, name string, value strin
1030
1100
for _ , leafRef := range modelInfo .tableInfo [tableName ].leafRef [name ] {
1031
1101
1032
1102
//Get reference table name from the path and the leaf name
1033
- matches := reLeafRef .FindStringSubmatch (leafRef )
1103
+ matches := reLeafRef .FindStringSubmatch (leafRef . path )
1034
1104
1035
1105
//We have the leafref table name and the leaf name as well
1036
1106
if (matches != nil && len (matches ) == 5 ) { //whole + 4 sub matches
0 commit comments