Skip to content

Commit d24722b

Browse files
authored
feat: speed up question and answer internals (#1272)
1 parent 549a104 commit d24722b

5 files changed

Lines changed: 61 additions & 24 deletions

File tree

src/zeroconf/_dns.pxd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ cdef object current_time_millis
2222

2323
cdef class DNSEntry:
2424

25-
cdef public object key
26-
cdef public object name
25+
cdef public str key
26+
cdef public str name
2727
cdef public object type
2828
cdef public object class_
2929
cdef public object unique
@@ -84,8 +84,8 @@ cdef class DNSHinfo(DNSRecord):
8484
cdef class DNSPointer(DNSRecord):
8585

8686
cdef public cython.int _hash
87-
cdef public object alias
88-
cdef public object alias_key
87+
cdef public str alias
88+
cdef public str alias_key
8989

9090
cdef _eq(self, DNSPointer other)
9191

src/zeroconf/_dns.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ class DNSEntry:
6767

6868
__slots__ = ('key', 'name', 'type', 'class_', 'unique')
6969

70-
def __init__(self, name: str, type_: int, class_: int) -> None:
71-
self.key = name.lower()
70+
def __init__(self, name: str, type_: _int, class_: _int) -> None:
7271
self.name = name
72+
self.key = name.lower()
7373
self.type = type_
7474
self.class_ = class_ & _CLASS_MASK
7575
self.unique = (class_ & _CLASS_UNIQUE) != 0
@@ -328,7 +328,7 @@ def __init__(
328328
) -> None:
329329
super().__init__(name, type_, class_, ttl, created)
330330
self.alias = alias
331-
self.alias_key = self.alias.lower()
331+
self.alias_key = alias.lower()
332332
self._hash = hash((self.key, type_, self.class_, self.alias_key))
333333

334334
@property

src/zeroconf/_handlers/answers.pxd

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ from .._dns cimport DNSRecord
55
from .._protocol.outgoing cimport DNSOutgoing
66

77

8+
cdef class QuestionAnswers:
9+
10+
cdef public object ucast
11+
cdef public object mcast_now
12+
cdef public object mcast_aggregate
13+
cdef public object mcast_aggregate_last_second
14+
15+
16+
cdef class AnswerGroup:
17+
18+
cdef public object send_after
19+
cdef public object send_before
20+
cdef public object answers
21+
22+
23+
24+
825
cdef object _FLAGS_QR_RESPONSE_AA
926
cdef object NAME_GETTER
1027

src/zeroconf/_handlers/answers.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"""
2222

2323
from operator import attrgetter
24-
from typing import Dict, List, NamedTuple, Set
24+
from typing import Dict, List, Set
2525

2626
from .._dns import DNSQuestion, DNSRecord
2727
from .._protocol.outgoing import DNSOutgoing
@@ -38,20 +38,37 @@
3838

3939
_FLAGS_QR_RESPONSE_AA = _FLAGS_QR_RESPONSE | _FLAGS_AA
4040

41+
float_ = float
4142

42-
class QuestionAnswers(NamedTuple):
43-
ucast: _AnswerWithAdditionalsType
44-
mcast_now: _AnswerWithAdditionalsType
45-
mcast_aggregate: _AnswerWithAdditionalsType
46-
mcast_aggregate_last_second: _AnswerWithAdditionalsType
4743

44+
class QuestionAnswers:
45+
"""A group of answers to a question."""
4846

49-
class AnswerGroup(NamedTuple):
47+
__slots__ = ('ucast', 'mcast_now', 'mcast_aggregate', 'mcast_aggregate_last_second')
48+
49+
def __init__(
50+
self,
51+
ucast: _AnswerWithAdditionalsType,
52+
mcast_now: _AnswerWithAdditionalsType,
53+
mcast_aggregate: _AnswerWithAdditionalsType,
54+
mcast_aggregate_last_second: _AnswerWithAdditionalsType,
55+
) -> None:
56+
"""Initialize a QuestionAnswers."""
57+
self.ucast = ucast
58+
self.mcast_now = mcast_now
59+
self.mcast_aggregate = mcast_aggregate
60+
self.mcast_aggregate_last_second = mcast_aggregate_last_second
61+
62+
63+
class AnswerGroup:
5064
"""A group of answers scheduled to be sent at the same time."""
5165

52-
send_after: float # Must be sent after this time
53-
send_before: float # Must be sent before this time
54-
answers: _AnswerWithAdditionalsType
66+
__slots__ = ('send_after', 'send_before', 'answers')
67+
68+
def __init__(self, send_after: float_, send_before: float_, answers: _AnswerWithAdditionalsType) -> None:
69+
self.send_after = send_after # Must be sent after this time
70+
self.send_before = send_before # Must be sent before this time
71+
self.answers = answers
5572

5673

5774
def construct_outgoing_multicast_answers(answers: _AnswerWithAdditionalsType) -> DNSOutgoing:

src/zeroconf/_handlers/query_handler.pxd

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
import cython
33

44
from .._cache cimport DNSCache
5-
from .._dns cimport DNSPointer, DNSQuestion, DNSRecord, DNSRRSet
5+
from .._dns cimport DNSAddress, DNSPointer, DNSQuestion, DNSRecord, DNSRRSet
66
from .._history cimport QuestionHistory
77
from .._protocol.incoming cimport DNSIncoming
88
from .._services.info cimport ServiceInfo
99
from .._services.registry cimport ServiceRegistry
10+
from .answers cimport QuestionAnswers
1011

1112

12-
cdef object TYPE_CHECKING, QuestionAnswers
13+
cdef object TYPE_CHECKING
1314
cdef cython.uint _ONE_SECOND, _TYPE_PTR, _TYPE_ANY, _TYPE_A, _TYPE_AAAA, _TYPE_SRV, _TYPE_TXT
1415
cdef str _SERVICE_TYPE_ENUMERATION_NAME
1516
cdef cython.set _RESPOND_IMMEDIATE_TYPES
@@ -19,7 +20,7 @@ cdef object _TYPE_PTR, _CLASS_IN, _DNS_OTHER_TTL
1920

2021
cdef class _QueryResponse:
2122

22-
cdef object _is_probe
23+
cdef bint _is_probe
2324
cdef DNSIncoming _msg
2425
cdef float _now
2526
cdef DNSCache _cache
@@ -29,17 +30,19 @@ cdef class _QueryResponse:
2930
cdef cython.set _mcast_aggregate
3031
cdef cython.set _mcast_aggregate_last_second
3132

33+
@cython.locals(record=DNSRecord)
3234
cpdef add_qu_question_response(self, cython.dict answers)
3335

3436
cpdef add_ucast_question_response(self, cython.dict answers)
3537

38+
@cython.locals(answer=DNSRecord)
3639
cpdef add_mcast_question_response(self, cython.dict answers)
3740

3841
@cython.locals(maybe_entry=DNSRecord)
39-
cpdef _has_mcast_within_one_quarter_ttl(self, DNSRecord record)
42+
cdef bint _has_mcast_within_one_quarter_ttl(self, DNSRecord record)
4043

4144
@cython.locals(maybe_entry=DNSRecord)
42-
cpdef _has_mcast_record_in_last_second(self, DNSRecord record)
45+
cdef bint _has_mcast_record_in_last_second(self, DNSRecord record)
4346

4447
cpdef answers(self)
4548

@@ -55,8 +58,8 @@ cdef class QueryHandler:
5558
@cython.locals(service=ServiceInfo)
5659
cdef _add_pointer_answers(self, str lower_name, cython.dict answer_set, DNSRRSet known_answers)
5760

58-
@cython.locals(service=ServiceInfo)
59-
cdef _add_address_answers(self, str lower_name, cython.dict answer_set, DNSRRSet known_answers, cython.uint type_)
61+
@cython.locals(service=ServiceInfo, dns_address=DNSAddress)
62+
cdef _add_address_answers(self, str lower_name, cython.dict answer_set, DNSRRSet known_answers, object type_)
6063

6164
@cython.locals(question_lower_name=str, type_=cython.uint, service=ServiceInfo)
6265
cdef cython.dict _answer_question(self, DNSQuestion question, DNSRRSet known_answers)

0 commit comments

Comments
 (0)