Skip to content

Commit

Permalink
Improve get_interface_attr speed through caching
Browse files Browse the repository at this point in the history
  • Loading branch information
fahhem committed Dec 23, 2024
1 parent 68c0996 commit 976bea3
Showing 1 changed file with 31 additions and 17 deletions.
48 changes: 31 additions & 17 deletions opendbc/car/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,28 +375,42 @@ def update(self, CC: structs.CarControl, CS: CarStateBase, now_nanos: int) -> tu

# interface-specific helpers

_brand_values = {} # attr_file => brand_name => module
_brand_names = None
def get_interface_attr(attr: str, combine_brands: bool = False, ignore_none: bool = False) -> dict[str | StrEnum, Any]:
global _brand_names
# read all the folders in opendbc/car and return a dict where:
# - keys are all the car models or brand names
# - values are attr values from all car folders
result = {}
for car_folder in sorted([x[0] for x in os.walk(BASEDIR)]):
try:
brand_name = car_folder.split('/')[-1]
brand_values = __import__(f'opendbc.car.{brand_name}.{INTERFACE_ATTR_FILE.get(attr, "values")}', fromlist=[attr])
if hasattr(brand_values, attr) or not ignore_none:
attr_data = getattr(brand_values, attr, None)
else:
continue

if combine_brands:
if isinstance(attr_data, dict):
for f, v in attr_data.items():
result[f] = v
else:
result[brand_name] = attr_data
except (ImportError, OSError):
pass
attr_file = INTERFACE_ATTR_FILE.get(attr, "values")
if _brand_names is None:
_brand_names = [folder.split('/')[-1] for folder in sorted(x[0] for x in os.walk(BASEDIR))]
if attr_file not in _brand_values:
_brand_values[attr_file] = {}
for brand_name in _brand_names:
try:
brand_values = __import__(f'opendbc.car.{brand_name}.{attr_file}', fromlist=[attr])
_brand_values[attr_file][brand_name] = brand_values
except (ImportError, OSError):
pass

for brand_name in _brand_names:
brand_values = _brand_values[attr_file].get(brand_name)
if brand_values is None:
# This was an ImportError or OSError, so we skip it
continue
if hasattr(brand_values, attr) or not ignore_none:
attr_data = getattr(brand_values, attr, None)
else:
continue

if combine_brands:
if isinstance(attr_data, dict):
for f, v in attr_data.items():
result[f] = v
else:
result[brand_name] = attr_data

return result

Expand Down

0 comments on commit 976bea3

Please sign in to comment.