use std::mem::size_of;
use arrow::array::ArrayRef;
use datafusion_common::Result;
use datafusion_expr::EmitTo;
mod full;
mod partial;
use crate::InputOrderMode;
pub use full::GroupOrderingFull;
pub use partial::GroupOrderingPartial;
#[derive(Debug)]
pub enum GroupOrdering {
None,
Partial(GroupOrderingPartial),
Full(GroupOrderingFull),
}
impl GroupOrdering {
pub fn try_new(mode: &InputOrderMode) -> Result<Self> {
match mode {
InputOrderMode::Linear => Ok(GroupOrdering::None),
InputOrderMode::PartiallySorted(order_indices) => {
GroupOrderingPartial::try_new(order_indices.clone())
.map(GroupOrdering::Partial)
}
InputOrderMode::Sorted => Ok(GroupOrdering::Full(GroupOrderingFull::new())),
}
}
pub fn emit_to(&self) -> Option<EmitTo> {
match self {
GroupOrdering::None => None,
GroupOrdering::Partial(partial) => partial.emit_to(),
GroupOrdering::Full(full) => full.emit_to(),
}
}
pub fn input_done(&mut self) {
match self {
GroupOrdering::None => {}
GroupOrdering::Partial(partial) => partial.input_done(),
GroupOrdering::Full(full) => full.input_done(),
}
}
pub fn remove_groups(&mut self, n: usize) {
match self {
GroupOrdering::None => {}
GroupOrdering::Partial(partial) => partial.remove_groups(n),
GroupOrdering::Full(full) => full.remove_groups(n),
}
}
pub fn new_groups(
&mut self,
batch_group_values: &[ArrayRef],
group_indices: &[usize],
total_num_groups: usize,
) -> Result<()> {
match self {
GroupOrdering::None => {}
GroupOrdering::Partial(partial) => {
partial.new_groups(
batch_group_values,
group_indices,
total_num_groups,
)?;
}
GroupOrdering::Full(full) => {
full.new_groups(total_num_groups);
}
};
Ok(())
}
pub fn size(&self) -> usize {
size_of::<Self>()
+ match self {
GroupOrdering::None => 0,
GroupOrdering::Partial(partial) => partial.size(),
GroupOrdering::Full(full) => full.size(),
}
}
}