changeset 499:f46932e8a84c

Configuration._lookupvar() now uses an internal cache (positive and negative). This give a nice performance boost.
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 18 Dec 2021 00:43:36 +0100
parents e7c82706b67a
children 34cd4f111134
files configmix/config.py
diffstat 1 files changed, 21 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/configmix/config.py	Sat Dec 18 00:00:36 2021 +0100
+++ b/configmix/config.py	Sat Dec 18 00:43:36 2021 +0100
@@ -33,6 +33,7 @@
 
 
 _MARKER = object()
+_MISSING = object()
 
 
 class _AttributeDict(ConfigurationBase):
@@ -263,6 +264,13 @@
     is_jail = False
     """Flag to show that this is not a jail for another configuration"""
 
+    def __init__(self, *args, **kwds):
+        #
+        # PY2.7 compat: must be set before calling the superclass' __init__
+        #
+        self.__cache = {}
+        super(Configuration, self).__init__(*args, **kwds)
+
     def __getitem__(self, key):
         """Mapping and list interface that forwards to :meth:`~.getvarl_s`
 
@@ -580,15 +588,28 @@
         """
         if not path:
             return self
+        v = self.__cache.get(path, _MARKER)
+        if v is not _MARKER:
+            if v is _MISSING:
+                raise KeyError(
+                    "Configuration variable %r not found"
+                    " (negative internal cache value)" % (path,))
+            else:
+                return v
         eiref = self.expand_if_reference
         try:
             v = eiref(super(Configuration, self).__getitem__(path[0]))
             for p in path[1:]:
                 v = eiref(v[p])
         except TypeError:
+            self.__cache[path] = _MISSING
             raise KeyError(
                 "Configuration variable %r not found"
                 "(missing intermediate keys?)" % (path,))
+        except KeyError:
+            self.__cache[path] = _MISSING
+            raise
+        self.__cache[path] = v
         return v
 
     def _lookupref(self, key, default=_MARKER):