From e513eb7994d300bae18c81eff38575c62c0ec1c4 Mon Sep 17 00:00:00 2001 From: Markus Scheidgen <markus.scheidgen@gmail.com> Date: Fri, 27 Sep 2019 20:48:13 +0200 Subject: [PATCH] Added cache to metainfo definition methods. --- nomad/metainfo/metainfo.py | 43 ++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/nomad/metainfo/metainfo.py b/nomad/metainfo/metainfo.py index b97efdd396..553cb252df 100644 --- a/nomad/metainfo/metainfo.py +++ b/nomad/metainfo/metainfo.py @@ -622,11 +622,42 @@ class MObject(metaclass=MObjectMeta): # These placeholder are replaced, once the necessary classes are defined. This process # is referred to as 'bootstrapping'. +_definition_change_counter = 0 + + +def cached(f): + """ A decorator that allows to cache the results of metainfo definition methods. + + The cache will be invalidated whenever a new definition is added. Once all definitions + are loaded, the cache becomes stable and complex derived results become available + instantaneous. + """ + cache = dict(change=-1, value=None) + + def wrapper(*args, **kwargs): + if cache['change'] == _definition_change_counter: + return cache['value'] + + value = f(*args, **kwargs) + cache['change'] == _definition_change_counter + cache['value'] == value + + return value + + return wrapper + + class Definition(MObject): + name: 'Quantity' = None description: 'Quantity' = None links: 'Quantity' = None + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + global _definition_change_counter + _definition_change_counter += 1 + class Quantity(Definition): """Used to define quantities that store a certain piece of (meta-)data. @@ -731,8 +762,8 @@ class Section(Definition): super().__init__(**kwargs) Section.__all_instances.append(self) - # TODO cache - @property + @property # type: ignore + @cached def attributes(self) -> Dict[str, Union['Section', Quantity]]: """ All attribute (sub section and quantity) definitions. """ @@ -740,8 +771,8 @@ class Section(Definition): attributes.update(**self.sub_sections) return attributes - # TODO cache - @property + @property # type: ignore + @cached def quantities(self) -> Dict[str, Quantity]: """ All quantity definition in the given section definition. """ @@ -749,8 +780,8 @@ class Section(Definition): quantity.name: quantity for quantity in self.m_data.get('Quantity', [])} - # TODO cache - @property + @property # type: ignore + @cached def sub_sections(self) -> Dict[str, 'Section']: """ All sub section definitions for this section definition. """ -- GitLab