Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-compute/src/horizontal_flatten/struct_.rs
6939 views
1
use super::*;
2
3
/// # Safety
4
/// All preconditions in [`super::horizontal_flatten_unchecked`]
5
pub(super) unsafe fn horizontal_flatten_unchecked(
6
arrays: &[StructArray],
7
widths: &[usize],
8
output_height: usize,
9
) -> StructArray {
10
// For StructArrays, we perform the flatten operation individually for every field in the struct
11
// as well as on the outer validity. We then construct the result array from the individual
12
// result parts.
13
14
let dtype = arrays[0].dtype();
15
16
let field_arrays: Vec<&[Box<dyn Array>]> = arrays
17
.iter()
18
.inspect(|x| debug_assert_eq!(x.dtype(), dtype))
19
.map(|x| x.values())
20
.collect::<Vec<_>>();
21
22
let n_fields = field_arrays[0].len();
23
24
let mut scratch = Vec::with_capacity(field_arrays.len());
25
// Safety: We can take by index as all struct arrays have the same columns names in the same
26
// order.
27
// Note: `field_arrays` can be empty for 0-field structs.
28
let field_arrays = (0..n_fields)
29
.map(|i| {
30
scratch.clear();
31
scratch.extend(field_arrays.iter().map(|v| v[i].clone()));
32
33
super::horizontal_flatten_unchecked(&scratch, widths, output_height)
34
})
35
.collect::<Vec<_>>();
36
37
let validity = if arrays.iter().any(|x| x.validity().is_some()) {
38
let max_height = output_height * widths.iter().fold(0usize, |a, b| a.max(*b));
39
let mut shared_validity = None;
40
41
// We need to create BooleanArrays from the Bitmaps for dispatch.
42
let validities: Vec<BooleanArray> = arrays
43
.iter()
44
.map(|x| {
45
x.validity().cloned().unwrap_or_else(|| {
46
if shared_validity.is_none() {
47
shared_validity = Some(Bitmap::new_with_value(true, max_height))
48
};
49
// We have to slice to exact length to pass an assertion.
50
shared_validity.clone().unwrap().sliced(0, x.len())
51
})
52
})
53
.map(|x| BooleanArray::from_inner_unchecked(ArrowDataType::Boolean, x, None))
54
.collect::<Vec<_>>();
55
56
Some(
57
super::horizontal_flatten_unchecked_impl_generic::<BooleanArray>(
58
&validities,
59
widths,
60
output_height,
61
&ArrowDataType::Boolean,
62
)
63
.as_any()
64
.downcast_ref::<BooleanArray>()
65
.unwrap()
66
.values()
67
.clone(),
68
)
69
} else {
70
None
71
};
72
73
StructArray::new(
74
dtype.clone(),
75
if n_fields == 0 {
76
output_height * widths.iter().copied().sum::<usize>()
77
} else {
78
debug_assert_eq!(
79
field_arrays[0].len(),
80
output_height * widths.iter().copied().sum::<usize>()
81
);
82
83
field_arrays[0].len()
84
},
85
field_arrays,
86
validity,
87
)
88
}
89
90