Skip to content

Commit

Permalink
feat: speed up question and answer internals (#1272)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Sep 14, 2023
1 parent 549a104 commit d24722b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 24 deletions.
8 changes: 4 additions & 4 deletions src/zeroconf/_dns.pxd
Expand Up @@ -22,8 +22,8 @@ cdef object current_time_millis

cdef class DNSEntry:

cdef public object key
cdef public object name
cdef public str key
cdef public str name
cdef public object type
cdef public object class_
cdef public object unique
Expand Down Expand Up @@ -84,8 +84,8 @@ cdef class DNSHinfo(DNSRecord):
cdef class DNSPointer(DNSRecord):

cdef public cython.int _hash
cdef public object alias
cdef public object alias_key
cdef public str alias
cdef public str alias_key

cdef _eq(self, DNSPointer other)

Expand Down
6 changes: 3 additions & 3 deletions src/zeroconf/_dns.py
Expand Up @@ -67,9 +67,9 @@ class DNSEntry:

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

def __init__(self, name: str, type_: int, class_: int) -> None:
self.key = name.lower()
def __init__(self, name: str, type_: _int, class_: _int) -> None:
self.name = name
self.key = name.lower()
self.type = type_
self.class_ = class_ & _CLASS_MASK
self.unique = (class_ & _CLASS_UNIQUE) != 0
Expand Down Expand Up @@ -328,7 +328,7 @@ def __init__(
) -> None:
super().__init__(name, type_, class_, ttl, created)
self.alias = alias
self.alias_key = self.alias.lower()
self.alias_key = alias.lower()
self._hash = hash((self.key, type_, self.class_, self.alias_key))

@property
Expand Down
17 changes: 17 additions & 0 deletions src/zeroconf/_handlers/answers.pxd
Expand Up @@ -5,6 +5,23 @@ from .._dns cimport DNSRecord
from .._protocol.outgoing cimport DNSOutgoing


cdef class QuestionAnswers:

cdef public object ucast
cdef public object mcast_now
cdef public object mcast_aggregate
cdef public object mcast_aggregate_last_second


cdef class AnswerGroup:

cdef public object send_after
cdef public object send_before
cdef public object answers




cdef object _FLAGS_QR_RESPONSE_AA
cdef object NAME_GETTER

Expand Down
37 changes: 27 additions & 10 deletions src/zeroconf/_handlers/answers.py
Expand Up @@ -21,7 +21,7 @@
"""

from operator import attrgetter
from typing import Dict, List, NamedTuple, Set
from typing import Dict, List, Set

from .._dns import DNSQuestion, DNSRecord
from .._protocol.outgoing import DNSOutgoing
Expand All @@ -38,20 +38,37 @@

_FLAGS_QR_RESPONSE_AA = _FLAGS_QR_RESPONSE | _FLAGS_AA

float_ = float

class QuestionAnswers(NamedTuple):
ucast: _AnswerWithAdditionalsType
mcast_now: _AnswerWithAdditionalsType
mcast_aggregate: _AnswerWithAdditionalsType
mcast_aggregate_last_second: _AnswerWithAdditionalsType

class QuestionAnswers:
"""A group of answers to a question."""

class AnswerGroup(NamedTuple):
__slots__ = ('ucast', 'mcast_now', 'mcast_aggregate', 'mcast_aggregate_last_second')

def __init__(
self,
ucast: _AnswerWithAdditionalsType,
mcast_now: _AnswerWithAdditionalsType,
mcast_aggregate: _AnswerWithAdditionalsType,
mcast_aggregate_last_second: _AnswerWithAdditionalsType,
) -> None:
"""Initialize a QuestionAnswers."""
self.ucast = ucast
self.mcast_now = mcast_now
self.mcast_aggregate = mcast_aggregate
self.mcast_aggregate_last_second = mcast_aggregate_last_second


class AnswerGroup:
"""A group of answers scheduled to be sent at the same time."""

send_after: float # Must be sent after this time
send_before: float # Must be sent before this time
answers: _AnswerWithAdditionalsType
__slots__ = ('send_after', 'send_before', 'answers')

def __init__(self, send_after: float_, send_before: float_, answers: _AnswerWithAdditionalsType) -> None:
self.send_after = send_after # Must be sent after this time
self.send_before = send_before # Must be sent before this time
self.answers = answers


def construct_outgoing_multicast_answers(answers: _AnswerWithAdditionalsType) -> DNSOutgoing:
Expand Down
17 changes: 10 additions & 7 deletions src/zeroconf/_handlers/query_handler.pxd
Expand Up @@ -2,14 +2,15 @@
import cython

from .._cache cimport DNSCache
from .._dns cimport DNSPointer, DNSQuestion, DNSRecord, DNSRRSet
from .._dns cimport DNSAddress, DNSPointer, DNSQuestion, DNSRecord, DNSRRSet
from .._history cimport QuestionHistory
from .._protocol.incoming cimport DNSIncoming
from .._services.info cimport ServiceInfo
from .._services.registry cimport ServiceRegistry
from .answers cimport QuestionAnswers


cdef object TYPE_CHECKING, QuestionAnswers
cdef object TYPE_CHECKING
cdef cython.uint _ONE_SECOND, _TYPE_PTR, _TYPE_ANY, _TYPE_A, _TYPE_AAAA, _TYPE_SRV, _TYPE_TXT
cdef str _SERVICE_TYPE_ENUMERATION_NAME
cdef cython.set _RESPOND_IMMEDIATE_TYPES
Expand All @@ -19,7 +20,7 @@ cdef object _TYPE_PTR, _CLASS_IN, _DNS_OTHER_TTL

cdef class _QueryResponse:

cdef object _is_probe
cdef bint _is_probe
cdef DNSIncoming _msg
cdef float _now
cdef DNSCache _cache
Expand All @@ -29,17 +30,19 @@ cdef class _QueryResponse:
cdef cython.set _mcast_aggregate
cdef cython.set _mcast_aggregate_last_second

@cython.locals(record=DNSRecord)
cpdef add_qu_question_response(self, cython.dict answers)

cpdef add_ucast_question_response(self, cython.dict answers)

@cython.locals(answer=DNSRecord)
cpdef add_mcast_question_response(self, cython.dict answers)

@cython.locals(maybe_entry=DNSRecord)
cpdef _has_mcast_within_one_quarter_ttl(self, DNSRecord record)
cdef bint _has_mcast_within_one_quarter_ttl(self, DNSRecord record)

@cython.locals(maybe_entry=DNSRecord)
cpdef _has_mcast_record_in_last_second(self, DNSRecord record)
cdef bint _has_mcast_record_in_last_second(self, DNSRecord record)

cpdef answers(self)

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

@cython.locals(service=ServiceInfo)
cdef _add_address_answers(self, str lower_name, cython.dict answer_set, DNSRRSet known_answers, cython.uint type_)
@cython.locals(service=ServiceInfo, dns_address=DNSAddress)
cdef _add_address_answers(self, str lower_name, cython.dict answer_set, DNSRRSet known_answers, object type_)

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

0 comments on commit d24722b

Please sign in to comment.