Limit cache size of EntityValues (#94983)

This commit is contained in:
J. Nick Koston 2023-06-21 22:23:35 +02:00 committed by GitHub
parent 90386bc036
commit 8d2daaa694
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 8 deletions

View File

@ -3,14 +3,24 @@ from __future__ import annotations
from collections import OrderedDict
import fnmatch
from functools import lru_cache
import re
from typing import Any
from homeassistant.core import split_entity_id
_MAX_EXPECTED_ENTITIES = 16384
class EntityValues:
"""Class to store entity id based values."""
"""Class to store entity id based values.
This class is expected to only be used infrequently
as it caches all entity ids up to _MAX_EXPECTED_ENTITIES.
The cache includes `self` so it is important to
only use this in places where usage of `EntityValues` is immortal.
"""
def __init__(
self,
@ -19,7 +29,6 @@ class EntityValues:
glob: dict[str, dict[str, str]] | None = None,
) -> None:
"""Initialize an EntityConfigDict."""
self._cache: dict[str, dict[str, str]] = {}
self._exact = exact
self._domain = domain
@ -32,13 +41,11 @@ class EntityValues:
self._glob = compiled
@lru_cache(maxsize=_MAX_EXPECTED_ENTITIES)
def get(self, entity_id: str) -> dict[str, str]:
"""Get config for an entity id."""
if entity_id in self._cache:
return self._cache[entity_id]
domain, _ = split_entity_id(entity_id)
result = self._cache[entity_id] = {}
result: dict[str, str] = {}
if self._domain is not None and domain in self._domain:
result.update(self._domain[domain])

View File

@ -10,9 +10,12 @@ def test_override_single_value() -> None:
"""Test values with exact match."""
store = EV({ent: {"key": "value"}})
assert store.get(ent) == {"key": "value"}
assert len(store._cache) == 1
assert store.get.cache_info().currsize == 1
assert store.get.cache_info().misses == 1
assert store.get(ent) == {"key": "value"}
assert len(store._cache) == 1
assert store.get.cache_info().currsize == 1
assert store.get.cache_info().misses == 1
assert store.get.cache_info().hits == 1
def test_override_by_domain() -> None: