Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-expr/src/reduce/len.rs
6940 views
1
#![allow(unsafe_op_in_unsafe_fn)]
2
use polars_core::error::constants::LENGTH_LIMIT_MSG;
3
4
use super::*;
5
6
#[derive(Default)]
7
pub struct LenReduce {
8
groups: Vec<u64>,
9
evictions: Vec<u64>,
10
}
11
12
impl GroupedReduction for LenReduce {
13
fn new_empty(&self) -> Box<dyn GroupedReduction> {
14
Box::new(Self::default())
15
}
16
17
fn reserve(&mut self, additional: usize) {
18
self.groups.reserve(additional);
19
}
20
21
fn resize(&mut self, num_groups: IdxSize) {
22
self.groups.resize(num_groups as usize, 0);
23
}
24
25
fn update_group(
26
&mut self,
27
values: &Column,
28
group_idx: IdxSize,
29
_seq_id: u64,
30
) -> PolarsResult<()> {
31
self.groups[group_idx as usize] += values.len() as u64;
32
Ok(())
33
}
34
35
unsafe fn update_groups_while_evicting(
36
&mut self,
37
_values: &Column,
38
_subset: &[IdxSize],
39
group_idxs: &[EvictIdx],
40
_seq_id: u64,
41
) -> PolarsResult<()> {
42
unsafe {
43
// SAFETY: indices are in-bounds guaranteed by trait.
44
for g in group_idxs.iter() {
45
let grp = self.groups.get_unchecked_mut(g.idx());
46
if g.should_evict() {
47
self.evictions.push(*grp);
48
*grp = 0;
49
}
50
*grp += 1;
51
}
52
}
53
Ok(())
54
}
55
56
unsafe fn combine_subset(
57
&mut self,
58
other: &dyn GroupedReduction,
59
subset: &[IdxSize],
60
group_idxs: &[IdxSize],
61
) -> PolarsResult<()> {
62
let other = other.as_any().downcast_ref::<Self>().unwrap();
63
assert!(subset.len() == group_idxs.len());
64
unsafe {
65
// SAFETY: indices are in-bounds guaranteed by trait.
66
for (i, g) in subset.iter().zip(group_idxs) {
67
*self.groups.get_unchecked_mut(*g as usize) +=
68
*other.groups.get_unchecked(*i as usize);
69
}
70
}
71
Ok(())
72
}
73
74
fn take_evictions(&mut self) -> Box<dyn GroupedReduction> {
75
Box::new(Self {
76
groups: core::mem::take(&mut self.evictions),
77
evictions: Vec::new(),
78
})
79
}
80
81
fn finalize(&mut self) -> PolarsResult<Series> {
82
let ca: IdxCa = self
83
.groups
84
.drain(..)
85
.map(|l| IdxSize::try_from(l).expect(LENGTH_LIMIT_MSG))
86
.collect_ca(PlSmallStr::EMPTY);
87
Ok(ca.into_series())
88
}
89
90
fn as_any(&self) -> &dyn Any {
91
self
92
}
93
}
94
95