use vortex_error::VortexResult;
use vortex_error::vortex_err;
use crate::plan::physical::operator::Cx;
use crate::plan::physical::operator::Input;
use crate::plan::physical::operator::Operator;
use crate::plan::physical::operator::Source;
use crate::plan::physical::operator::SourceBlocked;
use crate::plan::physical::operator::SourceReady;
use crate::plan::physical::operator::Step;
pub(crate) struct ConcatSource {
inlets: usize,
current: usize,
}
impl ConcatSource {
pub(crate) fn new(inlets: usize) -> Self {
Self { inlets, current: 0 }
}
}
impl Source for ConcatSource {
fn ready(&mut self, cx: &mut Cx<'_>) -> VortexResult<SourceReady> {
while self.current < self.inlets {
let inlet = cx.inlet(self.current);
if !inlet.is_empty() {
return Ok(SourceReady::Ready);
}
if !inlet.closed() {
return Ok(SourceReady::Blocked(SourceBlocked::Inlet(self.current)));
}
self.current += 1;
}
Ok(SourceReady::Ready)
}
}
impl Operator for ConcatSource {
fn compute(&mut self, _input: Input, cx: &mut Cx<'_>) -> VortexResult<Step> {
Ok(if self.current == self.inlets {
Step::End
} else {
Step::Final(
cx.inlet(self.current)
.take()
.ok_or_else(|| vortex_err!("Concat computed before its inlet was ready"))?,
)
})
}
}