diff --git a/crates/items_2/src/binning/container_events.rs b/crates/items_2/src/binning/container_events.rs index f45a32c..d2378f1 100644 --- a/crates/items_2/src/binning/container_events.rs +++ b/crates/items_2/src/binning/container_events.rs @@ -48,6 +48,7 @@ impl EventValueType for f32 { type AggregatorTimeWeight = AggregatorNumeric; } +#[derive(Debug, Clone)] pub struct EventSingle { pub ts: TsNano, pub val: EVT, @@ -102,6 +103,12 @@ where self.tss.back().map(|&x| x) } + pub fn len_before(&self, end: TsNano) -> usize { + let pp = self.tss.partition_point(|&x| x < end); + assert!(pp <= self.len(), "len_before pp {} len {}", pp, self.len()); + pp + } + pub fn event_next(&mut self) -> Option> { if let (Some(ts), Some(val)) = (self.tss.pop_front(), self.vals.pop_front()) { Some(EventSingle { ts, val }) diff --git a/crates/items_2/src/binning/timeweight/timeweight_events.rs b/crates/items_2/src/binning/timeweight/timeweight_events.rs index b5d700b..7612d63 100644 --- a/crates/items_2/src/binning/timeweight/timeweight_events.rs +++ b/crates/items_2/src/binning/timeweight/timeweight_events.rs @@ -24,8 +24,11 @@ pub enum Error { AnotherBeforeRange, NoLstAfterFirst, EmptyContainerInnerHandler, + NoLstButMinMax, } +type MinMax = (EventSingle, EventSingle); + struct InnerA { range: BinnedRange, cnt: u64, @@ -91,9 +94,17 @@ where // Do I maybe need both? // How to handle to not emit bins until at least some partially filled bin is encountered? // How to implement the bin cycle logic in clean way? + // How to emit things? Do to ship results to the caller? todo!("must check if ev is already after range."); } + if ev.ts >= self.range.nano_end() { + todo!("make sure that the transition to the next bin (if we want any next bin) works"); + todo!("keep lst. we derive min/max from lst upon the first event in range"); + + // TODO where and how do I initialize min/max ? + } + // TODO if the event is exactly on the current bin first edge, then there is no contribution to the avg yet // and I must initialize the min/max with the current event. // If the event is after the current bin first edge, then min/max is initialized from the lst @@ -106,7 +117,33 @@ where Ok(()) } - fn ingest_with_lst(&mut self, evs: ContainerEvents, lst: &mut EventSingle) -> Result<(), Error> { + fn ingest_with_lst_nominmax( + &mut self, + evs: ContainerEvents, + lst: &mut EventSingle, + minmax: &mut Option>, + ) -> Result<(), Error> { + // TODO how to handle the min max? I don't take event data yet out of the container. + todo!("minmax handle"); + if let Some(ts0) = evs.ts_first() { + if ts0 < self.range.nano_beg() { + Err(Error::AnotherBeforeRange) + } else { + self.ingest_with_lst_ge_range_beg(evs, lst) + } + } else { + Err(Error::EmptyContainerInnerHandler) + } + } + + fn ingest_with_lst_minmax( + &mut self, + evs: ContainerEvents, + lst: &mut EventSingle, + minmax: &mut MinMax, + ) -> Result<(), Error> { + // TODO how to handle the min max? I don't take event data yet out of the container. + todo!("minmax handle"); if let Some(ts0) = evs.ts_first() { if ts0 < self.range.nano_beg() { Err(Error::AnotherBeforeRange) @@ -125,6 +162,7 @@ where { inner_a: InnerA, lst: Option>, + minmax: Option<(EventSingle, EventSingle)>, } impl BinnedEventsTimeweight @@ -139,12 +177,17 @@ where _t1: PhantomData, }, lst: None, + minmax: None, } } fn ingest_event_without_lst(&mut self, ev: EventSingle) -> Result<(), Error> { - if ev.ts < self.inner_a.range.nano_end() { - if ev.ts >= self.inner_a.range.nano_beg() { + let range = &self.inner_a.range; + let beg = range.nano_beg(); + let end = range.nano_end(); + if ev.ts < end { + if ev.ts >= beg { + self.minmax = Some((ev.clone(), ev.clone())); self.inner_a.cnt += 1; } self.lst = Some(ev); @@ -157,7 +200,11 @@ where self.ingest_event_without_lst(ev)?; } if let Some(lst) = self.lst.as_mut() { - self.inner_a.ingest_with_lst(evs, lst) + if let Some(minmax) = self.minmax.as_mut() { + self.inner_a.ingest_with_lst_minmax(evs, lst, minmax) + } else { + self.inner_a.ingest_with_lst_nominmax(evs, lst, &mut self.minmax) + } } else { Err(Error::NoLstAfterFirst) } @@ -167,9 +214,17 @@ where // and with respect to the last container, if any. fn ingest_ordered(&mut self, evs: ContainerEvents) -> Result<(), Error> { if let Some(lst) = self.lst.as_mut() { - self.inner_a.ingest_with_lst(evs, lst) + if let Some(minmax) = self.minmax.as_mut() { + self.inner_a.ingest_with_lst_minmax(evs, lst, minmax) + } else { + self.inner_a.ingest_with_lst_nominmax(evs, lst, &mut self.minmax) + } } else { - self.ingest_without_lst(evs) + if self.minmax.is_some() { + Err(Error::NoLstButMinMax) + } else { + self.ingest_without_lst(evs) + } } }