Appearance
RollingWindow
What it does
Generic time-window scalar aggregator. RollingWindow<f64> holds (ms_of_day, value) entries up to the configured window_ms and exposes running totals over the window with right-open interval semantics.
rust
let mut window = RollingWindow::new(60_000); // 1-minute window (window_ms: i64)
window.push(ms_of_day as i64, value); // (ts_ms, value) admission
let sum = window.sum(); // Σ values in the window
let mean = window.mean(); // Σ / n
let n = window.count(); // count of entries in the window
let empty = window.is_empty();
// `advance_and_push(ts_ms, value)` evicts old entries against a
// supplied wall-clock then admits; `flush_before(ts_ms)` evicts only.Implementation
- Backing store is a
VecDeque<(i32, f64)>pre-sized at construction. - Running sum uses
NeumaierSum— wide-magnitude streams retain precision even when individual addends land below the running sum's ULP. admitis amortised O(1): old entries are evicted from the front in a single drain.
Replay parity
Insertion-order traversal is the load-bearing invariant. The RollingWindow does not reorder entries; the Neumaier accumulator's compensation makes the running sum independent of per-tick admission order at the recovered scale, but order-equivalence under replay holds only because the engine itself admits ticks in event-time order.
Consumers
BaselineComparison— rolling mean and variance over an arbitrary scalar series.VolumeAnomaly— daily-volume baseline.Vpin— sliding-window VPIN aggregate.Pctl— uses the rolling-window pattern but with insertion-order observations rather than time-keyed entries.
Why a primitive
Every analytic that maintains a windowed statistic shares the same two requirements: amortised-O(1) admission and Neumaier-summed running totals. Factoring the pattern into one primitive keeps the per-analytic math focused on the methodology and the primitive's order-independence test covered once in tests/rolling_window_invariants.rs.