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
8420 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
let &[values] = values else { unreachable!() };
32
self.groups[group_idx as usize] += values.len() as u64;
33
Ok(())
34
}
35
36
unsafe fn update_groups_while_evicting(
37
&mut self,
38
_values: &[&Column],
39
subset: &[IdxSize],
40
group_idxs: &[EvictIdx],
41
_seq_id: u64,
42
) -> PolarsResult<()> {
43
assert!(subset.len() == group_idxs.len());
44
unsafe {
45
// SAFETY: indices are in-bounds guaranteed by trait.
46
for g in group_idxs.iter() {
47
let grp = self.groups.get_unchecked_mut(g.idx());
48
if g.should_evict() {
49
self.evictions.push(*grp);
50
*grp = 0;
51
}
52
*grp += 1;
53
}
54
}
55
Ok(())
56
}
57
58
unsafe fn combine_subset(
59
&mut self,
60
other: &dyn GroupedReduction,
61
subset: &[IdxSize],
62
group_idxs: &[IdxSize],
63
) -> PolarsResult<()> {
64
let other = other.as_any().downcast_ref::<Self>().unwrap();
65
assert!(subset.len() == group_idxs.len());
66
unsafe {
67
// SAFETY: indices are in-bounds guaranteed by trait.
68
for (i, g) in subset.iter().zip(group_idxs) {
69
*self.groups.get_unchecked_mut(*g as usize) +=
70
*other.groups.get_unchecked(*i as usize);
71
}
72
}
73
Ok(())
74
}
75
76
fn take_evictions(&mut self) -> Box<dyn GroupedReduction> {
77
Box::new(Self {
78
groups: core::mem::take(&mut self.evictions),
79
evictions: Vec::new(),
80
})
81
}
82
83
fn finalize(&mut self) -> PolarsResult<Series> {
84
let ca: IdxCa = self
85
.groups
86
.drain(..)
87
.map(|l| IdxSize::try_from(l).expect(LENGTH_LIMIT_MSG))
88
.collect_ca(PlSmallStr::EMPTY);
89
Ok(ca.into_series())
90
}
91
92
fn as_any(&self) -> &dyn Any {
93
self
94
}
95
}
96
97