use datafusion_expr::EmitTo;
use std::mem::size_of;
#[derive(Debug)]
pub struct GroupOrderingFull {
state: State,
}
#[derive(Debug)]
enum State {
Start,
InProgress { current: usize },
Complete,
}
impl GroupOrderingFull {
pub fn new() -> Self {
Self {
state: State::Start,
}
}
pub fn emit_to(&self) -> Option<EmitTo> {
match &self.state {
State::Start => None,
State::InProgress { current, .. } => {
if *current == 0 {
None
} else {
Some(EmitTo::First(*current))
}
}
State::Complete => Some(EmitTo::All),
}
}
pub fn remove_groups(&mut self, n: usize) {
match &mut self.state {
State::Start => panic!("invalid state: start"),
State::InProgress { current } => {
assert!(*current >= n);
*current -= n;
}
State::Complete => panic!("invalid state: complete"),
}
}
pub fn input_done(&mut self) {
self.state = State::Complete;
}
pub fn new_groups(&mut self, total_num_groups: usize) {
assert_ne!(total_num_groups, 0);
let max_group_index = total_num_groups - 1;
self.state = match self.state {
State::Start => State::InProgress {
current: max_group_index,
},
State::InProgress { current } => {
assert!(current <= max_group_index, "{current} <= {max_group_index}");
State::InProgress {
current: max_group_index,
}
}
State::Complete => {
panic!("Saw new group after input was complete");
}
};
}
pub(crate) fn size(&self) -> usize {
size_of::<Self>()
}
}
impl Default for GroupOrderingFull {
fn default() -> Self {
Self::new()
}
}