mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 05:47:10 +00:00
Small tweaks to improve performance of bluetooth matching (#77934)
* Small tweaks to improve performance of bluetooth matching * Small tweaks to improve performance of bluetooth matching * cleanup
This commit is contained in:
parent
9ba1bb7c73
commit
dfef6c3d28
@ -180,12 +180,20 @@ class BluetoothMatcherIndexBase(Generic[_T]):
|
|||||||
|
|
||||||
We put them in the bucket that they are most likely to match.
|
We put them in the bucket that they are most likely to match.
|
||||||
"""
|
"""
|
||||||
|
# Local name is the cheapest to match since its just a dict lookup
|
||||||
if LOCAL_NAME in matcher:
|
if LOCAL_NAME in matcher:
|
||||||
self.local_name.setdefault(
|
self.local_name.setdefault(
|
||||||
_local_name_to_index_key(matcher[LOCAL_NAME]), []
|
_local_name_to_index_key(matcher[LOCAL_NAME]), []
|
||||||
).append(matcher)
|
).append(matcher)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Manufacturer data is 2nd cheapest since its all ints
|
||||||
|
if MANUFACTURER_ID in matcher:
|
||||||
|
self.manufacturer_id.setdefault(matcher[MANUFACTURER_ID], []).append(
|
||||||
|
matcher
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if SERVICE_UUID in matcher:
|
if SERVICE_UUID in matcher:
|
||||||
self.service_uuid.setdefault(matcher[SERVICE_UUID], []).append(matcher)
|
self.service_uuid.setdefault(matcher[SERVICE_UUID], []).append(matcher)
|
||||||
return
|
return
|
||||||
@ -196,12 +204,6 @@ class BluetoothMatcherIndexBase(Generic[_T]):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if MANUFACTURER_ID in matcher:
|
|
||||||
self.manufacturer_id.setdefault(matcher[MANUFACTURER_ID], []).append(
|
|
||||||
matcher
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
def remove(self, matcher: _T) -> None:
|
def remove(self, matcher: _T) -> None:
|
||||||
"""Remove a matcher from the index.
|
"""Remove a matcher from the index.
|
||||||
|
|
||||||
@ -214,6 +216,10 @@ class BluetoothMatcherIndexBase(Generic[_T]):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if MANUFACTURER_ID in matcher:
|
||||||
|
self.manufacturer_id[matcher[MANUFACTURER_ID]].remove(matcher)
|
||||||
|
return
|
||||||
|
|
||||||
if SERVICE_UUID in matcher:
|
if SERVICE_UUID in matcher:
|
||||||
self.service_uuid[matcher[SERVICE_UUID]].remove(matcher)
|
self.service_uuid[matcher[SERVICE_UUID]].remove(matcher)
|
||||||
return
|
return
|
||||||
@ -222,10 +228,6 @@ class BluetoothMatcherIndexBase(Generic[_T]):
|
|||||||
self.service_data_uuid[matcher[SERVICE_DATA_UUID]].remove(matcher)
|
self.service_data_uuid[matcher[SERVICE_DATA_UUID]].remove(matcher)
|
||||||
return
|
return
|
||||||
|
|
||||||
if MANUFACTURER_ID in matcher:
|
|
||||||
self.manufacturer_id[matcher[MANUFACTURER_ID]].remove(matcher)
|
|
||||||
return
|
|
||||||
|
|
||||||
def build(self) -> None:
|
def build(self) -> None:
|
||||||
"""Rebuild the index sets."""
|
"""Rebuild the index sets."""
|
||||||
self.service_uuid_set = set(self.service_uuid)
|
self.service_uuid_set = set(self.service_uuid)
|
||||||
@ -235,33 +237,36 @@ class BluetoothMatcherIndexBase(Generic[_T]):
|
|||||||
def match(self, service_info: BluetoothServiceInfoBleak) -> list[_T]:
|
def match(self, service_info: BluetoothServiceInfoBleak) -> list[_T]:
|
||||||
"""Check for a match."""
|
"""Check for a match."""
|
||||||
matches = []
|
matches = []
|
||||||
if len(service_info.name) >= LOCAL_NAME_MIN_MATCH_LENGTH:
|
if service_info.name and len(service_info.name) >= LOCAL_NAME_MIN_MATCH_LENGTH:
|
||||||
for matcher in self.local_name.get(
|
for matcher in self.local_name.get(
|
||||||
service_info.name[:LOCAL_NAME_MIN_MATCH_LENGTH], []
|
service_info.name[:LOCAL_NAME_MIN_MATCH_LENGTH], []
|
||||||
):
|
):
|
||||||
if ble_device_matches(matcher, service_info):
|
if ble_device_matches(matcher, service_info):
|
||||||
matches.append(matcher)
|
matches.append(matcher)
|
||||||
|
|
||||||
for service_data_uuid in self.service_data_uuid_set.intersection(
|
if self.service_data_uuid_set and service_info.service_data:
|
||||||
service_info.service_data
|
for service_data_uuid in self.service_data_uuid_set.intersection(
|
||||||
):
|
service_info.service_data
|
||||||
for matcher in self.service_data_uuid[service_data_uuid]:
|
):
|
||||||
if ble_device_matches(matcher, service_info):
|
for matcher in self.service_data_uuid[service_data_uuid]:
|
||||||
matches.append(matcher)
|
if ble_device_matches(matcher, service_info):
|
||||||
|
matches.append(matcher)
|
||||||
|
|
||||||
for manufacturer_id in self.manufacturer_id_set.intersection(
|
if self.manufacturer_id_set and service_info.manufacturer_data:
|
||||||
service_info.manufacturer_data
|
for manufacturer_id in self.manufacturer_id_set.intersection(
|
||||||
):
|
service_info.manufacturer_data
|
||||||
for matcher in self.manufacturer_id[manufacturer_id]:
|
):
|
||||||
if ble_device_matches(matcher, service_info):
|
for matcher in self.manufacturer_id[manufacturer_id]:
|
||||||
matches.append(matcher)
|
if ble_device_matches(matcher, service_info):
|
||||||
|
matches.append(matcher)
|
||||||
|
|
||||||
for service_uuid in self.service_uuid_set.intersection(
|
if self.service_uuid_set and service_info.service_uuids:
|
||||||
service_info.service_uuids
|
for service_uuid in self.service_uuid_set.intersection(
|
||||||
):
|
service_info.service_uuids
|
||||||
for matcher in self.service_uuid[service_uuid]:
|
):
|
||||||
if ble_device_matches(matcher, service_info):
|
for matcher in self.service_uuid[service_uuid]:
|
||||||
matches.append(matcher)
|
if ble_device_matches(matcher, service_info):
|
||||||
|
matches.append(matcher)
|
||||||
|
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
@ -347,8 +352,6 @@ def ble_device_matches(
|
|||||||
service_info: BluetoothServiceInfoBleak,
|
service_info: BluetoothServiceInfoBleak,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Check if a ble device and advertisement_data matches the matcher."""
|
"""Check if a ble device and advertisement_data matches the matcher."""
|
||||||
device = service_info.device
|
|
||||||
|
|
||||||
# Don't check address here since all callers already
|
# Don't check address here since all callers already
|
||||||
# check the address and we don't want to double check
|
# check the address and we don't want to double check
|
||||||
# since it would result in an unreachable reject case.
|
# since it would result in an unreachable reject case.
|
||||||
@ -379,7 +382,8 @@ def ble_device_matches(
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if (local_name := matcher.get(LOCAL_NAME)) and (
|
if (local_name := matcher.get(LOCAL_NAME)) and (
|
||||||
(device_name := advertisement_data.local_name or device.name) is None
|
(device_name := advertisement_data.local_name or service_info.device.name)
|
||||||
|
is None
|
||||||
or not _memorized_fnmatch(
|
or not _memorized_fnmatch(
|
||||||
device_name,
|
device_name,
|
||||||
local_name,
|
local_name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user