From 787de5aad206e43b60924843c9b1cab3cedcfdf4 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Fri, 2 Sep 2005 05:23:26 +0000 Subject: [PATCH] Add indexing to Message.find_rrset() Original author: Bob Halley Date: 2004-08-14 20:17:32 --- ChangeLog | 8 +++++++- dns/message.py | 30 ++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 72bbda3a..e9cbfe69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,14 @@ +2004-08-14 Bob Halley + + * dns/message.py (Message.find_rrset): find_rrset() now uses an + index, vastly improving the from_wire() performance of large + messages such as zone transfers. + 2004-08-07 Bob Halley * (Version 1.3.2 released) -2004-08-04 Bob Halley +2004-08-04 Bob Halley * dns/query.py: sending queries to a nameserver via IPv6 now works. diff --git a/dns/message.py b/dns/message.py index e46470ed..007fb974 100644 --- a/dns/message.py +++ b/dns/message.py @@ -122,6 +122,10 @@ class Message(object): message sequence? This variable is used when validating TSIG signatures on messages which are part of a zone transfer. @type first: bool + @ivar index: An index of rrsets in the message. The index key is + (section, name, rdclass, rdtype, covers, deleting). Indexing can be + disabled by setting the index to None. + @type index: dict """ def __init__(self, id=None): @@ -151,6 +155,7 @@ class Message(object): self.had_tsig = False self.multi = False self.first = True + self.index = {} def __repr__(self): return '' @@ -265,6 +270,18 @@ class Message(object): return False return True + def section_number(self, section): + if section is self.question: + return 0 + elif section is self.answer: + return 1 + elif section is self.authority: + return 2 + elif section is self.additional: + return 3 + else: + raise ValueError, 'unknown section' + def find_rrset(self, section, name, rdclass, rdtype, covers=dns.rdatatype.NONE, deleting=None, create=False, force_unique=False): @@ -292,14 +309,23 @@ class Message(object): @raises KeyError: the RRset was not found and create was False @rtype: dns.rrset.RRset object""" + key = (self.section_number(section), + name, rdclass, rdtype, covers, deleting) if not force_unique: - for rrset in section: - if rrset.match(name, rdclass, rdtype, covers, deleting): + if not self.index is None: + rrset = self.index.get(key) + if not rrset is None: return rrset + else: + for rrset in section: + if rrset.match(name, rdclass, rdtype, covers, deleting): + return rrset if not create: raise KeyError rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting) section.append(rrset) + if not self.index is None: + self.index[key] = rrset return rrset def get_rrset(self, section, name, rdclass, rdtype, -- 2.47.3