mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 11:47:06 +00:00
Avoid linear search to remove from the entity registry index (#111138)
Avoid linear search to remove from entity registry index Because the entity registry index needs to preserve insertion order for backwards compat, a list was used for the index. Because some config entries/devices/areas have a large amount of entities, removing the entities, the O(n) time complexity of removing from a list can slow down reloads. As python has no orderedset in stdlib, use a dict since it preserves insertion order has O(1) add/remove time complexity for the average case
This commit is contained in:
parent
b5a2df1951
commit
125de17a09
@ -455,9 +455,9 @@ class EntityRegistryItems(UserDict[str, RegistryEntry]):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self._entry_ids: dict[str, RegistryEntry] = {}
|
self._entry_ids: dict[str, RegistryEntry] = {}
|
||||||
self._index: dict[tuple[str, str, str], str] = {}
|
self._index: dict[tuple[str, str, str], str] = {}
|
||||||
self._config_entry_id_index: dict[str, list[str]] = {}
|
self._config_entry_id_index: dict[str, dict[str, Literal[True]]] = {}
|
||||||
self._device_id_index: dict[str, list[str]] = {}
|
self._device_id_index: dict[str, dict[str, Literal[True]]] = {}
|
||||||
self._area_id_index: dict[str, list[str]] = {}
|
self._area_id_index: dict[str, dict[str, Literal[True]]] = {}
|
||||||
|
|
||||||
def values(self) -> ValuesView[RegistryEntry]:
|
def values(self) -> ValuesView[RegistryEntry]:
|
||||||
"""Return the underlying values to avoid __iter__ overhead."""
|
"""Return the underlying values to avoid __iter__ overhead."""
|
||||||
@ -471,15 +471,17 @@ class EntityRegistryItems(UserDict[str, RegistryEntry]):
|
|||||||
data[key] = entry
|
data[key] = entry
|
||||||
self._entry_ids[entry.id] = entry
|
self._entry_ids[entry.id] = entry
|
||||||
self._index[(entry.domain, entry.platform, entry.unique_id)] = entry.entity_id
|
self._index[(entry.domain, entry.platform, entry.unique_id)] = entry.entity_id
|
||||||
|
# python has no ordered set, so we use a dict with True values
|
||||||
|
# https://discuss.python.org/t/add-orderedset-to-stdlib/12730
|
||||||
if (config_entry_id := entry.config_entry_id) is not None:
|
if (config_entry_id := entry.config_entry_id) is not None:
|
||||||
self._config_entry_id_index.setdefault(config_entry_id, []).append(key)
|
self._config_entry_id_index.setdefault(config_entry_id, {})[key] = True
|
||||||
if (device_id := entry.device_id) is not None:
|
if (device_id := entry.device_id) is not None:
|
||||||
self._device_id_index.setdefault(device_id, []).append(key)
|
self._device_id_index.setdefault(device_id, {})[key] = True
|
||||||
if (area_id := entry.area_id) is not None:
|
if (area_id := entry.area_id) is not None:
|
||||||
self._area_id_index.setdefault(area_id, []).append(key)
|
self._area_id_index.setdefault(area_id, {})[key] = True
|
||||||
|
|
||||||
def _unindex_entry_value(
|
def _unindex_entry_value(
|
||||||
self, key: str, value: str, index: dict[str, list[str]]
|
self, key: str, value: str, index: dict[str, dict[str, Literal[True]]]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Unindex an entry value.
|
"""Unindex an entry value.
|
||||||
|
|
||||||
@ -488,7 +490,7 @@ class EntityRegistryItems(UserDict[str, RegistryEntry]):
|
|||||||
index is the index to unindex from.
|
index is the index to unindex from.
|
||||||
"""
|
"""
|
||||||
entries = index[value]
|
entries = index[value]
|
||||||
entries.remove(key)
|
del entries[key]
|
||||||
if not entries:
|
if not entries:
|
||||||
del index[value]
|
del index[value]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user