summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2005-09-02 05:23:26 +0000
committerBob Halley <halley@dnspython.org>2005-09-02 05:23:26 +0000
commit787de5aad206e43b60924843c9b1cab3cedcfdf4 (patch)
treeb3c0c72dddd7d56eb8e40606848e80911aef9f2c
parenteb780473bcef6052ef937ab66fc2cd2f4faeb154 (diff)
downloaddnspython-787de5aad206e43b60924843c9b1cab3cedcfdf4.tar.gz
Add indexing to Message.find_rrset()
Original author: Bob Halley <halley@dnspython.org> Date: 2004-08-14 20:17:32
-rw-r--r--ChangeLog8
-rw-r--r--dns/message.py30
2 files changed, 35 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 72bbda3..e9cbfe6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,14 @@
+2004-08-14 Bob Halley <halley@dnspython.org>
+
+ * 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 <halley@dnspython.org>
* (Version 1.3.2 released)
-2004-08-04 Bob Halley <halley@nominum.com>
+2004-08-04 Bob Halley <halley@dnspython.org>
* dns/query.py: sending queries to a nameserver via IPv6 now
works.
diff --git a/dns/message.py b/dns/message.py
index e46470e..007fb97 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 '<DNS message, ID ' + `self.id` + '>'
@@ -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,