Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: speed up question and answer internals #1272

Merged
merged 4 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/zeroconf/_dns.pxd
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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