Reduce overhead to compile statistics (#106927)
* Reduce overhead to compile statistics statistics uses LazyState for compatibility with State when pulling data from the database. After the previous round of refactoring to modern history, the setters are never called and can be removed. * reduce
This commit is contained in:
parent
d04e2d56da
commit
acf78664e2
2 changed files with 26 additions and 71 deletions
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||
|
||||
from datetime import datetime
|
||||
import logging
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from sqlalchemy.engine.row import Row
|
||||
|
||||
|
@ -17,10 +17,16 @@ from homeassistant.core import Context, State
|
|||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .state_attributes import decode_attributes_from_source
|
||||
from .time import process_timestamp
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from functools import cached_property
|
||||
else:
|
||||
from homeassistant.backports.functools import cached_property
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
EMPTY_CONTEXT = Context(id=None)
|
||||
|
||||
|
||||
def extract_metadata_ids(
|
||||
entity_id_to_metadata_id: dict[str, int | None],
|
||||
|
@ -36,15 +42,6 @@ def extract_metadata_ids(
|
|||
class LazyState(State):
|
||||
"""A lazy version of core State after schema 31."""
|
||||
|
||||
__slots__ = [
|
||||
"_row",
|
||||
"_attributes",
|
||||
"_last_changed_ts",
|
||||
"_last_updated_ts",
|
||||
"_context",
|
||||
"attr_cache",
|
||||
]
|
||||
|
||||
def __init__( # pylint: disable=super-init-not-called
|
||||
self,
|
||||
row: Row,
|
||||
|
@ -61,61 +58,35 @@ class LazyState(State):
|
|||
self.state = state or ""
|
||||
self._attributes: dict[str, Any] | None = None
|
||||
self._last_updated_ts: float | None = last_updated_ts or start_time_ts
|
||||
self._last_changed_ts: float | None = None
|
||||
self._context: Context | None = None
|
||||
self.attr_cache = attr_cache
|
||||
self.context = EMPTY_CONTEXT
|
||||
|
||||
@property # type: ignore[override]
|
||||
@cached_property # type: ignore[override]
|
||||
def attributes(self) -> dict[str, Any]:
|
||||
"""State attributes."""
|
||||
if self._attributes is None:
|
||||
self._attributes = decode_attributes_from_source(
|
||||
getattr(self._row, "attributes", None), self.attr_cache
|
||||
)
|
||||
return self._attributes
|
||||
return decode_attributes_from_source(
|
||||
getattr(self._row, "attributes", None), self.attr_cache
|
||||
)
|
||||
|
||||
@attributes.setter
|
||||
def attributes(self, value: dict[str, Any]) -> None:
|
||||
"""Set attributes."""
|
||||
self._attributes = value
|
||||
@cached_property
|
||||
def _last_changed_ts(self) -> float | None:
|
||||
"""Last changed timestamp."""
|
||||
return getattr(self._row, "last_changed_ts", None)
|
||||
|
||||
@property
|
||||
def context(self) -> Context:
|
||||
"""State context."""
|
||||
if self._context is None:
|
||||
self._context = Context(id=None)
|
||||
return self._context
|
||||
|
||||
@context.setter
|
||||
def context(self, value: Context) -> None:
|
||||
"""Set context."""
|
||||
self._context = value
|
||||
|
||||
@property
|
||||
def last_changed(self) -> datetime:
|
||||
@cached_property
|
||||
def last_changed(self) -> datetime: # type: ignore[override]
|
||||
"""Last changed datetime."""
|
||||
if self._last_changed_ts is None:
|
||||
self._last_changed_ts = (
|
||||
getattr(self._row, "last_changed_ts", None) or self._last_updated_ts
|
||||
)
|
||||
return dt_util.utc_from_timestamp(self._last_changed_ts)
|
||||
return dt_util.utc_from_timestamp(
|
||||
self._last_changed_ts or self._last_updated_ts
|
||||
)
|
||||
|
||||
@last_changed.setter
|
||||
def last_changed(self, value: datetime) -> None:
|
||||
"""Set last changed datetime."""
|
||||
self._last_changed_ts = process_timestamp(value).timestamp()
|
||||
|
||||
@property
|
||||
def last_updated(self) -> datetime:
|
||||
@cached_property
|
||||
def last_updated(self) -> datetime: # type: ignore[override]
|
||||
"""Last updated datetime."""
|
||||
assert self._last_updated_ts is not None
|
||||
if TYPE_CHECKING:
|
||||
assert self._last_updated_ts is not None
|
||||
return dt_util.utc_from_timestamp(self._last_updated_ts)
|
||||
|
||||
@last_updated.setter
|
||||
def last_updated(self, value: datetime) -> None:
|
||||
"""Set last updated datetime."""
|
||||
self._last_updated_ts = process_timestamp(value).timestamp()
|
||||
|
||||
def as_dict(self) -> dict[str, Any]: # type: ignore[override]
|
||||
"""Return a dict representation of the LazyState.
|
||||
|
||||
|
|
|
@ -352,22 +352,6 @@ async def test_lazy_state_handles_same_last_updated_and_last_changed(
|
|||
"last_updated": "2021-06-12T03:04:01.000323+00:00",
|
||||
"state": "off",
|
||||
}
|
||||
lstate.last_updated = datetime(2020, 6, 12, 3, 4, 1, 323, tzinfo=dt_util.UTC)
|
||||
assert lstate.as_dict() == {
|
||||
"attributes": {"shared": True},
|
||||
"entity_id": "sensor.valid",
|
||||
"last_changed": "2021-06-12T03:04:01.000323+00:00",
|
||||
"last_updated": "2020-06-12T03:04:01.000323+00:00",
|
||||
"state": "off",
|
||||
}
|
||||
lstate.last_changed = datetime(2020, 6, 12, 3, 4, 1, 323, tzinfo=dt_util.UTC)
|
||||
assert lstate.as_dict() == {
|
||||
"attributes": {"shared": True},
|
||||
"entity_id": "sensor.valid",
|
||||
"last_changed": "2020-06-12T03:04:01.000323+00:00",
|
||||
"last_updated": "2020-06-12T03:04:01.000323+00:00",
|
||||
"state": "off",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
Loading…
Add table
Reference in a new issue