use reifydb_value::value::datetime::DateTime;
use crate::window::{
coord::{OrdinalCoord, RowSpan},
kind::ordinal_window_span,
span::WindowSpan,
};
pub struct TumblingOverRows {
capacity: RowSpan,
}
impl TumblingOverRows {
pub fn holding(capacity: RowSpan) -> Self {
Self {
capacity: RowSpan::of(capacity.rows().max(1)),
}
}
pub fn window_id(&self, coord: OrdinalCoord) -> u64 {
coord.value() / self.capacity.rows()
}
pub fn span(&self, coord: OrdinalCoord) -> WindowSpan<DateTime> {
ordinal_window_span(self.window_id(coord))
}
}
#[cfg(test)]
mod tests {
use super::*;
fn ordinal(value: u64) -> OrdinalCoord {
OrdinalCoord::from_arrival_counter(value)
}
#[test]
fn every_capacity_rows_advance_the_window_by_exactly_one() {
let rows = TumblingOverRows::holding(RowSpan::of(4));
assert_eq!(rows.window_id(ordinal(0)), 0);
assert_eq!(rows.window_id(ordinal(3)), 0);
assert_eq!(rows.window_id(ordinal(4)), 1);
assert_eq!(rows.window_id(ordinal(7)), 1);
assert_eq!(rows.window_id(ordinal(8)), 2);
}
#[test]
fn consecutive_windows_never_share_a_span() {
let rows = TumblingOverRows::holding(RowSpan::of(4));
assert_ne!(rows.span(ordinal(3)), rows.span(ordinal(4)));
assert_eq!(rows.span(ordinal(0)), rows.span(ordinal(3)));
}
}