Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 99a6f98

Browse filesBrowse files
authored
feat: speed up unpacking text records in ServiceInfo (#1212)
1 parent 32a016e commit 99a6f98
Copy full SHA for 99a6f98

File tree

Expand file treeCollapse file tree

1 file changed

+27
-9
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+27
-9
lines changed

‎src/zeroconf/_services/info.py

Copy file name to clipboardExpand all lines: src/zeroconf/_services/info.py
+27-9Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def __init__(
172172
self.priority = priority
173173
self.server = server if server else None
174174
self.server_key = server.lower() if server else None
175-
self._properties: Dict[Union[str, bytes], Optional[Union[str, bytes]]] = {}
175+
self._properties: Optional[Dict[Union[str, bytes], Optional[Union[str, bytes]]]] = None
176176
if isinstance(properties, bytes):
177177
self._set_text(properties)
178178
else:
@@ -226,14 +226,18 @@ def addresses(self, value: List[bytes]) -> None:
226226
self._ipv6_addresses.append(addr)
227227

228228
@property
229-
def properties(self) -> Dict:
229+
def properties(self) -> Dict[Union[str, bytes], Optional[Union[str, bytes]]]:
230230
"""If properties were set in the constructor this property returns the original dictionary
231231
of type `Dict[Union[bytes, str], Any]`.
232232
233233
If properties are coming from the network, after decoding a TXT record, the keys are always
234234
bytes and the values are either bytes, if there was a value, even empty, or `None`, if there
235235
was none. No further decoding is attempted. The type returned is `Dict[bytes, Optional[bytes]]`.
236236
"""
237+
if self._properties is None:
238+
self._unpack_text_into_properties()
239+
if TYPE_CHECKING:
240+
assert self._properties is not None
237241
return self._properties
238242

239243
async def async_wait(self, timeout: float) -> None:
@@ -317,10 +321,10 @@ def parsed_scoped_addresses(self, version: IPVersion = IPVersion.All) -> List[st
317321
for addr in self._ip_addresses_by_version_value(version.value)
318322
]
319323

320-
def _set_properties(self, properties: Dict) -> None:
324+
def _set_properties(self, properties: Dict[Union[str, bytes], Optional[Union[str, bytes]]]) -> None:
321325
"""Sets properties and text of this info from a dictionary"""
322326
self._properties = properties
323-
list_ = []
327+
list_: List[bytes] = []
324328
result = b''
325329
for key, value in properties.items():
326330
if isinstance(key, str):
@@ -338,14 +342,25 @@ def _set_properties(self, properties: Dict) -> None:
338342

339343
def _set_text(self, text: bytes) -> None:
340344
"""Sets properties and text given a text field"""
345+
if text == self.text:
346+
return
341347
self.text = text
348+
# Clear the properties cache
349+
self._properties = None
350+
351+
def _unpack_text_into_properties(self) -> None:
352+
"""Unpacks the text field into properties"""
353+
text = self.text
342354
end = len(text)
343355
if end == 0:
356+
# Properties should be set atomically
357+
# in case another thread is reading them
344358
self._properties = {}
345359
return
360+
346361
result: Dict[Union[str, bytes], Optional[Union[str, bytes]]] = {}
347362
index = 0
348-
strs = []
363+
strs: List[bytes] = []
349364
while index < end:
350365
length = text[index]
351366
index += 1
@@ -355,17 +370,20 @@ def _set_text(self, text: bytes) -> None:
355370
key: bytes
356371
value: Optional[bytes]
357372
for s in strs:
358-
try:
359-
key, value = s.split(b'=', 1)
360-
except ValueError:
373+
key_value = s.split(b'=', 1)
374+
if len(key_value) == 2:
375+
key, value = key_value
376+
else:
361377
# No equals sign at all
362378
key = s
363379
value = None
364380

365381
# Only update non-existent properties
366-
if key and result.get(key) is None:
382+
if key and key not in result:
367383
result[key] = value
368384

385+
# Properties should be set atomically
386+
# in case another thread is reading them
369387
self._properties = result
370388

371389
def get_name(self) -> str:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.