use std::collections::VecDeque;
use smallvec::SmallVec;
use vortex_array::ArrayRef;
use vortex_array::ExecutionCtx;
use vortex_array::buffer::BufferHandle;
use vortex_error::VortexResult;
use vortex_session::VortexSession;
use super::pipeline::Arena;
use super::pipeline::Inlet;
use super::pipeline::PortId;
use crate::segments::SegmentId;
#[derive(Debug)]
pub enum Step {
End,
More(ArrayRef),
Final(ArrayRef),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SourceReady {
Ready,
Blocked(SourceBlocked),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SourceBlocked {
Io,
Inlet(usize),
}
pub trait Source: Operator {
fn ready(&mut self, _cx: &mut Cx<'_>) -> VortexResult<SourceReady> {
Ok(SourceReady::Ready)
}
}
#[derive(Debug)]
pub enum Input {
None,
Batch(ArrayRef),
End,
}
pub trait Operator: Send {
fn compute(&mut self, input: Input, cx: &mut Cx<'_>) -> VortexResult<Step>;
}
#[derive(Default)]
pub(super) struct InletSet {
indices: Vec<usize>,
positions: Vec<usize>,
}
impl InletSet {
pub(super) fn new(inlets: usize) -> Self {
Self {
indices: Vec::with_capacity(inlets),
positions: vec![usize::MAX; inlets],
}
}
pub(super) fn all(inlets: usize) -> Self {
Self {
indices: (0..inlets).collect(),
positions: (0..inlets).collect(),
}
}
pub(super) fn insert(&mut self, index: usize) {
if self.positions[index] == usize::MAX {
self.positions[index] = self.indices.len();
self.indices.push(index);
}
}
pub(super) fn remove(&mut self, index: usize) {
let position = self.positions[index];
if position == usize::MAX {
return;
}
self.indices.swap_remove(position);
if let Some(&moved) = self.indices.get(position) {
self.positions[moved] = position;
}
self.positions[index] = usize::MAX;
}
fn pop(&mut self) -> Option<usize> {
let index = *self.indices.last()?;
self.remove(index);
Some(index)
}
pub(super) fn indices(&self) -> &[usize] {
&self.indices
}
pub(super) fn clear(&mut self) {
for &index in &self.indices {
self.positions[index] = usize::MAX;
}
self.indices.clear();
}
}
pub struct Cx<'a> {
pub(super) arena: &'a mut Arena,
pub(super) inlets: &'a [PortId],
pub(super) bytes: &'a mut VecDeque<(SegmentId, BufferHandle)>,
pub(super) reads: &'a mut SmallVec<[SegmentId; 1]>,
pub(super) session: &'a VortexSession,
pub(super) exec: &'a mut ExecutionCtx,
pub(super) touched: &'a mut InletSet,
pub(super) changed: &'a mut InletSet,
}
impl Cx<'_> {
pub fn changed_inlet(&mut self) -> Option<usize> {
self.changed.pop()
}
pub fn request_read(&mut self, segment: SegmentId) {
self.reads.push(segment);
}
pub fn has_bytes(&self) -> bool {
!self.bytes.is_empty()
}
pub fn inlet(&mut self, index: usize) -> Inlet<'_> {
self.touched.insert(index);
self.arena.inlet(self.inlets[index])
}
pub fn take_segment(&mut self) -> Option<(SegmentId, BufferHandle)> {
self.bytes.pop_front()
}
pub fn session(&self) -> &VortexSession {
self.session
}
pub fn exec(&mut self) -> &mut ExecutionCtx {
self.exec
}
}