use arrow::array::ArrayRef;
use datafusion_common::Result;
use datafusion_common::{DataFusionError, ScalarValue};
use std::ops::Range;
pub(crate) fn find_ranges_in_range<'a>(
partition_range: &Range<usize>,
sort_partition_points: &'a [Range<usize>],
) -> &'a [Range<usize>] {
let start_idx = sort_partition_points
.partition_point(|sort_range| sort_range.start < partition_range.start);
let end_idx = start_idx
+ sort_partition_points[start_idx..]
.partition_point(|sort_range| sort_range.end <= partition_range.end);
&sort_partition_points[start_idx..end_idx]
}
pub trait PartitionEvaluator {
fn include_rank(&self) -> bool {
false
}
fn uses_window_frame(&self) -> bool {
false
}
fn evaluate(
&self,
values: &[ArrayRef],
partition_points: Vec<Range<usize>>,
) -> Result<Vec<ArrayRef>> {
partition_points
.into_iter()
.map(|partition| self.evaluate_partition(values, partition))
.collect()
}
fn evaluate_with_rank(
&self,
partition_points: Vec<Range<usize>>,
sort_partition_points: Vec<Range<usize>>,
) -> Result<Vec<ArrayRef>> {
partition_points
.into_iter()
.map(|partition| {
let ranks_in_partition =
find_ranges_in_range(&partition, &sort_partition_points);
self.evaluate_partition_with_rank(partition, ranks_in_partition)
})
.collect()
}
fn evaluate_partition(
&self,
_values: &[ArrayRef],
_partition: Range<usize>,
) -> Result<ArrayRef> {
Err(DataFusionError::NotImplemented(
"evaluate_partition is not implemented by default".into(),
))
}
fn evaluate_partition_with_rank(
&self,
_partition: Range<usize>,
_ranks_in_partition: &[Range<usize>],
) -> Result<ArrayRef> {
Err(DataFusionError::NotImplemented(
"evaluate_partition_with_rank is not implemented by default".into(),
))
}
fn evaluate_inside_range(
&self,
_values: &[ArrayRef],
_range: Range<usize>,
) -> Result<ScalarValue> {
Err(DataFusionError::NotImplemented(
"evaluate_inside_range is not implemented by default".into(),
))
}
}