Skip to content

Commit b94c48b

Browse files
committed
Add oldest and newest timestamps to moving window
Methods to retrieve the timestamps of the oldest and newest sample in the moving window. Signed-off-by: cwasicki <[email protected]>
1 parent 6e113f4 commit b94c48b

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

RELEASE_NOTES.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ This release replaces the `@actor` decorator with a new `Actor` class.
100100

101101
- `Actor`: This new class inherits from `BackgroundService` and it replaces the `@actor` decorator.
102102

103-
- `MovingWindow`: Provide access to `capacity` (maximum number of elements).
103+
- `MovingWindow`: Provide access to `capacity` (maximum number of elements),
104+
`oldest_timestamp` and `newest_timestamp` of the window. The names in the
105+
`OrderedRingBuffer` have been changed to match these names.
104106

105107
## Bug Fixes
106108

src/frequenz/sdk/timeseries/_moving_window.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,32 @@ def capacity(self) -> int:
222222
"""
223223
return self._buffer.maxlen
224224

225+
@property
226+
def oldest_timestamp(self) -> datetime | None:
227+
"""
228+
Return the oldest timestamp in the MovingWindow.
229+
230+
Returns:
231+
The oldest timestamp in the MovingWindow.
232+
If the MovingWindow is empty, None is returned.
233+
"""
234+
if len(self._buffer) == 0:
235+
return None
236+
return self._buffer.oldest_timestamp
237+
238+
@property
239+
def newest_timestamp(self) -> datetime | None:
240+
"""
241+
Return the newest timestamp in the MovingWindow.
242+
243+
Returns:
244+
The newest timestamp in the MovingWindow.
245+
If the MovingWindow is empty, None is returned.
246+
"""
247+
if len(self._buffer) == 0:
248+
return None
249+
return self._buffer.newest_timestamp
250+
225251
async def _run_impl(self) -> None:
226252
"""Awaits samples from the receiver and updates the underlying ring buffer.
227253

tests/timeseries/test_moving_window.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,25 @@ async def test_window_size() -> None:
137137
assert len(window) == 5, "Window should be full"
138138

139139

140+
async def test_timestamps() -> None:
141+
"""Test the timestamp methods of the window."""
142+
window, sender = init_moving_window(timedelta(seconds=5))
143+
async with window:
144+
assert (
145+
window.oldest_timestamp is None
146+
), "For an empty window, oldest timestamp should be None"
147+
assert (
148+
window.newest_timestamp is None
149+
), "For an empty window, newest timestamp should be None"
150+
await push_logical_meter_data(sender, range(0, 20))
151+
assert window.oldest_timestamp == UNIX_EPOCH + timedelta(
152+
seconds=15
153+
), "Wrong oldest timestamp"
154+
assert window.newest_timestamp == UNIX_EPOCH + timedelta(
155+
seconds=19
156+
), "Wrong newest timestamp"
157+
158+
140159
# pylint: disable=redefined-outer-name
141160
async def test_resampling_window(fake_time: time_machine.Coordinates) -> None:
142161
"""Test resampling in MovingWindow."""

0 commit comments

Comments
 (0)