Move workspace crates into subfolder

This commit is contained in:
Dominik Werder
2023-07-10 14:45:25 +02:00
parent 8938e55f86
commit 30c7fcb1e5
212 changed files with 246 additions and 41 deletions

View File

@@ -0,0 +1,204 @@
use crate::timebin::TimeBinned;
use crate::AsAnyMut;
use crate::AsAnyRef;
use crate::Events;
use crate::TypeName;
use crate::WithLen;
use err::Error;
use netpod::log::*;
use netpod::range::evrange::SeriesRange;
use netpod::BinnedRangeEnum;
use serde::Serialize;
use std::any;
use std::any::Any;
use std::fmt;
// TODO check usage of this trait
pub trait ToJsonBytes {
fn to_json_bytes(&self) -> Result<Vec<u8>, Error>;
}
// TODO check usage of this trait
pub trait ToJsonResult: erased_serde::Serialize + fmt::Debug + AsAnyRef + AsAnyMut + Send {
fn to_json_result(&self) -> Result<Box<dyn ToJsonBytes>, Error>;
}
erased_serde::serialize_trait_object!(ToJsonResult);
impl AsAnyRef for serde_json::Value {
fn as_any_ref(&self) -> &dyn Any {
self
}
}
impl AsAnyMut for serde_json::Value {
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
impl ToJsonResult for serde_json::Value {
fn to_json_result(&self) -> Result<Box<dyn ToJsonBytes>, Error> {
Ok(Box::new(self.clone()))
}
}
impl ToJsonBytes for serde_json::Value {
fn to_json_bytes(&self) -> Result<Vec<u8>, Error> {
Ok(serde_json::to_vec(self)?)
}
}
pub trait Collected: fmt::Debug + Send + AsAnyRef + WithLen + ToJsonResult {}
erased_serde::serialize_trait_object!(Collected);
impl ToJsonResult for Box<dyn Collected> {
fn to_json_result(&self) -> Result<Box<dyn ToJsonBytes>, Error> {
self.as_ref().to_json_result()
}
}
impl WithLen for Box<dyn Collected> {
fn len(&self) -> usize {
self.as_ref().len()
}
}
impl Collected for Box<dyn Collected> {}
// TODO rename to `Typed`
pub trait CollectorType: fmt::Debug + Send + Unpin + WithLen {
type Input: Collectable;
type Output: Collected + ToJsonResult + Serialize;
fn ingest(&mut self, src: &mut Self::Input);
fn set_range_complete(&mut self);
fn set_timed_out(&mut self);
// TODO use this crate's Error instead:
fn result(&mut self, range: Option<SeriesRange>, binrange: Option<BinnedRangeEnum>) -> Result<Self::Output, Error>;
}
pub trait Collector: fmt::Debug + Send + Unpin + WithLen {
fn ingest(&mut self, src: &mut dyn Collectable);
fn set_range_complete(&mut self);
fn set_timed_out(&mut self);
// TODO factor the required parameters into new struct? Generic over events or binned?
fn result(
&mut self,
range: Option<SeriesRange>,
binrange: Option<BinnedRangeEnum>,
) -> Result<Box<dyn Collected>, Error>;
}
impl<T> Collector for T
where
T: fmt::Debug + CollectorType + 'static,
{
fn ingest(&mut self, src: &mut dyn Collectable) {
if let Some(src) = src.as_any_mut().downcast_mut::<<T as CollectorType>::Input>() {
trace!("sees incoming &mut ref");
T::ingest(self, src)
} else {
if let Some(src) = src.as_any_mut().downcast_mut::<Box<<T as CollectorType>::Input>>() {
trace!("sees incoming &mut Box");
T::ingest(self, src)
} else {
error!(
"No idea what this is. Expect: {} input {} got: {} {:?}",
any::type_name::<T>(),
any::type_name::<<T as CollectorType>::Input>(),
src.type_name(),
src
);
}
}
}
fn set_range_complete(&mut self) {
T::set_range_complete(self)
}
fn set_timed_out(&mut self) {
T::set_timed_out(self)
}
fn result(
&mut self,
range: Option<SeriesRange>,
binrange: Option<BinnedRangeEnum>,
) -> Result<Box<dyn Collected>, Error> {
let ret = T::result(self, range, binrange)?;
Ok(Box::new(ret))
}
}
// TODO rename to `Typed`
pub trait CollectableType: fmt::Debug + WithLen + AsAnyRef + AsAnyMut + TypeName + Send {
type Collector: CollectorType<Input = Self>;
fn new_collector() -> Self::Collector;
}
pub trait Collectable: fmt::Debug + WithLen + AsAnyRef + AsAnyMut + TypeName + Send {
fn new_collector(&self) -> Box<dyn Collector>;
}
impl TypeName for Box<dyn Events> {
fn type_name(&self) -> String {
self.as_ref().type_name()
}
}
impl Collectable for Box<dyn Events> {
fn new_collector(&self) -> Box<dyn Collector> {
self.as_ref().new_collector()
}
}
impl<T> Collectable for T
where
T: CollectableType + 'static,
{
fn new_collector(&self) -> Box<dyn Collector> {
Box::new(T::new_collector())
}
}
impl TypeName for Box<dyn Collectable> {
fn type_name(&self) -> String {
self.as_ref().type_name()
}
}
// TODO do this with some blanket impl:
impl WithLen for Box<dyn Collectable> {
fn len(&self) -> usize {
WithLen::len(self.as_ref())
}
}
// TODO do this with some blanket impl:
impl Collectable for Box<dyn Collectable> {
fn new_collector(&self) -> Box<dyn Collector> {
Collectable::new_collector(self.as_ref())
}
}
impl WithLen for Box<dyn TimeBinned> {
fn len(&self) -> usize {
WithLen::len(self.as_ref())
}
}
impl TypeName for Box<dyn TimeBinned> {
fn type_name(&self) -> String {
self.as_ref().type_name()
}
}
impl Collectable for Box<dyn TimeBinned> {
fn new_collector(&self) -> Box<dyn Collector> {
self.as_ref().new_collector()
}
}

View File

@@ -0,0 +1,11 @@
use crate::Events;
pub trait ByteEstimate {
fn byte_estimate(&self) -> u64;
}
impl ByteEstimate for Box<dyn Events> {
fn byte_estimate(&self) -> u64 {
self.as_ref().byte_estimate()
}
}

View File

@@ -0,0 +1,19 @@
// Required for any inner type of Sitemty.
pub trait FrameTypeInnerStatic {
const FRAME_TYPE_ID: u32;
}
// To be implemented by the T of Sitemty<T>, e.g. ScalarEvents.
pub trait FrameTypeInnerDyn {
// TODO check actual usage of this
fn frame_type_id(&self) -> u32;
}
impl<T> FrameTypeInnerDyn for T
where
T: FrameTypeInnerStatic,
{
fn frame_type_id(&self) -> u32 {
<Self as FrameTypeInnerStatic>::FRAME_TYPE_ID
}
}

View File

@@ -0,0 +1,25 @@
use chrono::DateTime;
use chrono::TimeZone;
use chrono::Utc;
use netpod::DATETIME_FMT_3MS;
use serde::Deserialize;
use serde::Serialize;
use serde::Serializer;
#[derive(Clone, Debug, Deserialize)]
pub struct IsoDateTime(DateTime<Utc>);
impl Serialize for IsoDateTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.0.format(DATETIME_FMT_3MS).to_string())
}
}
pub fn make_iso_ts(tss: &[u64]) -> Vec<IsoDateTime> {
tss.iter()
.map(|&k| IsoDateTime(Utc.timestamp_nanos(k as i64)))
.collect()
}

View File

@@ -0,0 +1,255 @@
pub mod collect_s;
pub mod container;
pub mod framable;
pub mod isodate;
pub mod overlap;
pub mod scalar_ops;
pub mod streamitem;
pub mod subfr;
pub mod test;
pub mod timebin;
pub mod transform;
pub mod bincode {
pub use bincode::*;
}
pub use futures_util;
use collect_s::Collectable;
use container::ByteEstimate;
use netpod::range::evrange::SeriesRange;
use std::any::Any;
use std::collections::VecDeque;
use std::fmt;
use timebin::TimeBinnable;
pub trait WithLen {
fn len(&self) -> usize;
}
pub trait Empty {
fn empty() -> Self;
}
pub trait Resettable {
fn reset(&mut self);
}
pub trait Appendable<STY>: Empty + WithLen {
fn push(&mut self, ts: u64, pulse: u64, value: STY);
}
pub trait TypeName {
fn type_name(&self) -> String;
}
pub trait AppendEmptyBin {
fn append_empty_bin(&mut self, ts1: u64, ts2: u64);
}
pub trait AppendAllFrom {
fn append_all_from(&mut self, src: &mut Self);
}
// TODO check usage, probably only for legacy
pub trait HasNonemptyFirstBin {
fn has_nonempty_first_bin(&self) -> bool;
}
pub trait AsAnyRef {
fn as_any_ref(&self) -> &dyn Any;
}
pub trait AsAnyMut {
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<T> AsAnyRef for Box<T>
where
T: AsAnyRef + ?Sized,
{
fn as_any_ref(&self) -> &dyn Any {
self.as_ref().as_any_ref()
}
}
impl<T> AsAnyMut for Box<T>
where
T: AsAnyMut + ?Sized,
{
fn as_any_mut(&mut self) -> &mut dyn Any {
self.as_mut().as_any_mut()
}
}
#[derive(Debug)]
pub enum MergeError {
NotCompatible,
Full,
}
impl From<MergeError> for err::Error {
fn from(e: MergeError) -> Self {
format!("{e:?}").into()
}
}
// TODO can I remove the Any bound?
/// Container of some form of events, for use as trait object.
pub trait Events:
fmt::Debug
+ TypeName
+ Any
+ Collectable
+ TimeBinnable
+ WithLen
+ ByteEstimate
+ Send
+ erased_serde::Serialize
+ EventsNonObj
{
fn as_time_binnable_ref(&self) -> &dyn TimeBinnable;
fn as_time_binnable_mut(&mut self) -> &mut dyn TimeBinnable;
fn verify(&self) -> bool;
fn output_info(&self);
fn as_collectable_mut(&mut self) -> &mut dyn Collectable;
fn as_collectable_with_default_ref(&self) -> &dyn Collectable;
fn as_collectable_with_default_mut(&mut self) -> &mut dyn Collectable;
fn ts_min(&self) -> Option<u64>;
fn ts_max(&self) -> Option<u64>;
// TODO is this used?
fn take_new_events_until_ts(&mut self, ts_end: u64) -> Box<dyn Events>;
fn new_empty_evs(&self) -> Box<dyn Events>;
fn drain_into_evs(&mut self, dst: &mut Box<dyn Events>, range: (usize, usize)) -> Result<(), MergeError>;
fn find_lowest_index_gt_evs(&self, ts: u64) -> Option<usize>;
fn find_lowest_index_ge_evs(&self, ts: u64) -> Option<usize>;
fn find_highest_index_lt_evs(&self, ts: u64) -> Option<usize>;
fn clone_dyn(&self) -> Box<dyn Events>;
fn partial_eq_dyn(&self, other: &dyn Events) -> bool;
fn serde_id(&self) -> &'static str;
fn nty_id(&self) -> u32;
fn tss(&self) -> &VecDeque<u64>;
fn pulses(&self) -> &VecDeque<u64>;
fn frame_type_id(&self) -> u32;
fn to_min_max_avg(&mut self) -> Box<dyn Events>;
}
impl WithLen for Box<dyn Events> {
fn len(&self) -> usize {
self.as_ref().len()
}
}
pub trait EventsNonObj {
fn into_tss_pulses(self: Box<Self>) -> (VecDeque<u64>, VecDeque<u64>);
}
erased_serde::serialize_trait_object!(Events);
impl PartialEq for Box<dyn Events> {
fn eq(&self, other: &Self) -> bool {
Events::partial_eq_dyn(self.as_ref(), other.as_ref())
}
}
impl EventsNonObj for Box<dyn Events> {
fn into_tss_pulses(self: Box<Self>) -> (VecDeque<u64>, VecDeque<u64>) {
todo!()
}
}
impl Events for Box<dyn Events> {
fn as_time_binnable_ref(&self) -> &dyn TimeBinnable {
Events::as_time_binnable_ref(self.as_ref())
}
fn as_time_binnable_mut(&mut self) -> &mut dyn TimeBinnable {
Events::as_time_binnable_mut(self.as_mut())
}
fn verify(&self) -> bool {
Events::verify(self.as_ref())
}
fn output_info(&self) {
Events::output_info(self.as_ref())
}
fn as_collectable_mut(&mut self) -> &mut dyn Collectable {
Events::as_collectable_mut(self.as_mut())
}
fn as_collectable_with_default_ref(&self) -> &dyn Collectable {
Events::as_collectable_with_default_ref(self.as_ref())
}
fn as_collectable_with_default_mut(&mut self) -> &mut dyn Collectable {
Events::as_collectable_with_default_mut(self.as_mut())
}
fn ts_min(&self) -> Option<u64> {
Events::ts_min(self.as_ref())
}
fn ts_max(&self) -> Option<u64> {
Events::ts_max(self.as_ref())
}
fn take_new_events_until_ts(&mut self, ts_end: u64) -> Box<dyn Events> {
Events::take_new_events_until_ts(self.as_mut(), ts_end)
}
fn new_empty_evs(&self) -> Box<dyn Events> {
Events::new_empty_evs(self.as_ref())
}
fn drain_into_evs(&mut self, dst: &mut Box<dyn Events>, range: (usize, usize)) -> Result<(), MergeError> {
Events::drain_into_evs(self.as_mut(), dst, range)
}
fn find_lowest_index_gt_evs(&self, ts: u64) -> Option<usize> {
Events::find_lowest_index_gt_evs(self.as_ref(), ts)
}
fn find_lowest_index_ge_evs(&self, ts: u64) -> Option<usize> {
Events::find_lowest_index_ge_evs(self.as_ref(), ts)
}
fn find_highest_index_lt_evs(&self, ts: u64) -> Option<usize> {
Events::find_highest_index_lt_evs(self.as_ref(), ts)
}
fn clone_dyn(&self) -> Box<dyn Events> {
Events::clone_dyn(self.as_ref())
}
fn partial_eq_dyn(&self, other: &dyn Events) -> bool {
Events::partial_eq_dyn(self.as_ref(), other)
}
fn serde_id(&self) -> &'static str {
Events::serde_id(self.as_ref())
}
fn nty_id(&self) -> u32 {
Events::nty_id(self.as_ref())
}
fn tss(&self) -> &VecDeque<u64> {
Events::tss(self.as_ref())
}
fn pulses(&self) -> &VecDeque<u64> {
Events::pulses(self.as_ref())
}
fn frame_type_id(&self) -> u32 {
Events::frame_type_id(self.as_ref())
}
fn to_min_max_avg(&mut self) -> Box<dyn Events> {
Events::to_min_max_avg(self.as_mut())
}
}

View File

@@ -0,0 +1,151 @@
use netpod::log::*;
use netpod::range::evrange::SeriesRange;
// TODO rename, no more deque involved
pub trait HasTimestampDeque {
fn timestamp_min(&self) -> Option<u64>;
fn timestamp_max(&self) -> Option<u64>;
fn pulse_min(&self) -> Option<u64>;
fn pulse_max(&self) -> Option<u64>;
}
pub trait RangeOverlapInfo {
fn ends_before(&self, range: &SeriesRange) -> bool;
fn ends_after(&self, range: &SeriesRange) -> bool;
fn starts_after(&self, range: &SeriesRange) -> bool;
}
#[macro_export]
macro_rules! impl_range_overlap_info_events {
($ty:ident) => {
impl<STY> RangeOverlapInfo for $ty<STY>
where
STY: ScalarOps,
{
fn ends_before(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(max) = HasTimestampDeque::timestamp_max(self) {
max < range.beg_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(max) = HasTimestampDeque::pulse_max(self) {
max < range.beg_u64()
} else {
true
}
} else {
error!("unexpected");
true
}
}
fn ends_after(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(max) = HasTimestampDeque::timestamp_max(self) {
max >= range.end_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(max) = HasTimestampDeque::pulse_max(self) {
max >= range.end_u64()
} else {
true
}
} else {
error!("unexpected");
false
}
}
fn starts_after(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(min) = HasTimestampDeque::timestamp_min(self) {
min >= range.end_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(min) = HasTimestampDeque::pulse_min(self) {
min >= range.end_u64()
} else {
true
}
} else {
error!("unexpected");
true
}
}
}
};
}
#[macro_export]
macro_rules! impl_range_overlap_info_bins {
($ty:ident) => {
impl<STY> RangeOverlapInfo for $ty<STY>
where
STY: ScalarOps,
{
fn ends_before(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(max) = HasTimestampDeque::timestamp_max(self) {
max <= range.beg_u64()
} else {
true
}
} else if range.is_pulse() {
// TODO for the time being, the ts represent either ts or pulse
if let Some(max) = HasTimestampDeque::timestamp_max(self) {
max <= range.beg_u64()
} else {
true
}
} else {
error!("unexpected");
true
}
}
fn ends_after(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(max) = HasTimestampDeque::timestamp_max(self) {
max > range.end_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(max) = HasTimestampDeque::timestamp_max(self) {
max > range.end_u64()
} else {
true
}
} else {
error!("unexpected");
false
}
}
fn starts_after(&self, range: &SeriesRange) -> bool {
if range.is_time() {
if let Some(min) = HasTimestampDeque::timestamp_min(self) {
min >= range.end_u64()
} else {
true
}
} else if range.is_pulse() {
if let Some(min) = HasTimestampDeque::timestamp_min(self) {
min >= range.end_u64()
} else {
true
}
} else {
error!("unexpected");
true
}
}
}
};
}

View File

@@ -0,0 +1,214 @@
use crate::subfr::SubFrId;
use serde::Serialize;
use std::fmt;
use std::ops;
#[allow(unused)]
const fn is_nan_int<T>(_x: &T) -> bool {
false
}
#[allow(unused)]
fn is_nan_f32(x: f32) -> bool {
x.is_nan()
}
#[allow(unused)]
fn is_nan_f64(x: f64) -> bool {
x.is_nan()
}
pub trait AsPrimF32 {
fn as_prim_f32_b(&self) -> f32;
}
macro_rules! impl_as_prim_f32 {
($ty:ident) => {
impl AsPrimF32 for $ty {
fn as_prim_f32_b(&self) -> f32 {
*self as f32
}
}
};
}
impl_as_prim_f32!(u8);
impl_as_prim_f32!(u16);
impl_as_prim_f32!(u32);
impl_as_prim_f32!(u64);
impl_as_prim_f32!(i8);
impl_as_prim_f32!(i16);
impl_as_prim_f32!(i32);
impl_as_prim_f32!(i64);
impl_as_prim_f32!(f32);
impl_as_prim_f32!(f64);
impl AsPrimF32 for bool {
fn as_prim_f32_b(&self) -> f32 {
if *self {
1.
} else {
0.
}
}
}
impl AsPrimF32 for String {
fn as_prim_f32_b(&self) -> f32 {
// Well, at least some impl.
self.len() as f32
}
}
pub trait ScalarOps:
fmt::Debug + Clone + PartialOrd + PartialEq + SubFrId + AsPrimF32 + Serialize + Unpin + Send + 'static
{
fn zero_b() -> Self;
fn equal_slack(&self, rhs: &Self) -> bool;
fn add(&mut self, rhs: &Self);
fn div(&mut self, n: usize);
fn find_vec_min(a: &Vec<Self>) -> Option<Self>;
fn find_vec_max(a: &Vec<Self>) -> Option<Self>;
fn avg_vec(a: &Vec<Self>) -> Option<Self>;
}
macro_rules! impl_scalar_ops {
($ty:ident, $zero:expr, $equal_slack:ident, $mac_add:ident, $mac_div:ident) => {
impl ScalarOps for $ty {
fn zero_b() -> Self {
$zero
}
fn equal_slack(&self, rhs: &Self) -> bool {
$equal_slack(self, rhs)
}
fn add(&mut self, rhs: &Self) {
$mac_add!(self, rhs);
}
fn div(&mut self, n: usize) {
$mac_div!(self, n);
}
fn find_vec_min(a: &Vec<Self>) -> Option<Self> {
if a.len() == 0 {
None
} else {
let mut k = &a[0];
for (i, v) in a.iter().enumerate() {
if *v < *k {
k = &a[i];
}
}
Some(k.clone())
}
}
fn find_vec_max(a: &Vec<Self>) -> Option<Self> {
if a.len() == 0 {
None
} else {
let mut k = &a[0];
for (i, v) in a.iter().enumerate() {
if *v > *k {
k = &a[i];
}
}
Some(k.clone())
}
}
fn avg_vec(a: &Vec<Self>) -> Option<Self> {
if a.len() == 0 {
None
} else {
let mut sum = Self::zero_b();
let mut c = 0;
for v in a.iter() {
sum.add(v);
c += 1;
}
ScalarOps::div(&mut sum, c);
Some(sum)
}
}
}
};
}
fn equal_int<T: PartialEq>(a: T, b: T) -> bool {
a == b
}
fn equal_f32(&a: &f32, &b: &f32) -> bool {
(a - b).abs() < 1e-4 || (a / b > 0.999 && a / b < 1.001)
}
fn equal_f64(&a: &f64, &b: &f64) -> bool {
(a - b).abs() < 1e-6 || (a / b > 0.99999 && a / b < 1.00001)
}
fn equal_bool(&a: &bool, &b: &bool) -> bool {
a == b
}
fn equal_string(a: &String, b: &String) -> bool {
a == b
}
fn add_int<T: ops::AddAssign>(a: &mut T, b: &T) {
ops::AddAssign::add_assign(a, todo!());
}
macro_rules! add_int {
($a:expr, $b:expr) => {
*$a += $b;
};
}
macro_rules! add_bool {
($a:expr, $b:expr) => {
*$a |= $b;
};
}
macro_rules! add_string {
($a:expr, $b:expr) => {
$a.push_str($b);
};
}
macro_rules! div_int {
($a:expr, $b:expr) => {
// TODO for average calculation, the accumulator must be large enough!
// Use u64 for all ints, and f32 for all floats.
// Therefore, the name "add" is too general.
//*$a /= $b;
};
}
macro_rules! div_bool {
($a:expr, $b:expr) => {
//
};
}
macro_rules! div_string {
($a:expr, $b:expr) => {
//
};
}
impl_scalar_ops!(u8, 0, equal_int, add_int, div_int);
impl_scalar_ops!(u16, 0, equal_int, add_int, div_int);
impl_scalar_ops!(u32, 0, equal_int, add_int, div_int);
impl_scalar_ops!(u64, 0, equal_int, add_int, div_int);
impl_scalar_ops!(i8, 0, equal_int, add_int, div_int);
impl_scalar_ops!(i16, 0, equal_int, add_int, div_int);
impl_scalar_ops!(i32, 0, equal_int, add_int, div_int);
impl_scalar_ops!(i64, 0, equal_int, add_int, div_int);
impl_scalar_ops!(f32, 0., equal_f32, add_int, div_int);
impl_scalar_ops!(f64, 0., equal_f64, add_int, div_int);
impl_scalar_ops!(bool, false, equal_bool, add_bool, div_bool);
impl_scalar_ops!(String, String::new(), equal_string, add_string, div_string);

View File

@@ -0,0 +1,179 @@
use crate::timebin::TimeBinned;
use err::Error;
use netpod::log::Level;
use netpod::DiskStats;
use netpod::EventDataReadStats;
use netpod::RangeFilterStats;
use serde::Deserialize;
use serde::Serialize;
pub const TERM_FRAME_TYPE_ID: u32 = 0xaa01;
pub const ERROR_FRAME_TYPE_ID: u32 = 0xaa02;
pub const SITEMTY_NONSPEC_FRAME_TYPE_ID: u32 = 0xaa04;
pub const EVENT_QUERY_JSON_STRING_FRAME: u32 = 0x100;
pub const EVENTS_0D_FRAME_TYPE_ID: u32 = 0x500;
pub const MIN_MAX_AVG_DIM_0_BINS_FRAME_TYPE_ID: u32 = 0x700;
pub const MIN_MAX_AVG_DIM_1_BINS_FRAME_TYPE_ID: u32 = 0x800;
pub const MIN_MAX_AVG_WAVE_BINS: u32 = 0xa00;
pub const WAVE_EVENTS_FRAME_TYPE_ID: u32 = 0xb00;
pub const LOG_FRAME_TYPE_ID: u32 = 0xc00;
pub const STATS_FRAME_TYPE_ID: u32 = 0xd00;
pub const RANGE_COMPLETE_FRAME_TYPE_ID: u32 = 0xe00;
pub const EVENT_FULL_FRAME_TYPE_ID: u32 = 0x2200;
pub const EVENTS_ITEM_FRAME_TYPE_ID: u32 = 0x2300;
pub const STATS_EVENTS_FRAME_TYPE_ID: u32 = 0x2400;
pub const ITEMS_2_CHANNEL_EVENTS_FRAME_TYPE_ID: u32 = 0x2500;
pub const X_BINNED_SCALAR_EVENTS_FRAME_TYPE_ID: u32 = 0x8800;
pub const X_BINNED_WAVE_EVENTS_FRAME_TYPE_ID: u32 = 0x8900;
pub const DATABUFFER_EVENT_BLOB_FRAME_TYPE_ID: u32 = 0x8a00;
pub fn bool_is_false(j: &bool) -> bool {
*j == false
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum RangeCompletableItem<T> {
RangeComplete,
Data(T),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum StatsItem {
EventDataReadStats(EventDataReadStats),
RangeFilterStats(RangeFilterStats),
DiskStats(DiskStats),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum StreamItem<T> {
DataItem(T),
Log(LogItem),
Stats(StatsItem),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct LogItem {
pub node_ix: u32,
#[serde(with = "levelserde")]
pub level: Level,
pub msg: String,
}
impl LogItem {
pub fn quick(level: Level, msg: String) -> Self {
Self {
level,
msg,
node_ix: 42,
}
}
}
pub type Sitemty<T> = Result<StreamItem<RangeCompletableItem<T>>, Error>;
#[macro_export]
macro_rules! on_sitemty_range_complete {
($item:expr, $ex:expr) => {
if let Ok($crate::StreamItem::DataItem($crate::RangeCompletableItem::RangeComplete)) = $item {
$ex
}
};
}
#[macro_export]
macro_rules! on_sitemty_data_old {
($item:expr, $ex:expr) => {
if let Ok($crate::streamitem::StreamItem::DataItem($crate::streamitem::RangeCompletableItem::Data(item))) =
$item
{
$ex(item)
} else {
$item
}
};
}
#[macro_export]
macro_rules! on_sitemty_data {
($item:expr, $ex:expr) => {{
use $crate::streamitem::RangeCompletableItem;
use $crate::streamitem::StreamItem;
match $item {
Ok(x) => match x {
StreamItem::DataItem(x) => match x {
RangeCompletableItem::Data(x) => $ex(x),
RangeCompletableItem::RangeComplete => {
Ok(StreamItem::DataItem(RangeCompletableItem::RangeComplete))
}
},
StreamItem::Log(x) => Ok(StreamItem::Log(x)),
StreamItem::Stats(x) => Ok(StreamItem::Stats(x)),
},
Err(x) => Err(x),
}
}};
}
pub fn sitem_data<X>(x: X) -> Sitemty<X> {
Ok(StreamItem::DataItem(RangeCompletableItem::Data(x)))
}
mod levelserde {
use super::Level;
use serde::de::{self, Visitor};
use serde::{Deserializer, Serializer};
use std::fmt;
pub fn serialize<S>(t: &Level, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let g = match *t {
Level::ERROR => 1,
Level::WARN => 2,
Level::INFO => 3,
Level::DEBUG => 4,
Level::TRACE => 5,
};
se.serialize_u32(g)
}
struct VisitLevel;
impl VisitLevel {
fn from_u32(x: u32) -> Level {
match x {
1 => Level::ERROR,
2 => Level::WARN,
3 => Level::INFO,
4 => Level::DEBUG,
5 => Level::TRACE,
_ => Level::TRACE,
}
}
}
impl<'de> Visitor<'de> for VisitLevel {
type Value = Level;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "expect Level code")
}
fn visit_u64<E>(self, val: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(VisitLevel::from_u32(val as _))
}
}
pub fn deserialize<'de, D>(de: D) -> Result<Level, D::Error>
where
D: Deserializer<'de>,
{
de.deserialize_u32(VisitLevel)
}
}
erased_serde::serialize_trait_object!(TimeBinned);

View File

@@ -0,0 +1,51 @@
pub trait SubFrId {
const SUB: u32;
}
impl SubFrId for u8 {
const SUB: u32 = 0x03;
}
impl SubFrId for u16 {
const SUB: u32 = 0x05;
}
impl SubFrId for u32 {
const SUB: u32 = 0x08;
}
impl SubFrId for u64 {
const SUB: u32 = 0x0a;
}
impl SubFrId for i8 {
const SUB: u32 = 0x02;
}
impl SubFrId for i16 {
const SUB: u32 = 0x04;
}
impl SubFrId for i32 {
const SUB: u32 = 0x07;
}
impl SubFrId for i64 {
const SUB: u32 = 0x09;
}
impl SubFrId for f32 {
const SUB: u32 = 0x0b;
}
impl SubFrId for f64 {
const SUB: u32 = 0x0c;
}
impl SubFrId for bool {
const SUB: u32 = 0x0d;
}
impl SubFrId for String {
const SUB: u32 = 0x0e;
}

View File

@@ -0,0 +1,87 @@
pub fn f32_cmp_near(x: f32, y: f32, abs: f32, rel: f32) -> bool {
/*let x = {
let mut a = x.to_le_bytes();
a[0] &= 0xf0;
f32::from_ne_bytes(a)
};
let y = {
let mut a = y.to_le_bytes();
a[0] &= 0xf0;
f32::from_ne_bytes(a)
};
x == y*/
let ad = (x - y).abs();
ad <= abs || (ad / y).abs() <= rel
}
pub fn f64_cmp_near(x: f64, y: f64, abs: f64, rel: f64) -> bool {
/*let x = {
let mut a = x.to_le_bytes();
a[0] &= 0x00;
a[1] &= 0x00;
f64::from_ne_bytes(a)
};
let y = {
let mut a = y.to_le_bytes();
a[0] &= 0x00;
a[1] &= 0x00;
f64::from_ne_bytes(a)
};
x == y*/
let ad = (x - y).abs();
ad <= abs || (ad / y).abs() <= rel
}
pub fn f32_iter_cmp_near<A, B>(a: A, b: B, abs: f32, rel: f32) -> bool
where
A: IntoIterator<Item = f32>,
B: IntoIterator<Item = f32>,
{
let mut a = a.into_iter();
let mut b = b.into_iter();
loop {
let x = a.next();
let y = b.next();
if let (Some(x), Some(y)) = (x, y) {
if !f32_cmp_near(x, y, abs, rel) {
return false;
}
} else if x.is_some() || y.is_some() {
return false;
} else {
return true;
}
}
}
pub fn f64_iter_cmp_near<A, B>(a: A, b: B, abs: f64, rel: f64) -> bool
where
A: IntoIterator<Item = f64>,
B: IntoIterator<Item = f64>,
{
let mut a = a.into_iter();
let mut b = b.into_iter();
loop {
let x = a.next();
let y = b.next();
if let (Some(x), Some(y)) = (x, y) {
if !f64_cmp_near(x, y, abs, rel) {
return false;
}
} else if x.is_some() || y.is_some() {
return false;
} else {
return true;
}
}
}
#[test]
fn test_f32_iter_cmp_near() {
let a = [-127.553e17];
let b = [-127.554e17];
assert_eq!(f32_iter_cmp_near(a, b, 0.000001, 0.000001), false);
let a = [-127.55300e17];
let b = [-127.55301e17];
assert_eq!(f32_iter_cmp_near(a, b, 0.000001, 0.000001), true);
}

View File

@@ -0,0 +1,473 @@
pub mod timebinimpl;
use crate::collect_s::Collectable;
use crate::collect_s::Collector;
use crate::collect_s::ToJsonResult;
use crate::overlap::RangeOverlapInfo;
use crate::AsAnyMut;
use crate::AsAnyRef;
use crate::Events;
use crate::Resettable;
use crate::TypeName;
use crate::WithLen;
use err::Error;
use netpod::log::*;
use netpod::range::evrange::SeriesRange;
use netpod::BinnedRangeEnum;
use std::any::Any;
use std::fmt;
use std::ops::Range;
// TODO can probably be removed.
pub trait TimeBins {
fn ts_min(&self) -> Option<u64>;
fn ts_max(&self) -> Option<u64>;
fn ts_min_max(&self) -> Option<(u64, u64)>;
}
pub trait TimeBinnerTy: fmt::Debug + Send + Unpin {
type Input: fmt::Debug;
type Output: fmt::Debug;
fn ingest(&mut self, item: &mut Self::Input);
fn set_range_complete(&mut self);
fn bins_ready_count(&self) -> usize;
fn bins_ready(&mut self) -> Option<Self::Output>;
/// If there is a bin in progress with non-zero count, push it to the result set.
/// With push_empty == true, a bin in progress is pushed even if it contains no counts.
fn push_in_progress(&mut self, push_empty: bool);
/// Implies `Self::push_in_progress` but in addition, pushes a zero-count bin if the call
/// to `push_in_progress` did not change the result count, as long as edges are left.
/// The next call to `Self::bins_ready_count` must return one higher count than before.
fn cycle(&mut self);
fn empty(&self) -> Option<Self::Output>;
fn append_empty_until_end(&mut self);
}
pub trait TimeBinnableTy: fmt::Debug + WithLen + Send + Sized {
type TimeBinner: TimeBinnerTy<Input = Self>;
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Self::TimeBinner;
}
/// Data in time-binned form.
pub trait TimeBinned: Any + TypeName + TimeBinnable + Resettable + Collectable + erased_serde::Serialize {
fn clone_box_time_binned(&self) -> Box<dyn TimeBinned>;
fn as_time_binnable_ref(&self) -> &dyn TimeBinnable;
fn as_time_binnable_mut(&mut self) -> &mut dyn TimeBinnable;
fn as_collectable_mut(&mut self) -> &mut dyn Collectable;
fn edges_slice(&self) -> (&[u64], &[u64]);
fn counts(&self) -> &[u64];
fn mins(&self) -> Vec<f32>;
fn maxs(&self) -> Vec<f32>;
fn avgs(&self) -> Vec<f32>;
fn validate(&self) -> Result<(), String>;
fn empty_like_self_box_time_binned(&self) -> Box<dyn TimeBinned>;
fn to_simple_bins_f32(&mut self) -> Box<dyn TimeBinned>;
fn drain_into_tb(&mut self, dst: &mut dyn TimeBinned, range: Range<usize>) -> Result<(), Error>;
}
impl Clone for Box<dyn TimeBinned> {
fn clone(&self) -> Self {
self.clone_box_time_binned()
}
}
impl RangeOverlapInfo for Box<dyn TimeBinned> {
fn ends_before(&self, range: &SeriesRange) -> bool {
todo!()
}
fn ends_after(&self, range: &SeriesRange) -> bool {
todo!()
}
fn starts_after(&self, range: &SeriesRange) -> bool {
todo!()
}
}
impl TimeBinnable for Box<dyn TimeBinned> {
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Box<dyn TimeBinner> {
todo!()
}
fn to_box_to_json_result(&self) -> Box<dyn ToJsonResult> {
todo!()
}
}
pub trait TimeBinner: fmt::Debug + Send {
fn ingest(&mut self, item: &mut dyn TimeBinnable);
fn bins_ready_count(&self) -> usize;
fn bins_ready(&mut self) -> Option<Box<dyn TimeBinned>>;
/// If there is a bin in progress with non-zero count, push it to the result set.
/// With push_empty == true, a bin in progress is pushed even if it contains no counts.
fn push_in_progress(&mut self, push_empty: bool);
/// Implies `Self::push_in_progress` but in addition, pushes a zero-count bin if the call
/// to `push_in_progress` did not change the result count, as long as edges are left.
/// The next call to `Self::bins_ready_count` must return one higher count than before.
fn cycle(&mut self);
fn set_range_complete(&mut self);
fn empty(&self) -> Box<dyn TimeBinned>;
fn append_empty_until_end(&mut self);
}
// TODO remove the Any bound. Factor out into custom AsAny trait.
/// Provides a time-binned representation of the implementing type.
/// In contrast to `TimeBinnableType` this is meant for trait objects.
pub trait TimeBinnable:
fmt::Debug + WithLen + RangeOverlapInfo + Collectable + Any + AsAnyRef + AsAnyMut + Send
{
// TODO implementors may fail if edges contain not at least 2 entries.
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Box<dyn TimeBinner>;
// TODO just a helper for the empty result.
fn to_box_to_json_result(&self) -> Box<dyn ToJsonResult>;
}
impl WithLen for Box<dyn TimeBinnable> {
fn len(&self) -> usize {
WithLen::len(self.as_ref())
}
}
impl RangeOverlapInfo for Box<dyn TimeBinnable> {
fn ends_before(&self, range: &SeriesRange) -> bool {
todo!()
}
fn ends_after(&self, range: &SeriesRange) -> bool {
todo!()
}
fn starts_after(&self, range: &SeriesRange) -> bool {
todo!()
}
}
impl TimeBinnable for Box<dyn TimeBinnable> {
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Box<dyn TimeBinner> {
todo!()
}
fn to_box_to_json_result(&self) -> Box<dyn ToJsonResult> {
todo!()
}
}
impl RangeOverlapInfo for Box<dyn Events> {
fn ends_before(&self, range: &SeriesRange) -> bool {
todo!()
}
fn ends_after(&self, range: &SeriesRange) -> bool {
todo!()
}
fn starts_after(&self, range: &SeriesRange) -> bool {
todo!()
}
}
impl TimeBinnable for Box<dyn Events> {
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Box<dyn TimeBinner> {
TimeBinnable::time_binner_new(self.as_ref(), binrange, do_time_weight)
}
fn to_box_to_json_result(&self) -> Box<dyn ToJsonResult> {
TimeBinnable::to_box_to_json_result(self.as_ref())
}
}
impl TypeName for Box<dyn TimeBinnable> {
fn type_name(&self) -> String {
format!("Box<dyn TimeBinnable> TODO TypeName for Box<dyn TimeBinnable>")
}
}
impl Collectable for Box<dyn TimeBinnable> {
fn new_collector(&self) -> Box<dyn Collector> {
self.as_ref().new_collector()
}
}
#[derive(Debug)]
pub struct TimeBinnerDynStruct {
binrange: BinnedRangeEnum,
do_time_weight: bool,
binner: Option<Box<dyn TimeBinner>>,
}
impl TimeBinnerDynStruct {
pub fn type_name() -> &'static str {
std::any::type_name::<Self>()
}
pub fn new(binrange: BinnedRangeEnum, do_time_weight: bool, binner: Box<dyn TimeBinner>) -> Self {
Self {
binrange,
do_time_weight,
binner: Some(binner),
}
}
}
impl TimeBinnerTy for TimeBinnerDynStruct {
type Input = Box<dyn TimeBinnable>;
type Output = Box<dyn TimeBinned>;
fn ingest(&mut self, item: &mut Self::Input) {
trace!("{} INGEST {:?}", Self::type_name(), item);
if self.binner.is_none() {
self.binner = Some(Box::new(TimeBinnableTy::time_binner_new(
item,
self.binrange.clone(),
self.do_time_weight,
)));
}
self.binner.as_mut().unwrap().as_mut().ingest(item.as_mut())
}
fn set_range_complete(&mut self) {
if let Some(k) = self.binner.as_mut() {
k.set_range_complete()
}
}
fn bins_ready_count(&self) -> usize {
if let Some(k) = self.binner.as_ref() {
k.bins_ready_count()
} else {
0
}
}
fn bins_ready(&mut self) -> Option<Self::Output> {
if let Some(k) = self.binner.as_mut() {
k.bins_ready()
} else {
None
}
}
fn push_in_progress(&mut self, push_empty: bool) {
if let Some(k) = self.binner.as_mut() {
k.push_in_progress(push_empty)
}
}
fn cycle(&mut self) {
if let Some(k) = self.binner.as_mut() {
k.cycle()
}
}
fn empty(&self) -> Option<Self::Output> {
if let Some(k) = self.binner.as_ref() {
Some(k.empty())
} else {
warn!("TimeBinnerDynStruct::empty called with binner None");
None
}
}
fn append_empty_until_end(&mut self) {
todo!()
}
}
impl TimeBinner for TimeBinnerDynStruct {
fn ingest(&mut self, item: &mut dyn TimeBinnable) {
todo!()
}
fn bins_ready_count(&self) -> usize {
todo!()
}
fn bins_ready(&mut self) -> Option<Box<dyn TimeBinned>> {
todo!()
}
fn push_in_progress(&mut self, push_empty: bool) {
todo!()
}
fn cycle(&mut self) {
todo!()
}
fn set_range_complete(&mut self) {
todo!()
}
fn empty(&self) -> Box<dyn TimeBinned> {
todo!()
}
fn append_empty_until_end(&mut self) {
todo!()
}
}
#[derive(Debug)]
pub struct TimeBinnerDynStruct2 {
binrange: BinnedRangeEnum,
do_time_weight: bool,
binner: Option<Box<dyn TimeBinner>>,
}
impl TimeBinnerDynStruct2 {
pub fn type_name() -> &'static str {
std::any::type_name::<Self>()
}
pub fn new(binrange: BinnedRangeEnum, do_time_weight: bool, binner: Box<dyn TimeBinner>) -> Self {
Self {
binrange,
do_time_weight,
binner: Some(binner),
}
}
}
impl TimeBinnerTy for TimeBinnerDynStruct2 {
type Input = Box<dyn TimeBinned>;
type Output = Box<dyn TimeBinned>;
fn ingest(&mut self, item: &mut Self::Input) {
trace!("{} INGEST {:?}", Self::type_name(), item);
if self.binner.is_none() {
self.binner = Some(Box::new(TimeBinnableTy::time_binner_new(
item,
self.binrange.clone(),
self.do_time_weight,
)));
}
self.binner
.as_mut()
.unwrap()
.as_mut()
.ingest(item.as_time_binnable_mut())
}
fn set_range_complete(&mut self) {
if let Some(k) = self.binner.as_mut() {
k.set_range_complete()
}
}
fn bins_ready_count(&self) -> usize {
if let Some(k) = self.binner.as_ref() {
k.bins_ready_count()
} else {
0
}
}
fn bins_ready(&mut self) -> Option<Self::Output> {
if let Some(k) = self.binner.as_mut() {
k.bins_ready()
} else {
None
}
}
fn push_in_progress(&mut self, push_empty: bool) {
if let Some(k) = self.binner.as_mut() {
k.push_in_progress(push_empty)
}
}
fn cycle(&mut self) {
if let Some(k) = self.binner.as_mut() {
k.cycle()
}
}
fn empty(&self) -> Option<Self::Output> {
if let Some(k) = self.binner.as_ref() {
Some(k.empty())
} else {
warn!("TimeBinnerDynStruct::empty called with binner None");
None
}
}
fn append_empty_until_end(&mut self) {
todo!()
}
}
impl TimeBinner for TimeBinnerDynStruct2 {
fn ingest(&mut self, item: &mut dyn TimeBinnable) {
todo!()
}
fn bins_ready_count(&self) -> usize {
todo!()
}
fn bins_ready(&mut self) -> Option<Box<dyn TimeBinned>> {
todo!()
}
fn push_in_progress(&mut self, push_empty: bool) {
todo!()
}
fn cycle(&mut self) {
todo!()
}
fn set_range_complete(&mut self) {
todo!()
}
fn empty(&self) -> Box<dyn TimeBinned> {
todo!()
}
fn append_empty_until_end(&mut self) {
todo!()
}
}
impl TimeBinnableTy for Box<dyn TimeBinnable> {
type TimeBinner = TimeBinnerDynStruct;
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Self::TimeBinner {
let binner = self.as_ref().time_binner_new(binrange.clone(), do_time_weight);
TimeBinnerDynStruct::new(binrange, do_time_weight, binner)
}
}
impl TimeBinnableTy for Box<dyn TimeBinned> {
type TimeBinner = TimeBinnerDynStruct2;
fn time_binner_new(&self, binrange: BinnedRangeEnum, do_time_weight: bool) -> Self::TimeBinner {
let binner = self
.as_time_binnable_ref()
.time_binner_new(binrange.clone(), do_time_weight);
TimeBinnerDynStruct2::new(binrange, do_time_weight, binner)
}
}
pub trait TimeBinnerIngest: fmt::Debug + TypeName + Send {
fn ingest_inrange(&mut self, item: &mut dyn TimeBinnable) -> Result<(), Error>;
}

View File

@@ -0,0 +1,199 @@
#![allow(unused)]
use crate::timebin::TimeBinnable;
use crate::timebin::TimeBinned;
use crate::timebin::TimeBinner;
use crate::timebin::TimeBinnerIngest;
use crate::TypeName;
use netpod::log::*;
use netpod::range::evrange::NanoRange;
#[allow(unused)]
macro_rules! trace2 {
($($arg:tt)*) => { trace!($($arg)*) };
}
#[allow(unused)]
macro_rules! trace_ingest {
($($arg:tt)*) => { trace!($($arg)*) };
}
#[cfg(DISABLED)]
impl<T> TimeBinner for T
where
T: TimeBinnerIngest,
{
fn bins_ready_count(&self) -> usize {
match &self.ready {
Some(k) => k.len(),
None => 0,
}
}
fn bins_ready(&mut self) -> Option<Box<dyn TimeBinned>> {
match self.ready.take() {
Some(k) => Some(Box::new(k)),
None => None,
}
}
fn ingest(&mut self, item: &mut dyn TimeBinnable) {
trace2!(
"TimeBinner for {} ingest agg.range {:?} item {:?}",
self.type_name(),
self.agg.range(),
item
);
if item.len() == 0 {
// Return already here, RangeOverlapInfo would not give much sense.
return;
}
// TODO optimize by remembering at which event array index we have arrived.
// That needs modified interfaces which can take and yield the start and latest index.
loop {
while item.starts_after(self.agg.range()) {
trace!(
"{} IGNORE ITEM AND CYCLE BECAUSE item.starts_after",
self.type_name()
);
self.cycle();
if self.rng.is_none() {
warn!("{} no more bin in edges B", self.type_name());
return;
}
}
if item.ends_before(self.agg.range()) {
trace!("{} IGNORE ITEM BECAUSE ends_before", self.type_name());
return;
} else {
if self.rng.is_none() {
trace!("{} no more bin in edges D", self.type_name());
return;
} else {
match TimeBinnerIngest::ingest_inrange(self, item) {
Ok(()) => {
if item.ends_after(self.agg.range()) {
trace_ingest!("{} FED ITEM, ENDS AFTER.", self.type_name());
self.cycle();
if self.rng.is_none() {
warn!("{} no more bin in edges C", self.type_name());
return;
} else {
trace_ingest!("{} FED ITEM, CYCLED, CONTINUE.", self.type_name());
}
} else {
trace_ingest!("{} FED ITEM.", self.type_name());
break;
}
}
Err(e) => {
error!("{}::ingest {}", self.type_name(), e);
}
}
/*
// Move to TimeBinnerIngest
if let Some(item) = item
.as_any_ref()
// TODO make statically sure that we attempt to cast to the correct type here:
.downcast_ref::<<EventsDim0Aggregator<STY> as TimeBinnableTypeAggregator>::Input>()
{
// TODO collect statistics associated with this request:
trace_ingest!("{self_name} FEED THE ITEM...");
self.agg.ingest(item);
} else {
error!("{self_name}::ingest unexpected item type");
};
*/
}
}
}
}
fn push_in_progress(&mut self, push_empty: bool) {
trace!("{}::push_in_progress push_empty {push_empty}", self.type_name());
// TODO expand should be derived from AggKind. Is it still required after all?
// TODO here, the expand means that agg will assume that the current value is kept constant during
// the rest of the time range.
if self.rng.is_none() {
} else {
let expand = true;
let range_next = self.next_bin_range();
self.rng = range_next.clone();
let mut bins = if let Some(range_next) = range_next {
self.agg.result_reset(range_next, expand)
} else {
// Acts as placeholder
let range_next = NanoRange {
beg: u64::MAX - 1,
end: u64::MAX,
};
self.agg.result_reset(range_next.into(), expand)
};
if bins.len() != 1 {
error!("{}::push_in_progress bins.len() {}", self.type_name(), bins.len());
return;
} else {
if push_empty || bins.counts[0] != 0 {
match self.ready.as_mut() {
Some(ready) => {
ready.append_all_from(&mut bins);
}
None => {
self.ready = Some(bins);
}
}
}
}
}
}
fn cycle(&mut self) {
trace!("{}::cycle", self.type_name());
// TODO refactor this logic.
let n = self.bins_ready_count();
self.push_in_progress(true);
if self.bins_ready_count() == n {
let range_next = self.next_bin_range();
self.rng = range_next.clone();
if let Some(range) = range_next {
/*
TODO Move out to trait.
let mut bins = BinsDim0::empty();
if range.is_time() {
bins.append_zero(range.beg_u64(), range.end_u64());
} else {
error!("TODO {self_name}::cycle is_pulse");
}
match self.ready.as_mut() {
Some(ready) => {
ready.append_all_from(&mut bins);
}
None => {
self.ready = Some(bins);
}
}
*/
if self.bins_ready_count() <= n {
error!("{}::cycle failed to push a zero bin", self.type_name());
}
} else {
warn!(
"{}::cycle no in-progress bin pushed, but also no more bin to add as zero-bin",
self.type_name()
);
}
}
}
fn set_range_complete(&mut self) {
self.range_final = true;
}
fn empty(&self) -> Box<dyn TimeBinned> {
/*
TODO factor out to trait.
let ret = <EventsDim0Aggregator<STY> as TimeBinnableTypeAggregator>::Output::empty();
*/
let ret = todo!();
Box::new(ret)
}
}

View File

@@ -0,0 +1,189 @@
use crate::collect_s::Collectable;
use crate::collect_s::Collected;
use crate::streamitem::RangeCompletableItem;
use crate::streamitem::Sitemty;
use crate::streamitem::StreamItem;
use crate::timebin::TimeBinnable;
use crate::Events;
use err::Error;
use futures_util::stream;
use futures_util::Future;
use futures_util::Stream;
use futures_util::StreamExt;
use std::pin::Pin;
use std::task::Context;
use std::task::Poll;
pub trait EventStreamTrait: Stream<Item = Sitemty<Box<dyn Events>>> + WithTransformProperties + Send {}
pub trait TimeBinnableStreamTrait:
Stream<Item = Sitemty<Box<dyn TimeBinnable>>> + WithTransformProperties + Send
{
}
pub trait CollectableStreamTrait:
Stream<Item = Sitemty<Box<dyn Collectable>>> + WithTransformProperties + Send
{
}
pub struct EventTransformProperties {
pub needs_value: bool,
}
pub struct TransformProperties {
pub needs_one_before_range: bool,
pub needs_value: bool,
}
pub trait WithTransformProperties {
fn query_transform_properties(&self) -> TransformProperties;
}
impl<T> WithTransformProperties for Box<T>
where
T: WithTransformProperties,
{
fn query_transform_properties(&self) -> TransformProperties {
self.as_ref().query_transform_properties()
}
}
impl<T> WithTransformProperties for Pin<Box<T>>
where
T: WithTransformProperties,
{
fn query_transform_properties(&self) -> TransformProperties {
self.as_ref().query_transform_properties()
}
}
pub trait EventTransform: WithTransformProperties + Send {
fn transform(&mut self, src: Box<dyn Events>) -> Box<dyn Events>;
}
impl<T> EventTransform for Box<T>
where
T: EventTransform,
{
fn transform(&mut self, src: Box<dyn Events>) -> Box<dyn Events> {
self.as_mut().transform(src)
}
}
impl<T> EventTransform for Pin<Box<T>>
where
T: EventTransform,
{
fn transform(&mut self, src: Box<dyn Events>) -> Box<dyn Events> {
todo!()
}
}
pub struct IdentityTransform {}
impl IdentityTransform {
pub fn default() -> Self {
Self {}
}
}
impl WithTransformProperties for IdentityTransform {
fn query_transform_properties(&self) -> TransformProperties {
todo!()
}
}
impl EventTransform for IdentityTransform {
fn transform(&mut self, src: Box<dyn Events>) -> Box<dyn Events> {
src
}
}
pub struct TransformEvent(pub Box<dyn EventTransform>);
impl WithTransformProperties for TransformEvent {
fn query_transform_properties(&self) -> TransformProperties {
self.0.query_transform_properties()
}
}
impl EventTransform for TransformEvent {
fn transform(&mut self, src: Box<dyn Events>) -> Box<dyn Events> {
self.0.transform(src)
}
}
impl<T> WithTransformProperties for stream::Iter<T> {
fn query_transform_properties(&self) -> TransformProperties {
todo!()
}
}
impl<T> EventStreamTrait for stream::Iter<T> where
T: core::iter::Iterator<Item = Sitemty<Box<(dyn Events + 'static)>>> + Send
{
}
pub struct EventStreamBox(pub Pin<Box<dyn EventStreamTrait>>);
impl<T> From<T> for EventStreamBox
where
T: Events,
{
fn from(value: T) -> Self {
let item = Ok(StreamItem::DataItem(RangeCompletableItem::Data(Box::new(value) as _)));
let x = stream::iter(vec![item]);
Self(Box::pin(x))
}
}
pub struct TimeBinnableStreamBox(pub Pin<Box<dyn TimeBinnableStreamTrait>>);
impl WithTransformProperties for TimeBinnableStreamBox {
fn query_transform_properties(&self) -> TransformProperties {
self.0.query_transform_properties()
}
}
impl Stream for TimeBinnableStreamBox {
type Item = <dyn TimeBinnableStreamTrait as Stream>::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
self.0.poll_next_unpin(cx)
}
}
impl TimeBinnableStreamTrait for TimeBinnableStreamBox {}
pub struct CollectableStreamBox(pub Pin<Box<dyn CollectableStreamTrait>>);
impl Stream for CollectableStreamBox {
type Item = Sitemty<Box<dyn Collectable>>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
self.0.poll_next_unpin(cx)
}
}
impl WithTransformProperties for CollectableStreamBox {
fn query_transform_properties(&self) -> TransformProperties {
todo!()
}
}
impl CollectableStreamTrait for CollectableStreamBox {}
impl<T> WithTransformProperties for stream::Empty<T> {
fn query_transform_properties(&self) -> TransformProperties {
todo!()
}
}
impl<T> CollectableStreamTrait for stream::Empty<T>
where
T: Send,
stream::Empty<T>: Stream<Item = Sitemty<Box<dyn Collectable>>>,
{
}
impl<T> CollectableStreamTrait for Pin<Box<T>> where T: CollectableStreamTrait {}