use arrow::array::ArrayRef;
use datafusion_common::DataFusionError;
use datafusion_common::Result;
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 evaluate(&self, partition_points: Vec<Range<usize>>) -> Result<Vec<ArrayRef>> {
partition_points
.into_iter()
.map(|partition| self.evaluate_partition(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, _partition: Range<usize>) -> Result<ArrayRef>;
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(),
))
}
}