feat: optimize cache implementation (#1252) · python-zeroconf/python-zeroconf@8d3ec79
@@ -20,7 +20,6 @@
2020 USA
2121"""
222223-import itertools
2423from typing import Dict, Iterable, List, Optional, Set, Tuple, Union, cast
25242625from ._dns import (
@@ -115,12 +114,12 @@ def async_remove_records(self, entries: Iterable[DNSRecord]) -> None:
115114for entry in entries:
116115self._async_remove(entry)
117116118-def async_expire(self, now: float) -> List[DNSRecord]:
117+def async_expire(self, now: _float) -> List[DNSRecord]:
119118"""Purge expired entries from the cache.
120119121120 This function must be run in from event loop.
122121 """
123-expired = [record for record in itertools.chain(*self.cache.values()) if record.is_expired(now)]
122+expired = [record for records in self.cache.values() for record in records if record.is_expired(now)]
124123self.async_remove_records(expired)
125124return expired
126125@@ -136,15 +135,7 @@ def async_get_unique(self, entry: _UniqueRecordsType) -> Optional[DNSRecord]:
136135return None
137136return store.get(entry)
138137139-def async_all_by_details(self, name: _str, type_: int, class_: int) -> Iterable[DNSRecord]:
140-"""Gets all matching entries by details.
141-142- This function is not thread-safe and must be called from
143- the event loop.
144- """
145-return self._async_all_by_details(name, type_, class_)
146-147-def _async_all_by_details(self, name: _str, type_: _int, class_: _int) -> List[DNSRecord]:
138+def async_all_by_details(self, name: _str, type_: _int, class_: _int) -> List[DNSRecord]:
148139"""Gets all matching entries by details.
149140150141 This function is not thread-safe and must be called from
@@ -240,20 +231,16 @@ def names(self) -> List[str]:
240231241232def async_mark_unique_records_older_than_1s_to_expire(
242233self, unique_types: Set[Tuple[_str, _int, _int]], answers: Iterable[DNSRecord], now: _float
243- ) -> None:
244-self._async_mark_unique_records_older_than_1s_to_expire(unique_types, answers, now)
245-246-def _async_mark_unique_records_older_than_1s_to_expire(
247-self, unique_types: Set[Tuple[_str, _int, _int]], answers: Iterable[DNSRecord], now: _float
248234 ) -> None:
249235# rfc6762#section-10.2 para 2
250236# Since unique is set, all old records with that name, rrtype,
251237# and rrclass that were received more than one second ago are declared
252238# invalid, and marked to expire from the cache in one second.
253239answers_rrset = set(answers)
254240for name, type_, class_ in unique_types:
255-for record in self._async_all_by_details(name, type_, class_):
256-if (now - record.created > _ONE_SECOND) and record not in answers_rrset:
241+for record in self.async_all_by_details(name, type_, class_):
242+created_float = record.created
243+if (now - created_float > _ONE_SECOND) and record not in answers_rrset:
257244# Expire in 1s
258245record.set_created_ttl(now, 1)
259246