Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-arrow/src/compute/utils.rs
6939 views
1
use std::borrow::Borrow;
2
use std::ops::{BitAnd, BitOr};
3
4
use polars_error::{PolarsResult, polars_ensure};
5
6
use crate::array::Array;
7
use crate::bitmap::{Bitmap, and_not, push_bitchunk, ternary};
8
9
pub fn combine_validities_and3(
10
opt1: Option<&Bitmap>,
11
opt2: Option<&Bitmap>,
12
opt3: Option<&Bitmap>,
13
) -> Option<Bitmap> {
14
match (opt1, opt2, opt3) {
15
(Some(a), Some(b), Some(c)) => Some(ternary(a, b, c, |x, y, z| x & y & z)),
16
(Some(a), Some(b), None) => Some(a.bitand(b)),
17
(Some(a), None, Some(c)) => Some(a.bitand(c)),
18
(None, Some(b), Some(c)) => Some(b.bitand(c)),
19
(Some(a), None, None) => Some(a.clone()),
20
(None, Some(b), None) => Some(b.clone()),
21
(None, None, Some(c)) => Some(c.clone()),
22
(None, None, None) => None,
23
}
24
}
25
26
pub fn combine_validities_and(opt_l: Option<&Bitmap>, opt_r: Option<&Bitmap>) -> Option<Bitmap> {
27
match (opt_l, opt_r) {
28
(Some(l), Some(r)) => Some(l.bitand(r)),
29
(None, Some(r)) => Some(r.clone()),
30
(Some(l), None) => Some(l.clone()),
31
(None, None) => None,
32
}
33
}
34
35
pub fn combine_validities_or(opt_l: Option<&Bitmap>, opt_r: Option<&Bitmap>) -> Option<Bitmap> {
36
match (opt_l, opt_r) {
37
(Some(l), Some(r)) => Some(l.bitor(r)),
38
_ => None,
39
}
40
}
41
42
pub fn combine_validities_and_not(
43
opt_l: Option<&Bitmap>,
44
opt_r: Option<&Bitmap>,
45
) -> Option<Bitmap> {
46
match (opt_l, opt_r) {
47
(Some(l), Some(r)) => Some(and_not(l, r)),
48
(None, Some(r)) => Some(!r),
49
(Some(l), None) => Some(l.clone()),
50
(None, None) => None,
51
}
52
}
53
54
pub fn combine_validities_and_many<B: Borrow<Bitmap>>(bitmaps: &[Option<B>]) -> Option<Bitmap> {
55
let mut bitmaps = bitmaps
56
.iter()
57
.flatten()
58
.map(|b| b.borrow())
59
.collect::<Vec<_>>();
60
61
match bitmaps.len() {
62
0 => None,
63
1 => bitmaps.pop().cloned(),
64
2 => combine_validities_and(bitmaps.pop(), bitmaps.pop()),
65
3 => combine_validities_and3(bitmaps.pop(), bitmaps.pop(), bitmaps.pop()),
66
_ => {
67
let mut iterators = bitmaps
68
.iter()
69
.map(|v| v.fast_iter_u64())
70
.collect::<Vec<_>>();
71
let mut buffer = Vec::with_capacity(iterators.first().unwrap().size_hint().0 + 2);
72
73
'rows: loop {
74
// All ones so as identity for & operation
75
let mut out = u64::MAX;
76
for iter in iterators.iter_mut() {
77
if let Some(v) = iter.next() {
78
out &= v
79
} else {
80
break 'rows;
81
}
82
}
83
push_bitchunk(&mut buffer, out);
84
}
85
86
// All ones so as identity for & operation
87
let mut out = [u64::MAX, u64::MAX];
88
let mut len = 0;
89
for iter in iterators.into_iter() {
90
let (rem, rem_len) = iter.remainder();
91
len = rem_len;
92
93
for (out, rem) in out.iter_mut().zip(rem) {
94
*out &= rem;
95
}
96
}
97
push_bitchunk(&mut buffer, out[0]);
98
if len > 64 {
99
push_bitchunk(&mut buffer, out[1]);
100
}
101
let bitmap = Bitmap::from_u8_vec(buffer, bitmaps[0].len());
102
if bitmap.unset_bits() == bitmap.len() {
103
None
104
} else {
105
Some(bitmap)
106
}
107
},
108
}
109
}
110
111
// Errors iff the two arrays have a different length.
112
#[inline]
113
pub fn check_same_len(lhs: &dyn Array, rhs: &dyn Array) -> PolarsResult<()> {
114
polars_ensure!(lhs.len() == rhs.len(), ComputeError:
115
"arrays must have the same length"
116
);
117
Ok(())
118
}
119
120