use std::any::TypeId;
use std::marker::PhantomData;
use crate::env::stream_env::StreamEnv;
use crate::runtime::chain_job::{ChainOperatorKind, ChainStep};
use crate::runtime::chain_segment::ChainSegmentFactory;
use tinyflow_api::functions::*;
pub struct DataStream<T> {
pub(crate) env: StreamEnv,
pub(crate) tail_step_index: usize,
pub(crate) _marker: PhantomData<T>,
}
impl<T: 'static> DataStream<T> {
pub(crate) fn new(env: StreamEnv, tail_step_index: usize) -> Self {
Self {
env,
tail_step_index,
_marker: PhantomData,
}
}
pub fn name(self, n: impl Into<String>) -> Self {
let name = n.into();
let tail = self.tail_step_index;
{
let mut job = self.env.chain_job.lock().unwrap();
if let Some(job) = job.as_mut()
&& tail < job.steps.len()
{
job.steps[tail].user_name = Some(name);
}
}
self
}
fn push_step<OUT: Send + 'static>(
self,
kind: ChainOperatorKind,
factory: ChainSegmentFactory,
) -> DataStream<OUT> {
let mut job_guard = self.env.chain_job.lock().unwrap();
let job = job_guard
.as_mut()
.expect("ChainJob missing; call add_source first");
job.push_step_with_types(
ChainStep {
kind,
user_name: None,
factory,
},
Some(TypeId::of::<T>()),
TypeId::of::<OUT>(),
);
let idx = job.steps.len() - 1;
DataStream::new(self.env.clone(), idx)
}
}
impl<T: Send + Clone + 'static> DataStream<T> {
pub fn map<O: Send + Clone + 'static, F: MapFunction<T, O> + Clone + Send + 'static>(
self,
f: F,
) -> DataStream<O> {
let factory = crate::runtime::chain_segment::map_chain_factory(f);
self.push_step(ChainOperatorKind::Map, factory)
}
pub fn filter<F: FilterFunction<T> + Clone + Send + 'static>(self, f: F) -> DataStream<T> {
let factory = crate::runtime::chain_segment::filter_chain_factory(f);
self.push_step(ChainOperatorKind::Filter, factory)
}
pub fn flat_map<
O: Send + Clone + 'static,
F: FlatMapFunction<T, O> + Clone + Send + 'static,
>(
self,
f: F,
) -> DataStream<O> {
let factory = crate::runtime::chain_segment::flat_map_chain_factory(f);
self.push_step(ChainOperatorKind::FlatMap, factory)
}
pub fn sink<F>(self, f: F)
where
F: SinkFunction<T> + Clone + Send + 'static,
{
self.sink_named_impl(None, f);
}
pub fn sink_named<F>(self, name: impl Into<String>, f: F)
where
F: SinkFunction<T> + Clone + Send + 'static,
{
self.sink_named_impl(Some(name.into()), f);
}
fn sink_named_impl<F>(self, user_name: Option<String>, f: F)
where
F: SinkFunction<T> + Clone + Send + 'static,
{
let factory = crate::runtime::chain_segment::sink_chain_factory(f);
let mut job_guard = self.env.chain_job.lock().unwrap();
let job = job_guard
.as_mut()
.expect("ChainJob missing; call add_source first");
job.push_step_with_types(
ChainStep {
kind: ChainOperatorKind::Sink,
user_name,
factory,
},
Some(TypeId::of::<T>()),
TypeId::of::<T>(),
);
drop(job_guard);
}
}