Refactor
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
use crate::framable::FrameType;
|
||||
use crate::merger;
|
||||
use crate::Events;
|
||||
use items::FrameType;
|
||||
use items::FrameTypeInnerStatic;
|
||||
use items_0::collect_s::Collectable;
|
||||
use items_0::collect_s::Collector;
|
||||
use items_0::framable::FrameTypeInnerStatic;
|
||||
use items_0::streamitem::ITEMS_2_CHANNEL_EVENTS_FRAME_TYPE_ID;
|
||||
use items_0::AsAnyMut;
|
||||
use items_0::AsAnyRef;
|
||||
use netpod::log::*;
|
||||
@@ -88,7 +89,7 @@ pub enum ChannelEvents {
|
||||
}
|
||||
|
||||
impl FrameTypeInnerStatic for ChannelEvents {
|
||||
const FRAME_TYPE_ID: u32 = items::ITEMS_2_CHANNEL_EVENTS_FRAME_TYPE_ID;
|
||||
const FRAME_TYPE_ID: u32 = ITEMS_2_CHANNEL_EVENTS_FRAME_TYPE_ID;
|
||||
}
|
||||
|
||||
impl FrameType for ChannelEvents {
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
use items::FrameType;
|
||||
use items::FrameTypeInnerStatic;
|
||||
use serde::Serialize;
|
||||
|
||||
pub struct DatabufferEventBlob {}
|
||||
|
||||
impl FrameTypeInnerStatic for DatabufferEventBlob {
|
||||
const FRAME_TYPE_ID: u32 = items::DATABUFFER_EVENT_BLOB_FRAME_TYPE_ID;
|
||||
}
|
||||
|
||||
impl FrameType for DatabufferEventBlob {
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeInnerStatic>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for DatabufferEventBlob {
|
||||
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
214
items_2/src/eventfull.rs
Normal file
214
items_2/src/eventfull.rs
Normal file
@@ -0,0 +1,214 @@
|
||||
use crate::framable::FrameType;
|
||||
use bytes::BytesMut;
|
||||
use items::ByteEstimate;
|
||||
use items::Clearable;
|
||||
use items::PushableIndex;
|
||||
use items::WithTimestamps;
|
||||
use items_0::framable::FrameTypeInnerStatic;
|
||||
use items_0::streamitem::EVENT_FULL_FRAME_TYPE_ID;
|
||||
use items_0::WithLen;
|
||||
use netpod::ScalarType;
|
||||
use netpod::Shape;
|
||||
use parse::channelconfig::CompressionMethod;
|
||||
use serde::Deserialize;
|
||||
use serde::Deserializer;
|
||||
use serde::Serialize;
|
||||
use serde::Serializer;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct EventFull {
|
||||
pub tss: VecDeque<u64>,
|
||||
pub pulses: VecDeque<u64>,
|
||||
pub blobs: VecDeque<Option<Vec<u8>>>,
|
||||
//#[serde(with = "decomps_serde")]
|
||||
// TODO allow access to `decomps` via method which checks first if `blobs` is already the decomp.
|
||||
pub decomps: VecDeque<Option<Vec<u8>>>,
|
||||
pub scalar_types: VecDeque<ScalarType>,
|
||||
pub be: VecDeque<bool>,
|
||||
pub shapes: VecDeque<Shape>,
|
||||
pub comps: VecDeque<Option<CompressionMethod>>,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
mod decomps_serde {
|
||||
use super::*;
|
||||
|
||||
pub fn serialize<S>(t: &VecDeque<Option<BytesMut>>, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let a: Vec<_> = t
|
||||
.iter()
|
||||
.map(|k| match k {
|
||||
None => None,
|
||||
Some(j) => Some(j[..].to_vec()),
|
||||
})
|
||||
.collect();
|
||||
Serialize::serialize(&a, s)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(d: D) -> Result<VecDeque<Option<BytesMut>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let a: Vec<Option<Vec<u8>>> = Deserialize::deserialize(d)?;
|
||||
let a = a
|
||||
.iter()
|
||||
.map(|k| match k {
|
||||
None => None,
|
||||
Some(j) => {
|
||||
let mut a = BytesMut::new();
|
||||
a.extend_from_slice(&j);
|
||||
Some(a)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl EventFull {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
tss: VecDeque::new(),
|
||||
pulses: VecDeque::new(),
|
||||
blobs: VecDeque::new(),
|
||||
decomps: VecDeque::new(),
|
||||
scalar_types: VecDeque::new(),
|
||||
be: VecDeque::new(),
|
||||
shapes: VecDeque::new(),
|
||||
comps: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_event(
|
||||
&mut self,
|
||||
ts: u64,
|
||||
pulse: u64,
|
||||
blob: Option<Vec<u8>>,
|
||||
decomp: Option<Vec<u8>>,
|
||||
scalar_type: ScalarType,
|
||||
be: bool,
|
||||
shape: Shape,
|
||||
comp: Option<CompressionMethod>,
|
||||
) {
|
||||
self.tss.push_back(ts);
|
||||
self.pulses.push_back(pulse);
|
||||
self.blobs.push_back(blob);
|
||||
self.decomps.push_back(decomp);
|
||||
self.scalar_types.push_back(scalar_type);
|
||||
self.be.push_back(be);
|
||||
self.shapes.push_back(shape);
|
||||
self.comps.push_back(comp);
|
||||
}
|
||||
|
||||
pub fn truncate_ts(&mut self, end: u64) {
|
||||
let mut nkeep = usize::MAX;
|
||||
for (i, &ts) in self.tss.iter().enumerate() {
|
||||
if ts >= end {
|
||||
nkeep = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.tss.truncate(nkeep);
|
||||
self.pulses.truncate(nkeep);
|
||||
self.blobs.truncate(nkeep);
|
||||
self.decomps.truncate(nkeep);
|
||||
self.scalar_types.truncate(nkeep);
|
||||
self.be.truncate(nkeep);
|
||||
self.shapes.truncate(nkeep);
|
||||
self.comps.truncate(nkeep);
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameTypeInnerStatic for EventFull {
|
||||
const FRAME_TYPE_ID: u32 = EVENT_FULL_FRAME_TYPE_ID;
|
||||
}
|
||||
|
||||
impl FrameType for EventFull {
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeInnerStatic>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl WithLen for EventFull {
|
||||
fn len(&self) -> usize {
|
||||
self.tss.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl items::WithLen for EventFull {
|
||||
fn len(&self) -> usize {
|
||||
self.tss.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl items::Appendable for EventFull {
|
||||
fn empty_like_self(&self) -> Self {
|
||||
Self::empty()
|
||||
}
|
||||
|
||||
// TODO expensive, get rid of it.
|
||||
fn append(&mut self, src: &Self) {
|
||||
self.tss.extend(&src.tss);
|
||||
self.pulses.extend(&src.pulses);
|
||||
self.blobs.extend(src.blobs.iter().map(Clone::clone));
|
||||
self.decomps.extend(src.decomps.iter().map(Clone::clone));
|
||||
self.scalar_types.extend(src.scalar_types.iter().map(Clone::clone));
|
||||
self.be.extend(&src.be);
|
||||
self.shapes.extend(src.shapes.iter().map(Clone::clone));
|
||||
self.comps.extend(src.comps.iter().map(Clone::clone));
|
||||
}
|
||||
|
||||
fn append_zero(&mut self, _ts1: u64, _ts2: u64) {
|
||||
// TODO do we still need this type?
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Clearable for EventFull {
|
||||
fn clear(&mut self) {
|
||||
self.tss.clear();
|
||||
self.pulses.clear();
|
||||
self.blobs.clear();
|
||||
self.decomps.clear();
|
||||
self.scalar_types.clear();
|
||||
self.be.clear();
|
||||
self.shapes.clear();
|
||||
self.comps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl WithTimestamps for EventFull {
|
||||
fn ts(&self, ix: usize) -> u64 {
|
||||
self.tss[ix]
|
||||
}
|
||||
}
|
||||
|
||||
impl ByteEstimate for EventFull {
|
||||
fn byte_estimate(&self) -> u64 {
|
||||
if self.len() == 0 {
|
||||
0
|
||||
} else {
|
||||
// TODO that is clumsy... it assumes homogenous types.
|
||||
// TODO improve via a const fn on NTY
|
||||
let decomp_len = self.decomps[0].as_ref().map_or(0, |h| h.len());
|
||||
self.tss.len() as u64 * (40 + self.blobs[0].as_ref().map_or(0, |x| x.len()) as u64 + decomp_len as u64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PushableIndex for EventFull {
|
||||
// TODO check all use cases, can't we move?
|
||||
fn push_index(&mut self, src: &Self, ix: usize) {
|
||||
self.tss.push_back(src.tss[ix]);
|
||||
self.pulses.push_back(src.pulses[ix]);
|
||||
self.blobs.push_back(src.blobs[ix].clone());
|
||||
self.decomps.push_back(src.decomps[ix].clone());
|
||||
self.scalar_types.push_back(src.scalar_types[ix].clone());
|
||||
self.be.push_back(src.be[ix]);
|
||||
self.shapes.push_back(src.shapes[ix].clone());
|
||||
self.comps.push_back(src.comps[ix].clone());
|
||||
}
|
||||
}
|
||||
@@ -1155,16 +1155,15 @@ impl<NTY: ScalarOps> items_0::collect_c::Collectable for EventsDim0<NTY> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_frame {
|
||||
use super::*;
|
||||
use crate::channelevents::ChannelEvents;
|
||||
use crate::eventsdim0::EventsDim0;
|
||||
use err::Error;
|
||||
use items::Framable;
|
||||
use items::RangeCompletableItem;
|
||||
use items::Sitemty;
|
||||
use items::StreamItem;
|
||||
use items_0::AsAnyMut;
|
||||
use items_0::Empty;
|
||||
use items_0::Events;
|
||||
use crate::framable::Framable;
|
||||
use crate::framable::INMEM_FRAME_ENCID;
|
||||
use crate::frame::decode_frame;
|
||||
use crate::inmem::InMemoryFrame;
|
||||
use items_0::streamitem::RangeCompletableItem;
|
||||
use items_0::streamitem::Sitemty;
|
||||
use items_0::streamitem::StreamItem;
|
||||
|
||||
#[test]
|
||||
fn events_bincode() {
|
||||
@@ -1180,13 +1179,13 @@ mod test_frame {
|
||||
let s = String::from_utf8_lossy(&buf[20..buf.len() - 4]);
|
||||
eprintln!("[[{s}]]");
|
||||
let buflen = buf.len();
|
||||
let frame = items::inmem::InMemoryFrame {
|
||||
encid: items::INMEM_FRAME_ENCID,
|
||||
let frame = InMemoryFrame {
|
||||
encid: INMEM_FRAME_ENCID,
|
||||
tyid: 0x2500,
|
||||
len: (buflen - 24) as _,
|
||||
buf: buf.split_off(20).split_to(buflen - 20 - 4).freeze(),
|
||||
};
|
||||
let item: Sitemty<ChannelEvents> = items::frame::decode_frame(&frame).unwrap();
|
||||
let item: Sitemty<ChannelEvents> = decode_frame(&frame).unwrap();
|
||||
let item = if let Ok(x) = item { x } else { panic!() };
|
||||
let item = if let StreamItem::DataItem(x) = item {
|
||||
x
|
||||
@@ -1208,31 +1207,34 @@ mod test_frame {
|
||||
} else {
|
||||
panic!()
|
||||
};
|
||||
eprintln!("NOW WE SEE: {:?}", item);
|
||||
// type_name_of_val alloc::boxed::Box<dyn items_0::Events>
|
||||
eprintln!("0 {:22?}", item.as_any_mut().type_id());
|
||||
eprintln!("A {:22?}", std::any::TypeId::of::<Box<dyn items_0::Events>>());
|
||||
eprintln!("B {:22?}", std::any::TypeId::of::<dyn items_0::Events>());
|
||||
eprintln!("C {:22?}", std::any::TypeId::of::<&dyn items_0::Events>());
|
||||
eprintln!("D {:22?}", std::any::TypeId::of::<&mut dyn items_0::Events>());
|
||||
eprintln!("E {:22?}", std::any::TypeId::of::<&mut Box<dyn items_0::Events>>());
|
||||
eprintln!("F {:22?}", std::any::TypeId::of::<Box<EventsDim0<f32>>>());
|
||||
eprintln!("G {:22?}", std::any::TypeId::of::<&EventsDim0<f32>>());
|
||||
eprintln!("H {:22?}", std::any::TypeId::of::<&mut EventsDim0<f32>>());
|
||||
eprintln!("I {:22?}", std::any::TypeId::of::<Box<Box<EventsDim0<f32>>>>());
|
||||
//let item = item.as_mut();
|
||||
//eprintln!("1 {:22?}", item.type_id());
|
||||
/*
|
||||
let item = if let Some(item) =
|
||||
items_0::collect_s::Collectable::as_any_mut(item).downcast_ref::<Box<EventsDim0<f32>>>()
|
||||
{
|
||||
item
|
||||
} else {
|
||||
panic!()
|
||||
};
|
||||
*/
|
||||
eprintln!("Final value: {item:?}");
|
||||
assert_eq!(item.tss(), &[123]);
|
||||
#[cfg(DISABLED)]
|
||||
{
|
||||
eprintln!("NOW WE SEE: {:?}", item);
|
||||
// type_name_of_val alloc::boxed::Box<dyn items_0::Events>
|
||||
eprintln!("0 {:22?}", item.as_any_mut().type_id());
|
||||
eprintln!("A {:22?}", std::any::TypeId::of::<Box<dyn items_0::Events>>());
|
||||
eprintln!("B {:22?}", std::any::TypeId::of::<dyn items_0::Events>());
|
||||
eprintln!("C {:22?}", std::any::TypeId::of::<&dyn items_0::Events>());
|
||||
eprintln!("D {:22?}", std::any::TypeId::of::<&mut dyn items_0::Events>());
|
||||
eprintln!("E {:22?}", std::any::TypeId::of::<&mut Box<dyn items_0::Events>>());
|
||||
eprintln!("F {:22?}", std::any::TypeId::of::<Box<EventsDim0<f32>>>());
|
||||
eprintln!("G {:22?}", std::any::TypeId::of::<&EventsDim0<f32>>());
|
||||
eprintln!("H {:22?}", std::any::TypeId::of::<&mut EventsDim0<f32>>());
|
||||
eprintln!("I {:22?}", std::any::TypeId::of::<Box<Box<EventsDim0<f32>>>>());
|
||||
//let item = item.as_mut();
|
||||
//eprintln!("1 {:22?}", item.type_id());
|
||||
/*
|
||||
let item = if let Some(item) =
|
||||
items_0::collect_s::Collectable::as_any_mut(item).downcast_ref::<Box<EventsDim0<f32>>>()
|
||||
{
|
||||
item
|
||||
} else {
|
||||
panic!()
|
||||
};
|
||||
*/
|
||||
//eprintln!("Final value: {item:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
150
items_2/src/framable.rs
Normal file
150
items_2/src/framable.rs
Normal file
@@ -0,0 +1,150 @@
|
||||
use crate::frame::make_error_frame;
|
||||
use crate::frame::make_frame_2;
|
||||
use crate::frame::make_log_frame;
|
||||
use crate::frame::make_range_complete_frame;
|
||||
use crate::frame::make_stats_frame;
|
||||
use bytes::BytesMut;
|
||||
use err::Error;
|
||||
use items_0::framable::FrameTypeInnerDyn;
|
||||
use items_0::framable::FrameTypeInnerStatic;
|
||||
use items_0::streamitem::LogItem;
|
||||
use items_0::streamitem::RangeCompletableItem;
|
||||
use items_0::streamitem::Sitemty;
|
||||
use items_0::streamitem::StatsItem;
|
||||
use items_0::streamitem::StreamItem;
|
||||
use items_0::streamitem::ERROR_FRAME_TYPE_ID;
|
||||
use items_0::streamitem::EVENT_QUERY_JSON_STRING_FRAME;
|
||||
use items_0::streamitem::SITEMTY_NONSPEC_FRAME_TYPE_ID;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
pub const INMEM_FRAME_ENCID: u32 = 0x12121212;
|
||||
pub const INMEM_FRAME_HEAD: usize = 20;
|
||||
pub const INMEM_FRAME_FOOT: usize = 4;
|
||||
pub const INMEM_FRAME_MAGIC: u32 = 0xc6c3b73d;
|
||||
|
||||
pub trait FrameTypeStatic {
|
||||
const FRAME_TYPE_ID: u32;
|
||||
}
|
||||
|
||||
impl<T> FrameTypeStatic for Sitemty<T>
|
||||
where
|
||||
T: FrameTypeInnerStatic,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = <T as FrameTypeInnerStatic>::FRAME_TYPE_ID;
|
||||
}
|
||||
|
||||
// Framable trait objects need some inspection to handle the supposed-to-be common Err ser format:
|
||||
// Meant to be implemented by Sitemty.
|
||||
pub trait FrameType {
|
||||
fn frame_type_id(&self) -> u32;
|
||||
}
|
||||
|
||||
impl<T> FrameType for Box<T>
|
||||
where
|
||||
T: FrameType,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
self.as_ref().frame_type_id()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Framable {
|
||||
fn make_frame(&self) -> Result<BytesMut, Error>;
|
||||
}
|
||||
|
||||
pub trait FramableInner: erased_serde::Serialize + FrameTypeInnerDyn + Send {
|
||||
fn _dummy(&self);
|
||||
}
|
||||
|
||||
impl<T: erased_serde::Serialize + FrameTypeInnerDyn + Send> FramableInner for T {
|
||||
fn _dummy(&self) {}
|
||||
}
|
||||
|
||||
impl<T> Framable for Sitemty<T>
|
||||
where
|
||||
T: Sized + serde::Serialize + FrameType,
|
||||
{
|
||||
fn make_frame(&self) -> Result<BytesMut, Error> {
|
||||
match self {
|
||||
Ok(StreamItem::DataItem(RangeCompletableItem::Data(k))) => {
|
||||
let frame_type_id = k.frame_type_id();
|
||||
make_frame_2(self, frame_type_id)
|
||||
}
|
||||
Ok(StreamItem::DataItem(RangeCompletableItem::RangeComplete)) => make_range_complete_frame(),
|
||||
Ok(StreamItem::Log(item)) => make_log_frame(item),
|
||||
Ok(StreamItem::Stats(item)) => make_stats_frame(item),
|
||||
Err(e) => make_error_frame(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Framable for Box<T>
|
||||
where
|
||||
T: Framable + ?Sized,
|
||||
{
|
||||
fn make_frame(&self) -> Result<BytesMut, Error> {
|
||||
self.as_ref().make_frame()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FrameDecodable: FrameTypeStatic + DeserializeOwned {
|
||||
fn from_error(e: ::err::Error) -> Self;
|
||||
fn from_log(item: LogItem) -> Self;
|
||||
fn from_stats(item: StatsItem) -> Self;
|
||||
fn from_range_complete() -> Self;
|
||||
}
|
||||
|
||||
impl<T> FrameDecodable for Sitemty<T>
|
||||
where
|
||||
T: FrameTypeInnerStatic + DeserializeOwned,
|
||||
{
|
||||
fn from_error(e: err::Error) -> Self {
|
||||
Err(e)
|
||||
}
|
||||
|
||||
fn from_log(item: LogItem) -> Self {
|
||||
Ok(StreamItem::Log(item))
|
||||
}
|
||||
|
||||
fn from_stats(item: StatsItem) -> Self {
|
||||
Ok(StreamItem::Stats(item))
|
||||
}
|
||||
|
||||
fn from_range_complete() -> Self {
|
||||
Ok(StreamItem::DataItem(RangeCompletableItem::RangeComplete))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct EventQueryJsonStringFrame(pub String);
|
||||
|
||||
impl FrameTypeInnerStatic for EventQueryJsonStringFrame {
|
||||
const FRAME_TYPE_ID: u32 = EVENT_QUERY_JSON_STRING_FRAME;
|
||||
}
|
||||
|
||||
impl FrameType for EventQueryJsonStringFrame {
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
EventQueryJsonStringFrame::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FrameType for Sitemty<T>
|
||||
where
|
||||
T: FrameType,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
match self {
|
||||
Ok(item) => match item {
|
||||
StreamItem::DataItem(item) => match item {
|
||||
RangeCompletableItem::RangeComplete => SITEMTY_NONSPEC_FRAME_TYPE_ID,
|
||||
RangeCompletableItem::Data(item) => item.frame_type_id(),
|
||||
},
|
||||
StreamItem::Log(_) => SITEMTY_NONSPEC_FRAME_TYPE_ID,
|
||||
StreamItem::Stats(_) => SITEMTY_NONSPEC_FRAME_TYPE_ID,
|
||||
},
|
||||
Err(_) => ERROR_FRAME_TYPE_ID,
|
||||
}
|
||||
}
|
||||
}
|
||||
372
items_2/src/frame.rs
Normal file
372
items_2/src/frame.rs
Normal file
@@ -0,0 +1,372 @@
|
||||
use crate::framable::FrameDecodable;
|
||||
use crate::framable::FrameType;
|
||||
use crate::framable::INMEM_FRAME_ENCID;
|
||||
use crate::framable::INMEM_FRAME_HEAD;
|
||||
use crate::framable::INMEM_FRAME_MAGIC;
|
||||
use crate::inmem::InMemoryFrame;
|
||||
use bincode::config::FixintEncoding;
|
||||
use bincode::config::LittleEndian;
|
||||
use bincode::config::RejectTrailing;
|
||||
use bincode::config::WithOtherEndian;
|
||||
use bincode::config::WithOtherIntEncoding;
|
||||
use bincode::config::WithOtherTrailing;
|
||||
use bincode::DefaultOptions;
|
||||
use bytes::BufMut;
|
||||
use bytes::BytesMut;
|
||||
use err::Error;
|
||||
use items_0::bincode;
|
||||
use items_0::streamitem::ContainsError;
|
||||
use items_0::streamitem::LogItem;
|
||||
use items_0::streamitem::StatsItem;
|
||||
use items_0::streamitem::ERROR_FRAME_TYPE_ID;
|
||||
use items_0::streamitem::LOG_FRAME_TYPE_ID;
|
||||
use items_0::streamitem::RANGE_COMPLETE_FRAME_TYPE_ID;
|
||||
use items_0::streamitem::STATS_FRAME_TYPE_ID;
|
||||
use items_0::streamitem::TERM_FRAME_TYPE_ID;
|
||||
#[allow(unused)]
|
||||
use netpod::log::*;
|
||||
use serde::Serialize;
|
||||
|
||||
trait EC {
|
||||
fn ec(self) -> err::Error;
|
||||
}
|
||||
|
||||
impl EC for rmp_serde::encode::Error {
|
||||
fn ec(self) -> err::Error {
|
||||
err::Error::with_msg_no_trace(format!("{self:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl EC for rmp_serde::decode::Error {
|
||||
fn ec(self) -> err::Error {
|
||||
err::Error::with_msg_no_trace(format!("{self:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_frame<FT>(item: &FT) -> Result<BytesMut, Error>
|
||||
where
|
||||
FT: FrameType + ContainsError + Serialize,
|
||||
{
|
||||
if item.is_err() {
|
||||
make_error_frame(item.err().unwrap())
|
||||
} else {
|
||||
make_frame_2(item, item.frame_type_id())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bincode_ser<W>(
|
||||
w: W,
|
||||
) -> bincode::Serializer<
|
||||
W,
|
||||
WithOtherTrailing<
|
||||
WithOtherIntEncoding<WithOtherEndian<DefaultOptions, LittleEndian>, FixintEncoding>,
|
||||
RejectTrailing,
|
||||
>,
|
||||
>
|
||||
where
|
||||
W: std::io::Write,
|
||||
{
|
||||
use bincode::Options;
|
||||
let opts = DefaultOptions::new()
|
||||
.with_little_endian()
|
||||
.with_fixint_encoding()
|
||||
.reject_trailing_bytes();
|
||||
let ser = bincode::Serializer::new(w, opts);
|
||||
ser
|
||||
}
|
||||
|
||||
pub fn bincode_to_vec<S>(item: S) -> Result<Vec<u8>, Error>
|
||||
where
|
||||
S: Serialize,
|
||||
{
|
||||
let mut out = Vec::new();
|
||||
let mut ser = bincode_ser(&mut out);
|
||||
item.serialize(&mut ser).map_err(|e| format!("{e}"))?;
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
pub fn bincode_from_slice<T>(buf: &[u8]) -> Result<T, Error>
|
||||
where
|
||||
T: for<'de> serde::Deserialize<'de>,
|
||||
{
|
||||
use bincode::Options;
|
||||
let opts = DefaultOptions::new()
|
||||
.with_little_endian()
|
||||
.with_fixint_encoding()
|
||||
.reject_trailing_bytes();
|
||||
let mut de = bincode::Deserializer::from_slice(buf, opts);
|
||||
<T as serde::Deserialize>::deserialize(&mut de).map_err(|e| format!("{e}").into())
|
||||
}
|
||||
|
||||
pub fn encode_to_vec<S>(item: S) -> Result<Vec<u8>, Error>
|
||||
where
|
||||
S: Serialize,
|
||||
{
|
||||
if false {
|
||||
serde_json::to_vec(&item).map_err(|e| e.into())
|
||||
} else {
|
||||
bincode_to_vec(&item)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_from_slice<T>(buf: &[u8]) -> Result<T, Error>
|
||||
where
|
||||
T: for<'de> serde::Deserialize<'de>,
|
||||
{
|
||||
if false {
|
||||
serde_json::from_slice(buf).map_err(|e| e.into())
|
||||
} else {
|
||||
bincode_from_slice(buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_frame_2<T>(item: &T, fty: u32) -> Result<BytesMut, Error>
|
||||
where
|
||||
T: erased_serde::Serialize,
|
||||
{
|
||||
let mut out = Vec::new();
|
||||
//let mut ser = rmp_serde::Serializer::new(&mut out).with_struct_map();
|
||||
//let writer = ciborium::ser::into_writer(&item, &mut out).unwrap();
|
||||
let mut ser = bincode_ser(&mut out);
|
||||
let mut ser2 = <dyn erased_serde::Serializer>::erase(&mut ser);
|
||||
//let mut ser = serde_json::Serializer::new(&mut out);
|
||||
//let mut ser2 = <dyn erased_serde::Serializer>::erase(&mut ser);
|
||||
match item.erased_serialize(&mut ser2) {
|
||||
Ok(_) => {
|
||||
let enc = out;
|
||||
if enc.len() > u32::MAX as usize {
|
||||
return Err(Error::with_msg(format!("too long payload {}", enc.len())));
|
||||
}
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&enc);
|
||||
let payload_crc = h.finalize();
|
||||
// TODO reserve also for footer via constant
|
||||
let mut buf = BytesMut::with_capacity(enc.len() + INMEM_FRAME_HEAD);
|
||||
buf.put_u32_le(INMEM_FRAME_MAGIC);
|
||||
buf.put_u32_le(INMEM_FRAME_ENCID);
|
||||
buf.put_u32_le(fty);
|
||||
buf.put_u32_le(enc.len() as u32);
|
||||
buf.put_u32_le(payload_crc);
|
||||
// TODO add padding to align to 8 bytes.
|
||||
//trace!("enc len {}", enc.len());
|
||||
//trace!("payload_crc {}", payload_crc);
|
||||
buf.put(enc.as_ref());
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&buf);
|
||||
let frame_crc = h.finalize();
|
||||
buf.put_u32_le(frame_crc);
|
||||
//trace!("frame_crc {}", frame_crc);
|
||||
Ok(buf)
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO remove duplication for these similar `make_*_frame` functions:
|
||||
|
||||
pub fn make_error_frame(error: &::err::Error) -> Result<BytesMut, Error> {
|
||||
match encode_to_vec(error) {
|
||||
Ok(enc) => {
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&enc);
|
||||
let payload_crc = h.finalize();
|
||||
let mut buf = BytesMut::with_capacity(INMEM_FRAME_HEAD);
|
||||
buf.put_u32_le(INMEM_FRAME_MAGIC);
|
||||
buf.put_u32_le(INMEM_FRAME_ENCID);
|
||||
buf.put_u32_le(ERROR_FRAME_TYPE_ID);
|
||||
buf.put_u32_le(enc.len() as u32);
|
||||
buf.put_u32_le(payload_crc);
|
||||
// TODO add padding to align to 8 bytes.
|
||||
//trace!("enc len {}", enc.len());
|
||||
//trace!("payload_crc {}", payload_crc);
|
||||
buf.put(enc.as_ref());
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&buf);
|
||||
let frame_crc = h.finalize();
|
||||
buf.put_u32_le(frame_crc);
|
||||
//trace!("frame_crc {}", frame_crc);
|
||||
Ok(buf)
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO can I remove this usage?
|
||||
pub fn make_log_frame(item: &LogItem) -> Result<BytesMut, Error> {
|
||||
warn!("make_log_frame {item:?}");
|
||||
match encode_to_vec(item) {
|
||||
Ok(enc) => {
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&enc);
|
||||
let payload_crc = h.finalize();
|
||||
let mut buf = BytesMut::with_capacity(INMEM_FRAME_HEAD);
|
||||
buf.put_u32_le(INMEM_FRAME_MAGIC);
|
||||
buf.put_u32_le(INMEM_FRAME_ENCID);
|
||||
buf.put_u32_le(LOG_FRAME_TYPE_ID);
|
||||
warn!("make_log_frame payload len {}", enc.len());
|
||||
buf.put_u32_le(enc.len() as u32);
|
||||
buf.put_u32_le(payload_crc);
|
||||
// TODO add padding to align to 8 bytes.
|
||||
buf.put(enc.as_ref());
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&buf);
|
||||
let frame_crc = h.finalize();
|
||||
buf.put_u32_le(frame_crc);
|
||||
Ok(buf)
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_stats_frame(item: &StatsItem) -> Result<BytesMut, Error> {
|
||||
match encode_to_vec(item) {
|
||||
Ok(enc) => {
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&enc);
|
||||
let payload_crc = h.finalize();
|
||||
let mut buf = BytesMut::with_capacity(INMEM_FRAME_HEAD);
|
||||
buf.put_u32_le(INMEM_FRAME_MAGIC);
|
||||
buf.put_u32_le(INMEM_FRAME_ENCID);
|
||||
buf.put_u32_le(STATS_FRAME_TYPE_ID);
|
||||
buf.put_u32_le(enc.len() as u32);
|
||||
buf.put_u32_le(payload_crc);
|
||||
// TODO add padding to align to 8 bytes.
|
||||
buf.put(enc.as_ref());
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&buf);
|
||||
let frame_crc = h.finalize();
|
||||
buf.put_u32_le(frame_crc);
|
||||
Ok(buf)
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_range_complete_frame() -> Result<BytesMut, Error> {
|
||||
let enc = [];
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&enc);
|
||||
let payload_crc = h.finalize();
|
||||
let mut buf = BytesMut::with_capacity(INMEM_FRAME_HEAD);
|
||||
buf.put_u32_le(INMEM_FRAME_MAGIC);
|
||||
buf.put_u32_le(INMEM_FRAME_ENCID);
|
||||
buf.put_u32_le(RANGE_COMPLETE_FRAME_TYPE_ID);
|
||||
buf.put_u32_le(enc.len() as u32);
|
||||
buf.put_u32_le(payload_crc);
|
||||
// TODO add padding to align to 8 bytes.
|
||||
buf.put(enc.as_ref());
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&buf);
|
||||
let frame_crc = h.finalize();
|
||||
buf.put_u32_le(frame_crc);
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
pub fn make_term_frame() -> Result<BytesMut, Error> {
|
||||
let enc = [];
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&enc);
|
||||
let payload_crc = h.finalize();
|
||||
let mut buf = BytesMut::with_capacity(INMEM_FRAME_HEAD);
|
||||
buf.put_u32_le(INMEM_FRAME_MAGIC);
|
||||
buf.put_u32_le(INMEM_FRAME_ENCID);
|
||||
buf.put_u32_le(TERM_FRAME_TYPE_ID);
|
||||
buf.put_u32_le(enc.len() as u32);
|
||||
buf.put_u32_le(payload_crc);
|
||||
// TODO add padding to align to 8 bytes.
|
||||
buf.put(enc.as_ref());
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(&buf);
|
||||
let frame_crc = h.finalize();
|
||||
buf.put_u32_le(frame_crc);
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
pub fn decode_frame<T>(frame: &InMemoryFrame) -> Result<T, Error>
|
||||
where
|
||||
T: FrameDecodable,
|
||||
{
|
||||
if frame.encid() != INMEM_FRAME_ENCID {
|
||||
return Err(Error::with_msg(format!("unknown encoder id {:?}", frame)));
|
||||
}
|
||||
if frame.len() as usize != frame.buf().len() {
|
||||
return Err(Error::with_msg(format!(
|
||||
"buf mismatch {} vs {} in {:?}",
|
||||
frame.len(),
|
||||
frame.buf().len(),
|
||||
frame
|
||||
)));
|
||||
}
|
||||
if frame.tyid() == ERROR_FRAME_TYPE_ID {
|
||||
let k: ::err::Error = match decode_from_slice(frame.buf()) {
|
||||
Ok(item) => item,
|
||||
Err(e) => {
|
||||
error!("ERROR deserialize len {} ERROR_FRAME_TYPE_ID", frame.buf().len());
|
||||
let n = frame.buf().len().min(128);
|
||||
let s = String::from_utf8_lossy(&frame.buf()[..n]);
|
||||
error!("frame.buf as string: {:?}", s);
|
||||
Err(e)?
|
||||
}
|
||||
};
|
||||
Ok(T::from_error(k))
|
||||
} else if frame.tyid() == LOG_FRAME_TYPE_ID {
|
||||
let k: LogItem = match decode_from_slice(frame.buf()) {
|
||||
Ok(item) => item,
|
||||
Err(e) => {
|
||||
error!("ERROR deserialize len {} LOG_FRAME_TYPE_ID", frame.buf().len());
|
||||
let n = frame.buf().len().min(128);
|
||||
let s = String::from_utf8_lossy(&frame.buf()[..n]);
|
||||
error!("frame.buf as string: {:?}", s);
|
||||
Err(e)?
|
||||
}
|
||||
};
|
||||
Ok(T::from_log(k))
|
||||
} else if frame.tyid() == STATS_FRAME_TYPE_ID {
|
||||
let k: StatsItem = match decode_from_slice(frame.buf()) {
|
||||
Ok(item) => item,
|
||||
Err(e) => {
|
||||
error!("ERROR deserialize len {} STATS_FRAME_TYPE_ID", frame.buf().len());
|
||||
let n = frame.buf().len().min(128);
|
||||
let s = String::from_utf8_lossy(&frame.buf()[..n]);
|
||||
error!("frame.buf as string: {:?}", s);
|
||||
Err(e)?
|
||||
}
|
||||
};
|
||||
Ok(T::from_stats(k))
|
||||
} else if frame.tyid() == RANGE_COMPLETE_FRAME_TYPE_ID {
|
||||
// There is currently no content in this variant.
|
||||
Ok(T::from_range_complete())
|
||||
} else {
|
||||
let tyid = T::FRAME_TYPE_ID;
|
||||
if frame.tyid() != tyid {
|
||||
Err(Error::with_msg(format!(
|
||||
"type id mismatch expect {:x} found {:x} {:?}",
|
||||
tyid,
|
||||
frame.tyid(),
|
||||
frame
|
||||
)))
|
||||
} else {
|
||||
match decode_from_slice(frame.buf()) {
|
||||
Ok(item) => Ok(item),
|
||||
Err(e) => {
|
||||
error!("decode_frame T = {}", std::any::type_name::<T>());
|
||||
error!("ERROR deserialize len {} tyid {:x}", frame.buf().len(), frame.tyid());
|
||||
let n = frame.buf().len().min(64);
|
||||
let s = String::from_utf8_lossy(&frame.buf()[..n]);
|
||||
error!("frame.buf as string: {:?}", s);
|
||||
Err(e)?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn crchex<T>(t: T) -> String
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
let mut h = crc32fast::Hasher::new();
|
||||
h.update(t.as_ref());
|
||||
let crc = h.finalize();
|
||||
format!("{:08x}", crc)
|
||||
}
|
||||
34
items_2/src/inmem.rs
Normal file
34
items_2/src/inmem.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use bytes::Bytes;
|
||||
use std::fmt;
|
||||
|
||||
pub struct InMemoryFrame {
|
||||
pub encid: u32,
|
||||
pub tyid: u32,
|
||||
pub len: u32,
|
||||
pub buf: Bytes,
|
||||
}
|
||||
|
||||
impl InMemoryFrame {
|
||||
pub fn encid(&self) -> u32 {
|
||||
self.encid
|
||||
}
|
||||
pub fn tyid(&self) -> u32 {
|
||||
self.tyid
|
||||
}
|
||||
pub fn len(&self) -> u32 {
|
||||
self.len
|
||||
}
|
||||
pub fn buf(&self) -> &Bytes {
|
||||
&self.buf
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for InMemoryFrame {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(
|
||||
fmt,
|
||||
"InMemoryFrame {{ encid: {:x} tyid: {:x} len {} }}",
|
||||
self.encid, self.tyid, self.len
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
pub mod binsdim0;
|
||||
pub mod binsxbindim0;
|
||||
pub mod channelevents;
|
||||
pub mod databuffereventblobs;
|
||||
pub mod eventfull;
|
||||
pub mod eventsdim0;
|
||||
pub mod eventsdim1;
|
||||
pub mod eventsxbindim0;
|
||||
pub mod eventtransform;
|
||||
pub mod framable;
|
||||
pub mod frame;
|
||||
pub mod inmem;
|
||||
pub mod merger;
|
||||
pub mod streams;
|
||||
#[cfg(test)]
|
||||
@@ -20,11 +23,11 @@ use chrono::Utc;
|
||||
use futures_util::FutureExt;
|
||||
use futures_util::Stream;
|
||||
use futures_util::StreamExt;
|
||||
use items::RangeCompletableItem;
|
||||
use items::Sitemty;
|
||||
use items::StreamItem;
|
||||
use items_0::collect_s::Collector;
|
||||
use items_0::collect_s::ToJsonResult;
|
||||
use items_0::streamitem::RangeCompletableItem;
|
||||
use items_0::streamitem::Sitemty;
|
||||
use items_0::streamitem::StreamItem;
|
||||
use items_0::Empty;
|
||||
use items_0::Events;
|
||||
use items_0::RangeOverlapInfo;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::Error;
|
||||
use futures_util::Stream;
|
||||
use futures_util::StreamExt;
|
||||
use items::sitem_data;
|
||||
use items::RangeCompletableItem;
|
||||
use items::Sitemty;
|
||||
use items::StreamItem;
|
||||
use items_0::streamitem::sitem_data;
|
||||
use items_0::streamitem::RangeCompletableItem;
|
||||
use items_0::streamitem::Sitemty;
|
||||
use items_0::streamitem::StreamItem;
|
||||
use netpod::log::*;
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt;
|
||||
@@ -359,7 +359,7 @@ where
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
use Poll::*;
|
||||
self.poll_count += 1;
|
||||
let span1 = span!(Level::TRACE, "Merger", pc = self.poll_count);
|
||||
let span1 = span!(Level::INFO, "Merger", pc = self.poll_count);
|
||||
let _spg = span1.enter();
|
||||
loop {
|
||||
trace3!("poll");
|
||||
|
||||
@@ -15,10 +15,10 @@ use chrono::TimeZone;
|
||||
use chrono::Utc;
|
||||
use futures_util::stream;
|
||||
use futures_util::StreamExt;
|
||||
use items::sitem_data;
|
||||
use items::RangeCompletableItem;
|
||||
use items::Sitemty;
|
||||
use items::StreamItem;
|
||||
use items_0::streamitem::sitem_data;
|
||||
use items_0::streamitem::RangeCompletableItem;
|
||||
use items_0::streamitem::Sitemty;
|
||||
use items_0::streamitem::StreamItem;
|
||||
use items_0::Empty;
|
||||
use netpod::log::*;
|
||||
use netpod::timeunits::*;
|
||||
|
||||
Reference in New Issue
Block a user