]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Optimize get_rdata_class().
authorBrian Wellington <bwelling@xbill.org>
Thu, 2 Apr 2020 16:30:34 +0000 (09:30 -0700)
committerBrian Wellington <bwelling@xbill.org>
Thu, 2 Apr 2020 16:30:34 +0000 (09:30 -0700)
This replaces the module cache with a class cache, so that the getattr()
call to retrieve the class happens only when a new type module is
loaded, not in the common case.  This also allows avoiding the calls to
dns.rdataclass.to_text() and dns.rdatatype.to_text() in the common case.

dns/rdata.py

index 9354418d40c2d472f9a097a38937c461f5c86155..1110e8f42129c688c61871f0289621873597acbd 100644 (file)
@@ -317,31 +317,31 @@ class GenericRdata(Rdata):
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
         return cls(rdclass, rdtype, wire[current: current + rdlen])
 
-_rdata_modules = {}
+_rdata_classes = {}
 _module_prefix = 'dns.rdtypes'
 
 def get_rdata_class(rdclass, rdtype):
-    mod = _rdata_modules.get((rdclass, rdtype))
-    rdclass_text = dns.rdataclass.to_text(rdclass)
-    rdtype_text = dns.rdatatype.to_text(rdtype)
-    rdtype_text = rdtype_text.replace('-', '_')
-    if not mod:
-        mod = _rdata_modules.get((dns.rdatatype.ANY, rdtype))
-        if not mod:
+    cls = _rdata_classes.get((rdclass, rdtype))
+    if not cls:
+        cls = _rdata_classes.get((dns.rdatatype.ANY, rdtype))
+        if not cls:
+            rdclass_text = dns.rdataclass.to_text(rdclass)
+            rdtype_text = dns.rdatatype.to_text(rdtype)
+            rdtype_text = rdtype_text.replace('-', '_')
             try:
                 mod = import_module('.'.join([_module_prefix,
                                               rdclass_text, rdtype_text]))
-                _rdata_modules[(rdclass, rdtype)] = mod
+                cls = getattr(mod, rdtype_text)
+                _rdata_classes[(rdclass, rdtype)] = cls
             except ImportError:
                 try:
                     mod = import_module('.'.join([_module_prefix,
                                                   'ANY', rdtype_text]))
-                    _rdata_modules[(dns.rdataclass.ANY, rdtype)] = mod
+                    cls = getattr(mod, rdtype_text)
+                    _rdata_classes[(dns.rdataclass.ANY, rdtype)] = cls
                 except ImportError:
-                    mod = None
-    if mod:
-        cls = getattr(mod, rdtype_text)
-    else:
+                    pass
+    if not cls:
         cls = GenericRdata
     return cls
 
@@ -461,5 +461,6 @@ def register_type(implementation, rdtype, rdtype_text, is_singleton=False,
     existing_cls = get_rdata_class(rdclass, rdtype)
     if existing_cls != GenericRdata:
         raise RdatatypeExists(rdclass=rdclass, rdtype=rdtype)
-    _rdata_modules[(rdclass, rdtype)] = implementation
+    _rdata_classes[(rdclass, rdtype)] = getattr(implementation,
+                                                rdtype_text.replace('-', '_'))
     dns.rdatatype.register_type(rdtype, rdtype_text, is_singleton)