@@ -82,7 +82,7 @@ def __init__(
8282 self ._gaps : list [Gap ] = []
8383 self ._datetime_newest : datetime = self ._DATETIME_MIN
8484 self ._datetime_oldest : datetime = self ._DATETIME_MAX
85- self ._time_range : timedelta = ( len (self ._buffer ) - 1 ) * sampling_period
85+ self ._full_time_range : timedelta = len (self ._buffer ) * self . _sampling_period
8686
8787 @property
8888 def sampling_period (self ) -> timedelta :
@@ -145,7 +145,9 @@ def update(self, sample: Sample[QuantityT]) -> None:
145145 # Update timestamps
146146 prev_newest = self ._datetime_newest
147147 self ._datetime_newest = max (self ._datetime_newest , timestamp )
148- self ._datetime_oldest = self ._datetime_newest - self ._time_range
148+ self ._datetime_oldest = self ._datetime_newest - (
149+ self ._full_time_range - self ._sampling_period
150+ )
149151
150152 # Update data
151153 value : float = np .nan if sample .value is None else sample .value .base_value
@@ -279,39 +281,39 @@ def is_missing(self, timestamp: datetime) -> bool:
279281 return any (map (lambda gap : gap .contains (timestamp ), self ._gaps ))
280282
281283 def _update_gaps (
282- self , timestamp : datetime , newest : datetime , new_missing : bool
284+ self , timestamp : datetime , newest : datetime , record_as_missing : bool
283285 ) -> None :
284286 """Update gap list with new timestamp.
285287
286288 Args:
287289 timestamp: Timestamp of the new value.
288290 newest: Timestamp of the newest value before the current update.
289- new_missing: if true, the given timestamp will be recorded as missing.
290-
291+ record_as_missing: if `True`, the given timestamp will be recorded as missing.
291292 """
292- currently_missing = self .is_missing (timestamp )
293+ found_in_gaps = self .is_missing (timestamp )
293294
294- if not new_missing :
295+ if not record_as_missing :
295296 # Replace all gaps with one if we went far into then future
296- if self ._datetime_newest - newest >= self ._time_range :
297+ if self ._datetime_newest - newest >= self ._full_time_range :
297298 self ._gaps = [
298299 Gap (start = self ._datetime_oldest , end = self ._datetime_newest )
299300 ]
300301 return
301302
302- if not currently_missing and timestamp > newest + self ._sampling_period :
303+ # Check if we created a gap with the addition of the new value
304+ if not found_in_gaps and timestamp > newest + self ._sampling_period :
303305 self ._gaps .append (
304306 Gap (start = newest + self ._sampling_period , end = timestamp )
305307 )
306308
307309 # New missing entry that is not already in a gap?
308- if new_missing :
309- if not currently_missing :
310+ if record_as_missing :
311+ if not found_in_gaps :
310312 self ._gaps .append (
311313 Gap (start = timestamp , end = timestamp + self ._sampling_period )
312314 )
313315 elif len (self ._gaps ) > 0 :
314- if currently_missing :
316+ if found_in_gaps :
315317 self ._remove_gap (timestamp )
316318
317319 self ._cleanup_gaps ()
@@ -515,10 +517,24 @@ def __len__(self) -> int:
515517 if self ._datetime_newest == self ._DATETIME_MIN :
516518 return 0
517519
520+ # Sum of all elements in the gap ranges
521+ sum_missing_entries = max (
522+ 0 ,
523+ sum (
524+ (
525+ gap .end
526+ # Don't look further back than oldest timestamp
527+ - max (gap .start , self ._datetime_oldest )
528+ )
529+ // self ._sampling_period
530+ for gap in self ._gaps
531+ ),
532+ )
533+
518534 start_index = self .datetime_to_index (self ._datetime_oldest )
519535 end_index = self .datetime_to_index (self ._datetime_newest )
520536
521537 if end_index < start_index :
522- return len (self ._buffer ) - start_index + end_index + 1
538+ return len (self ._buffer ) - start_index + end_index + 1 - sum_missing_entries
523539
524- return end_index + 1 - start_index
540+ return end_index + 1 - start_index - sum_missing_entries
0 commit comments