Path: blob/main/crates/polars-compute/src/rolling/min_max.rs
8449 views
use arrow::bitmap::Bitmap;1use arrow::types::NativeType;2use polars_utils::IdxSize;3use polars_utils::min_max::MinMaxPolicy;45use super::RollingFnParams;6use super::arg_min_max::ArgMinMaxWindow;7use super::no_nulls::RollingAggWindowNoNulls;8use super::nulls::RollingAggWindowNulls;910/// Min/max window implemented on top of ArgMinMaxWindow (arg-based).11pub struct MinMaxWindow<'a, T, P> {12inner: ArgMinMaxWindow<'a, T, P>,13}1415impl<'a, T: NativeType, P: MinMaxPolicy> RollingAggWindowNulls<T> for MinMaxWindow<'a, T, P> {16type This<'b> = MinMaxWindow<'b, T, P>;1718fn new<'b>(19slice: &'b [T],20validity: &'b Bitmap,21start: usize,22end: usize,23params: Option<RollingFnParams>,24window_size: Option<usize>,25) -> Self::This<'b> {26assert!(params.is_none());27assert!(start <= slice.len() && end <= slice.len() && start <= end);2829let inner = <ArgMinMaxWindow<'b, T, P> as RollingAggWindowNulls<T, IdxSize>>::new(30slice,31validity,32start,33end,34None,35window_size,36);3738MinMaxWindow { inner }39}4041unsafe fn update(&mut self, new_start: usize, new_end: usize) {42unsafe { RollingAggWindowNulls::<T, IdxSize>::update(&mut self.inner, new_start, new_end) };43}4445fn get_agg(&self, idx: usize) -> Option<T> {46let rel = RollingAggWindowNulls::<T, IdxSize>::get_agg(&self.inner, idx)?;47let abs = self.inner.start + rel as usize;48unsafe { Some(*self.inner.values.get_unchecked(abs)) }49}5051fn is_valid(&self, min_periods: usize) -> bool {52RollingAggWindowNulls::<T, IdxSize>::is_valid(&self.inner, min_periods)53}5455fn slice_len(&self) -> usize {56RollingAggWindowNulls::<T, IdxSize>::slice_len(&self.inner)57}58}5960impl<'a, T: NativeType, P: MinMaxPolicy> RollingAggWindowNoNulls<T> for MinMaxWindow<'a, T, P> {61type This<'b> = MinMaxWindow<'b, T, P>;6263fn new<'b>(64slice: &'b [T],65start: usize,66end: usize,67params: Option<RollingFnParams>,68window_size: Option<usize>,69) -> Self::This<'b> {70assert!(params.is_none());71assert!(start <= slice.len() && end <= slice.len() && start <= end);7273let inner = <ArgMinMaxWindow<'b, T, P> as RollingAggWindowNoNulls<T, IdxSize>>::new(74slice,75start,76end,77None,78window_size,79);8081MinMaxWindow { inner }82}8384unsafe fn update(&mut self, new_start: usize, new_end: usize) {85unsafe {86RollingAggWindowNoNulls::<T, IdxSize>::update(&mut self.inner, new_start, new_end);87};88}8990fn get_agg(&self, idx: usize) -> Option<T> {91let rel = RollingAggWindowNoNulls::<T, IdxSize>::get_agg(&self.inner, idx)?;92let abs = self.inner.start + rel as usize;93unsafe { Some(*self.inner.values.get_unchecked(abs)) }94}9596fn slice_len(&self) -> usize {97RollingAggWindowNoNulls::<T, IdxSize>::slice_len(&self.inner)98}99}100101102