This commit is contained in:
Dominik Werder
2023-04-25 09:08:14 +02:00
parent 95af6c359c
commit 498ff3612b
36 changed files with 1500 additions and 260 deletions

View File

@@ -375,6 +375,10 @@ impl<NTY> BinsDim0CollectedResult<NTY> {
self.range_final
}
pub fn timed_out(&self) -> bool {
self.timed_out
}
pub fn missing_bins(&self) -> u32 {
self.missing_bins
}

View File

@@ -6,6 +6,7 @@ use items_0::collect_s::Collected;
use items_0::collect_s::Collector;
use items_0::container::ByteEstimate;
use items_0::framable::FrameTypeInnerStatic;
use items_0::overlap::RangeOverlapInfo;
use items_0::streamitem::ITEMS_2_CHANNEL_EVENTS_FRAME_TYPE_ID;
use items_0::timebin::TimeBinnable;
use items_0::timebin::TimeBinnableTy;
@@ -16,7 +17,6 @@ use items_0::AsAnyMut;
use items_0::AsAnyRef;
use items_0::EventsNonObj;
use items_0::MergeError;
use items_0::RangeOverlapInfo;
use items_0::TypeName;
use items_0::WithLen;
use netpod::log::*;
@@ -159,6 +159,7 @@ mod serde_channel_events {
use crate::channelevents::ConnStatusEvent;
use crate::eventsdim0::EventsDim0;
use crate::eventsdim1::EventsDim1;
use crate::eventsxbindim0::EventsXbinDim0;
use items_0::subfr::SubFrId;
use serde::de::{self, EnumAccess, VariantAccess, Visitor};
use serde::ser::SerializeSeq;
@@ -257,12 +258,35 @@ mod serde_channel_events {
let obj: EventsDim1<f32> = seq.next_element()?.ok_or(de::Error::missing_field("[2] obj"))?;
Ok(EvBox(Box::new(obj)))
}
f64::SUB => {
let obj: EventsDim1<f64> = seq.next_element()?.ok_or(de::Error::missing_field("[2] obj"))?;
Ok(EvBox(Box::new(obj)))
}
bool::SUB => {
let obj: EventsDim1<bool> = seq.next_element()?.ok_or(de::Error::missing_field("[2] obj"))?;
Ok(EvBox(Box::new(obj)))
}
_ => Err(de::Error::custom(&format!("unknown nty {e1}"))),
}
} else if e0 == EventsXbinDim0::<u8>::serde_id() {
match e1 {
f32::SUB => {
let obj: EventsXbinDim0<f32> =
seq.next_element()?.ok_or(de::Error::missing_field("[2] obj"))?;
Ok(EvBox(Box::new(obj)))
}
f64::SUB => {
let obj: EventsXbinDim0<f64> =
seq.next_element()?.ok_or(de::Error::missing_field("[2] obj"))?;
Ok(EvBox(Box::new(obj)))
}
bool::SUB => {
let obj: EventsXbinDim0<bool> =
seq.next_element()?.ok_or(de::Error::missing_field("[2] obj"))?;
Ok(EvBox(Box::new(obj)))
}
_ => Err(de::Error::custom(&format!("unknown nty {e1}"))),
}
} else {
Err(de::Error::custom(&format!("unknown cty {e0}")))
}

View File

@@ -14,6 +14,8 @@ use items_0::collect_s::ToJsonBytes;
use items_0::collect_s::ToJsonResult;
use items_0::container::ByteEstimate;
use items_0::framable::FrameTypeInnerStatic;
use items_0::overlap::HasTimestampDeque;
use items_0::overlap::RangeOverlapCmp;
use items_0::scalar_ops::ScalarOps;
use items_0::timebin::TimeBinnable;
use items_0::timebin::TimeBinned;
@@ -59,14 +61,14 @@ macro_rules! trace2 {
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct EventsDim0<NTY> {
pub struct EventsDim0<STY> {
pub tss: VecDeque<u64>,
pub pulses: VecDeque<u64>,
pub values: VecDeque<NTY>,
pub values: VecDeque<STY>,
}
impl<NTY> EventsDim0<NTY> {
pub fn push_front(&mut self, ts: u64, pulse: u64, value: NTY) {
impl<STY> EventsDim0<STY> {
pub fn push_front(&mut self, ts: u64, pulse: u64, value: STY) {
self.tss.push_front(ts);
self.pulses.push_front(pulse);
self.values.push_front(value);
@@ -81,25 +83,25 @@ impl<NTY> EventsDim0<NTY> {
}
}
impl<NTY> AsAnyRef for EventsDim0<NTY>
impl<STY> AsAnyRef for EventsDim0<STY>
where
NTY: ScalarOps,
STY: ScalarOps,
{
fn as_any_ref(&self) -> &dyn Any {
self
}
}
impl<NTY> AsAnyMut for EventsDim0<NTY>
impl<STY> AsAnyMut for EventsDim0<STY>
where
NTY: ScalarOps,
STY: ScalarOps,
{
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
impl<NTY> Empty for EventsDim0<NTY> {
impl<STY> Empty for EventsDim0<STY> {
fn empty() -> Self {
Self {
tss: VecDeque::new(),
@@ -109,15 +111,16 @@ impl<NTY> Empty for EventsDim0<NTY> {
}
}
impl<NTY> fmt::Debug for EventsDim0<NTY>
impl<STY> fmt::Debug for EventsDim0<STY>
where
NTY: fmt::Debug,
STY: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
if false {
write!(
fmt,
"EventsDim0 {{ count {} ts {:?} vals {:?} }}",
"{} {{ count {} ts {:?} vals {:?} }}",
self.type_name(),
self.tss.len(),
self.tss.iter().map(|x| x / SEC).collect::<Vec<_>>(),
self.values,
@@ -125,7 +128,8 @@ where
} else {
write!(
fmt,
"EventsDim0 {{ count {} ts {:?} .. {:?} vals {:?} .. {:?} }}",
"{} {{ count {} ts {:?} .. {:?} vals {:?} .. {:?} }}",
self.type_name(),
self.tss.len(),
self.tss.front().map(|x| x / SEC),
self.tss.back().map(|x| x / SEC),
@@ -136,7 +140,7 @@ where
}
}
impl<NTY> WithLen for EventsDim0<NTY> {
impl<STY> WithLen for EventsDim0<STY> {
fn len(&self) -> usize {
self.tss.len()
}
@@ -149,71 +153,32 @@ impl<STY> ByteEstimate for EventsDim0<STY> {
}
}
impl<NTY: ScalarOps> RangeOverlapInfo for EventsDim0<NTY> {
fn ends_before(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(&max) = self.tss.back() {
max < range.beg_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(&max) = self.pulses.back() {
max < range.beg_u64()
} else {
true
}
} else {
error!("unexpected");
true
}
impl<STY: ScalarOps> HasTimestampDeque for EventsDim0<STY> {
fn timestamp_min(&self) -> Option<u64> {
self.tss.front().map(|x| *x)
}
fn ends_after(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(&max) = self.tss.back() {
max >= range.end_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(&max) = self.pulses.back() {
max >= range.end_u64()
} else {
true
}
} else {
error!("unexpected");
false
}
fn timestamp_max(&self) -> Option<u64> {
self.tss.back().map(|x| *x)
}
fn starts_after(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(&min) = self.tss.front() {
min >= range.end_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(&min) = self.pulses.front() {
min >= range.end_u64()
} else {
true
}
} else {
error!("unexpected");
true
}
fn pulse_min(&self) -> Option<u64> {
self.pulses.front().map(|x| *x)
}
fn pulse_max(&self) -> Option<u64> {
self.pulses.back().map(|x| *x)
}
}
impl<NTY> TimeBinnableType for EventsDim0<NTY>
items_0::impl_range_overlap_info_events!(EventsDim0);
impl<STY> TimeBinnableType for EventsDim0<STY>
where
NTY: ScalarOps,
STY: ScalarOps,
{
type Output = BinsDim0<NTY>;
type Aggregator = EventsDim0Aggregator<NTY>;
type Output = BinsDim0<STY>;
type Aggregator = EventsDim0Aggregator<STY>;
fn aggregator(range: SeriesRange, x_bin_count: usize, do_time_weight: bool) -> Self::Aggregator {
let self_name = any::type_name::<Self>();
@@ -226,13 +191,13 @@ where
}
#[derive(Debug)]
pub struct EventsDim0Collector<NTY> {
vals: Option<EventsDim0<NTY>>,
pub struct EventsDim0Collector<STY> {
vals: Option<EventsDim0<STY>>,
range_final: bool,
timed_out: bool,
}
impl<NTY> EventsDim0Collector<NTY> {
impl<STY> EventsDim0Collector<STY> {
pub fn new() -> Self {
Self {
vals: None,
@@ -242,14 +207,14 @@ impl<NTY> EventsDim0Collector<NTY> {
}
}
impl<NTY> WithLen for EventsDim0Collector<NTY> {
impl<STY> WithLen for EventsDim0Collector<STY> {
fn len(&self) -> usize {
self.vals.as_ref().map_or(0, |x| x.tss.len())
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct EventsDim0CollectorOutput<NTY> {
pub struct EventsDim0CollectorOutput<STY> {
#[serde(rename = "tsAnchor")]
ts_anchor_sec: u64,
#[serde(rename = "tsMs")]
@@ -261,7 +226,7 @@ pub struct EventsDim0CollectorOutput<NTY> {
#[serde(rename = "pulseOff")]
pulse_off: VecDeque<u64>,
#[serde(rename = "values")]
values: VecDeque<NTY>,
values: VecDeque<STY>,
#[serde(rename = "rangeFinal", default, skip_serializing_if = "is_false")]
range_final: bool,
#[serde(rename = "timedOut", default, skip_serializing_if = "is_false")]
@@ -270,7 +235,7 @@ pub struct EventsDim0CollectorOutput<NTY> {
continue_at: Option<IsoDateTime>,
}
impl<NTY: ScalarOps> EventsDim0CollectorOutput<NTY> {
impl<STY: ScalarOps> EventsDim0CollectorOutput<STY> {
pub fn ts_anchor_sec(&self) -> u64 {
self.ts_anchor_sec
}
@@ -328,42 +293,42 @@ impl<NTY: ScalarOps> EventsDim0CollectorOutput<NTY> {
}
}
impl<NTY> AsAnyRef for EventsDim0CollectorOutput<NTY>
impl<STY> AsAnyRef for EventsDim0CollectorOutput<STY>
where
NTY: ScalarOps,
STY: ScalarOps,
{
fn as_any_ref(&self) -> &dyn Any {
self
}
}
impl<NTY> AsAnyMut for EventsDim0CollectorOutput<NTY>
impl<STY> AsAnyMut for EventsDim0CollectorOutput<STY>
where
NTY: ScalarOps,
STY: ScalarOps,
{
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
impl<NTY: ScalarOps> WithLen for EventsDim0CollectorOutput<NTY> {
impl<STY: ScalarOps> WithLen for EventsDim0CollectorOutput<STY> {
fn len(&self) -> usize {
self.values.len()
}
}
impl<NTY: ScalarOps> ToJsonResult for EventsDim0CollectorOutput<NTY> {
impl<STY: ScalarOps> ToJsonResult for EventsDim0CollectorOutput<STY> {
fn to_json_result(&self) -> Result<Box<dyn ToJsonBytes>, Error> {
let k = serde_json::to_value(self)?;
Ok(Box::new(k))
}
}
impl<NTY: ScalarOps> Collected for EventsDim0CollectorOutput<NTY> {}
impl<STY: ScalarOps> Collected for EventsDim0CollectorOutput<STY> {}
impl<NTY: ScalarOps> CollectorType for EventsDim0Collector<NTY> {
type Input = EventsDim0<NTY>;
type Output = EventsDim0CollectorOutput<NTY>;
impl<STY: ScalarOps> CollectorType for EventsDim0Collector<STY> {
type Input = EventsDim0<STY>;
type Output = EventsDim0CollectorOutput<STY>;
fn ingest(&mut self, src: &mut Self::Input) {
if self.vals.is_none() {
@@ -451,8 +416,8 @@ impl<NTY: ScalarOps> CollectorType for EventsDim0Collector<NTY> {
}
}
impl<NTY: ScalarOps> items_0::collect_s::CollectableType for EventsDim0<NTY> {
type Collector = EventsDim0Collector<NTY>;
impl<STY: ScalarOps> items_0::collect_s::CollectableType for EventsDim0<STY> {
type Collector = EventsDim0Collector<STY>;
fn new_collector() -> Self::Collector {
Self::Collector::new()
@@ -460,23 +425,23 @@ impl<NTY: ScalarOps> items_0::collect_s::CollectableType for EventsDim0<NTY> {
}
#[derive(Debug)]
pub struct EventsDim0Aggregator<NTY> {
pub struct EventsDim0Aggregator<STY> {
range: SeriesRange,
count: u64,
min: NTY,
max: NTY,
min: STY,
max: STY,
sumc: u64,
sum: f32,
int_ts: u64,
last_seen_ts: u64,
last_seen_val: Option<NTY>,
last_seen_val: Option<STY>,
did_min_max: bool,
do_time_weight: bool,
events_taken_count: u64,
events_ignored_count: u64,
}
impl<NTY> Drop for EventsDim0Aggregator<NTY> {
impl<STY> Drop for EventsDim0Aggregator<STY> {
fn drop(&mut self) {
// TODO collect as stats for the request context:
trace!(
@@ -487,9 +452,9 @@ impl<NTY> Drop for EventsDim0Aggregator<NTY> {
}
}
impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
impl<STY: ScalarOps> EventsDim0Aggregator<STY> {
fn self_name() -> String {
format!("{}<{}>", any::type_name::<Self>(), any::type_name::<NTY>())
format!("{}<{}>", any::type_name::<Self>(), any::type_name::<STY>())
}
pub fn new(binrange: SeriesRange, do_time_weight: bool) -> Self {
@@ -497,8 +462,8 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
Self {
range: binrange,
count: 0,
min: NTY::zero_b(),
max: NTY::zero_b(),
min: STY::zero_b(),
max: STY::zero_b(),
sum: 0.,
sumc: 0,
int_ts,
@@ -512,7 +477,7 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
}
// TODO reduce clone.. optimize via more traits to factor the trade-offs?
fn apply_min_max(&mut self, val: NTY) {
fn apply_min_max(&mut self, val: STY) {
trace_ingest!(
"apply_min_max val {:?} last_val {:?} count {} sumc {:?} min {:?} max {:?}",
val,
@@ -536,7 +501,7 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
}
}
fn apply_event_unweight(&mut self, val: NTY) {
fn apply_event_unweight(&mut self, val: STY) {
error!("TODO check again result_reset_unweight");
err::todo();
let vf = val.as_prim_f32_b();
@@ -636,7 +601,7 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
}
}
fn result_reset_unweight(&mut self, range: SeriesRange) -> BinsDim0<NTY> {
fn result_reset_unweight(&mut self, range: SeriesRange) -> BinsDim0<STY> {
trace!("TODO check again result_reset_unweight");
err::todo();
let (min, max, avg) = if self.sumc > 0 {
@@ -645,7 +610,7 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
} else {
let g = match &self.last_seen_val {
Some(x) => x.clone(),
None => NTY::zero_b(),
None => STY::zero_b(),
};
(g.clone(), g.clone(), g.as_prim_f32_b())
};
@@ -672,7 +637,7 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
ret
}
fn result_reset_time_weight(&mut self, range: SeriesRange) -> BinsDim0<NTY> {
fn result_reset_time_weight(&mut self, range: SeriesRange) -> BinsDim0<STY> {
// TODO check callsite for correct expand status.
debug!("result_reset_time_weight calls apply_event_time_weight");
if self.range.is_time() {
@@ -687,7 +652,7 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
} else {
let g = match &self.last_seen_val {
Some(x) => x.clone(),
None => NTY::zero_b(),
None => STY::zero_b(),
};
(g.clone(), g.clone(), g.as_prim_f32_b())
};
@@ -711,15 +676,15 @@ impl<NTY: ScalarOps> EventsDim0Aggregator<NTY> {
self.sum = 0.;
self.sumc = 0;
self.did_min_max = false;
self.min = NTY::zero_b();
self.max = NTY::zero_b();
self.min = STY::zero_b();
self.max = STY::zero_b();
ret
}
}
impl<NTY: ScalarOps> TimeBinnableTypeAggregator for EventsDim0Aggregator<NTY> {
type Input = EventsDim0<NTY>;
type Output = BinsDim0<NTY>;
impl<STY: ScalarOps> TimeBinnableTypeAggregator for EventsDim0Aggregator<STY> {
type Input = EventsDim0<STY>;
type Output = BinsDim0<STY>;
fn range(&self) -> &SeriesRange {
&self.range
@@ -751,9 +716,9 @@ impl<NTY: ScalarOps> TimeBinnableTypeAggregator for EventsDim0Aggregator<NTY> {
}
}
impl<NTY: ScalarOps> TimeBinnable for EventsDim0<NTY> {
impl<STY: ScalarOps> TimeBinnable for EventsDim0<STY> {
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Box<dyn TimeBinner> {
let ret = EventsDim0TimeBinner::<NTY>::new(binrange, do_time_weight).unwrap();
let ret = EventsDim0TimeBinner::<STY>::new(binrange, do_time_weight).unwrap();
Box::new(ret)
}

View File

@@ -1,4 +1,5 @@
use crate::binsdim0::BinsDim0;
use crate::eventsxbindim0::EventsXbinDim0;
use crate::framable::FrameType;
use crate::IsoDateTime;
use crate::RangeOverlapInfo;
@@ -12,6 +13,8 @@ use items_0::collect_s::CollectorType;
use items_0::collect_s::ToJsonBytes;
use items_0::collect_s::ToJsonResult;
use items_0::container::ByteEstimate;
use items_0::overlap::HasTimestampDeque;
use items_0::overlap::RangeOverlapCmp;
use items_0::scalar_ops::ScalarOps;
use items_0::timebin::TimeBinnable;
use items_0::timebin::TimeBinned;
@@ -143,20 +146,26 @@ impl<STY> ByteEstimate for EventsDim1<STY> {
}
}
impl<NTY: ScalarOps> RangeOverlapInfo for EventsDim1<NTY> {
fn ends_before(&self, range: &SeriesRange) -> bool {
todo!()
impl<STY: ScalarOps> HasTimestampDeque for EventsDim1<STY> {
fn timestamp_min(&self) -> Option<u64> {
self.tss.front().map(|x| *x)
}
fn ends_after(&self, range: &SeriesRange) -> bool {
todo!()
fn timestamp_max(&self) -> Option<u64> {
self.tss.back().map(|x| *x)
}
fn starts_after(&self, range: &SeriesRange) -> bool {
todo!()
fn pulse_min(&self) -> Option<u64> {
self.pulses.front().map(|x| *x)
}
fn pulse_max(&self) -> Option<u64> {
self.pulses.back().map(|x| *x)
}
}
items_0::impl_range_overlap_info_events!(EventsDim1);
impl<NTY> TimeBinnableType for EventsDim1<NTY>
where
NTY: ScalarOps,
@@ -821,7 +830,33 @@ impl<STY: ScalarOps> Events for EventsDim1<STY> {
}
fn to_min_max_avg(&mut self) -> Box<dyn Events> {
todo!()
let mins = self
.values
.iter()
.map(|x| STY::find_vec_min(x))
.map(|x| x.unwrap_or_else(|| STY::zero_b()))
.collect();
let maxs = self
.values
.iter()
.map(|x| STY::find_vec_max(x))
.map(|x| x.unwrap_or_else(|| STY::zero_b()))
.collect();
let avgs = self
.values
.iter()
.map(|x| STY::avg_vec(x))
.map(|x| x.unwrap_or_else(|| STY::zero_b()))
.map(|x| x.as_prim_f32_b())
.collect();
let item = EventsXbinDim0 {
tss: mem::replace(&mut self.tss, VecDeque::new()),
pulses: mem::replace(&mut self.pulses, VecDeque::new()),
mins,
maxs,
avgs,
};
Box::new(item)
}
}

View File

@@ -4,16 +4,23 @@ use crate::RangeOverlapInfo;
use crate::TimeBinnableType;
use crate::TimeBinnableTypeAggregator;
use err::Error;
use items_0::collect_s::Collectable;
use items_0::collect_s::CollectableType;
use items_0::collect_s::Collected;
use items_0::collect_s::CollectorType;
use items_0::collect_s::ToJsonBytes;
use items_0::collect_s::ToJsonResult;
use items_0::container::ByteEstimate;
use items_0::overlap::HasTimestampDeque;
use items_0::overlap::RangeOverlapCmp;
use items_0::scalar_ops::ScalarOps;
use items_0::timebin::TimeBinnable;
use items_0::AsAnyMut;
use items_0::AsAnyRef;
use items_0::Empty;
use items_0::Events;
use items_0::EventsNonObj;
use items_0::MergeError;
use items_0::TypeName;
use items_0::WithLen;
use netpod::is_false;
@@ -26,6 +33,7 @@ use std::any;
use std::any::Any;
use std::collections::VecDeque;
use std::fmt;
use std::mem;
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct EventsXbinDim0<NTY> {
@@ -55,6 +63,10 @@ impl<NTY> EventsXbinDim0<NTY> {
self.maxs.push_front(max);
self.avgs.push_front(avg);
}
pub fn serde_id() -> &'static str {
"EventsXbinDim0"
}
}
impl<STY> TypeName for EventsXbinDim0<STY> {
@@ -120,17 +132,207 @@ impl<NTY> WithLen for EventsXbinDim0<NTY> {
}
}
impl<NTY> RangeOverlapInfo for EventsXbinDim0<NTY> {
fn ends_before(&self, range: &SeriesRange) -> bool {
todo!()
impl<STY: ScalarOps> HasTimestampDeque for EventsXbinDim0<STY> {
fn timestamp_min(&self) -> Option<u64> {
self.tss.front().map(|x| *x)
}
fn ends_after(&self, range: &SeriesRange) -> bool {
todo!()
fn timestamp_max(&self) -> Option<u64> {
self.tss.back().map(|x| *x)
}
fn starts_after(&self, range: &SeriesRange) -> bool {
todo!()
fn pulse_min(&self) -> Option<u64> {
self.pulses.front().map(|x| *x)
}
fn pulse_max(&self) -> Option<u64> {
self.pulses.back().map(|x| *x)
}
}
items_0::impl_range_overlap_info_events!(EventsXbinDim0);
impl<STY: ScalarOps> EventsNonObj for EventsXbinDim0<STY> {
fn into_tss_pulses(self: Box<Self>) -> (VecDeque<u64>, VecDeque<u64>) {
info!(
"EventsXbinDim0::into_tss_pulses len {} len {}",
self.tss.len(),
self.pulses.len()
);
(self.tss, self.pulses)
}
}
impl<STY: ScalarOps> Events for EventsXbinDim0<STY> {
fn as_time_binnable_mut(&mut self) -> &mut dyn TimeBinnable {
self as &mut dyn TimeBinnable
}
fn verify(&self) -> bool {
let mut good = true;
let mut ts_max = 0;
for ts in &self.tss {
let ts = *ts;
if ts < ts_max {
good = false;
error!("unordered event data ts {} ts_max {}", ts, ts_max);
}
ts_max = ts_max.max(ts);
}
good
}
fn output_info(&self) {
if false {
info!("output_info len {}", self.tss.len());
if self.tss.len() == 1 {
info!(
" only: ts {} pulse {} value {:?}",
self.tss[0], self.pulses[0], self.avgs[0]
);
} else if self.tss.len() > 1 {
info!(
" first: ts {} pulse {} value {:?}",
self.tss[0], self.pulses[0], self.avgs[0]
);
let n = self.tss.len() - 1;
info!(
" last: ts {} pulse {} value {:?}",
self.tss[n], self.pulses[n], self.avgs[n]
);
}
}
}
fn as_collectable_mut(&mut self) -> &mut dyn Collectable {
self
}
fn as_collectable_with_default_ref(&self) -> &dyn Collectable {
self
}
fn as_collectable_with_default_mut(&mut self) -> &mut dyn Collectable {
self
}
fn take_new_events_until_ts(&mut self, ts_end: u64) -> Box<dyn Events> {
// TODO improve the search
let n1 = self.tss.iter().take_while(|&&x| x <= ts_end).count();
let tss = self.tss.drain(..n1).collect();
let pulses = self.pulses.drain(..n1).collect();
let mins = self.mins.drain(..n1).collect();
let maxs = self.maxs.drain(..n1).collect();
let avgs = self.avgs.drain(..n1).collect();
let ret = Self {
tss,
pulses,
mins,
maxs,
avgs,
};
Box::new(ret)
}
fn new_empty_evs(&self) -> Box<dyn Events> {
Box::new(Self::empty())
}
fn drain_into_evs(&mut self, dst: &mut Box<dyn Events>, range: (usize, usize)) -> Result<(), MergeError> {
// TODO as_any and as_any_mut are declared on unrelated traits. Simplify.
if let Some(dst) = dst.as_mut().as_any_mut().downcast_mut::<Self>() {
// TODO make it harder to forget new members when the struct may get modified in the future
let r = range.0..range.1;
dst.tss.extend(self.tss.drain(r.clone()));
dst.pulses.extend(self.pulses.drain(r.clone()));
dst.mins.extend(self.mins.drain(r.clone()));
dst.maxs.extend(self.maxs.drain(r.clone()));
dst.avgs.extend(self.avgs.drain(r.clone()));
Ok(())
} else {
error!("downcast to {} FAILED", self.type_name());
Err(MergeError::NotCompatible)
}
}
fn find_lowest_index_gt_evs(&self, ts: u64) -> Option<usize> {
for (i, &m) in self.tss.iter().enumerate() {
if m > ts {
return Some(i);
}
}
None
}
fn find_lowest_index_ge_evs(&self, ts: u64) -> Option<usize> {
for (i, &m) in self.tss.iter().enumerate() {
if m >= ts {
return Some(i);
}
}
None
}
fn find_highest_index_lt_evs(&self, ts: u64) -> Option<usize> {
for (i, &m) in self.tss.iter().enumerate().rev() {
if m < ts {
return Some(i);
}
}
None
}
fn ts_min(&self) -> Option<u64> {
self.tss.front().map(|&x| x)
}
fn ts_max(&self) -> Option<u64> {
self.tss.back().map(|&x| x)
}
fn partial_eq_dyn(&self, other: &dyn Events) -> bool {
if let Some(other) = other.as_any_ref().downcast_ref::<Self>() {
self == other
} else {
false
}
}
fn serde_id(&self) -> &'static str {
Self::serde_id()
}
fn nty_id(&self) -> u32 {
STY::SUB
}
fn clone_dyn(&self) -> Box<dyn Events> {
Box::new(self.clone())
}
fn tss(&self) -> &VecDeque<u64> {
&self.tss
}
fn pulses(&self) -> &VecDeque<u64> {
&self.pulses
}
fn frame_type_id(&self) -> u32 {
error!("TODO frame_type_id should not be called");
// TODO make more nice
panic!()
}
fn to_min_max_avg(&mut self) -> Box<dyn Events> {
let dst = Self {
tss: mem::replace(&mut self.tss, Default::default()),
pulses: mem::replace(&mut self.pulses, Default::default()),
mins: mem::replace(&mut self.mins, Default::default()),
maxs: mem::replace(&mut self.maxs, Default::default()),
avgs: mem::replace(&mut self.avgs, Default::default()),
};
Box::new(dst)
}
}
@@ -151,6 +353,23 @@ where
}
}
impl<NTY> TimeBinnable for EventsXbinDim0<NTY>
where
NTY: ScalarOps,
{
fn time_binner_new(
&self,
binrange: BinnedRangeEnum,
do_time_weight: bool,
) -> Box<dyn items_0::timebin::TimeBinner> {
todo!()
}
fn to_box_to_json_result(&self) -> Box<dyn ToJsonResult> {
todo!()
}
}
pub struct EventsXbinDim0Aggregator<NTY>
where
NTY: ScalarOps,

View File

@@ -27,7 +27,7 @@ use items_0::transform::EventTransform;
use items_0::Empty;
use items_0::Events;
use items_0::MergeError;
use items_0::RangeOverlapInfo;
use items_0::overlap::RangeOverlapInfo;
use merger::Mergeable;
use netpod::range::evrange::SeriesRange;
use netpod::timeunits::*;