Skip to content

Commit dbb3fd5

Browse files
committed
finding backlinks is slow, cache
GCU calls this over and over. We don't want a whole tree reversal each time, cache!
1 parent 7262fe4 commit dbb3fd5

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

src/sonic-yang-mgmt/sonic_yang.py

+38-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ def __init__(self, yang_dir, debug=False, print_log_enabled=True):
2727
self.yangFiles = list()
2828
# map from TABLE in config DB to container and module
2929
self.confDbYangMap = dict()
30+
# map of backlinks dict()[]
31+
self.backlinkMap = None
3032
# JSON format of yang model [similar to pyang conversion]
3133
self.yJson = list()
3234
# config DB json input, will be cropped as yang models
@@ -461,6 +463,25 @@ def _find_data_nodes(self, data_xpath):
461463
list.append(data_set.path())
462464
return list
463465

466+
def _cache_schema_dependencies(self):
467+
if self.backlinkMap is not None:
468+
return
469+
470+
leafRefPaths = self.ctx.find_backlinks_paths(None)
471+
if leafRefPaths is None:
472+
return None
473+
474+
self.backlinkMap = dict()
475+
476+
for path in leafRefPaths:
477+
targets = self.ctx.find_leafref_path_target_paths(path)
478+
if targets is None:
479+
continue
480+
481+
for target in targets:
482+
if self.backlinkMap.get(target) is None:
483+
self.backlinkMap[target] = list()
484+
self.backlinkMap[target].append(path)
464485

465486
"""
466487
find_schema_dependencies(): find the schema dependencies from schema xpath
@@ -470,7 +491,23 @@ def _find_data_nodes(self, data_xpath):
470491
returns: - list of xpath of the dependencies
471492
"""
472493
def _find_schema_dependencies(self, match_path, match_ancestors: bool=False):
473-
return self.ctx.find_backlinks_paths(match_path, match_ancestors=match_ancestors)
494+
# Lazy building of cache
495+
self._cache_schema_dependencies()
496+
497+
if match_path is not None and (match_path == "/" or len(match_path) == 0):
498+
match_path = None
499+
500+
# This is an odd case where you want to know about the subtree. Do a
501+
# string prefix match and create a list.
502+
if match_path is None or match_ancestors is True:
503+
ret = []
504+
for target, leafrefs in my_dict.items():
505+
if match_path is None or target == match_path or target.startswith(match_path + "/"):
506+
ret.extend(leafrefs)
507+
return ret
508+
509+
# Common case
510+
return self.backlinkMap.get(match_path)
474511

475512
"""
476513
load_module_str_name(): load a module based on the provided string and return

0 commit comments

Comments
 (0)