polars_arrow/array/boolean/
mod.rs1use either::Either;
2use polars_error::{PolarsResult, polars_bail};
3
4use super::{Array, Splitable};
5use crate::array::iterator::NonNullValuesIter;
6use crate::bitmap::utils::{BitmapIter, ZipValidity};
7use crate::bitmap::{Bitmap, MutableBitmap};
8use crate::compute::utils::{combine_validities_and, combine_validities_or};
9use crate::datatypes::{ArrowDataType, PhysicalType};
10use crate::trusted_len::TrustedLen;
11
12mod ffi;
13pub(super) mod fmt;
14mod from;
15mod iterator;
16mod mutable;
17pub use mutable::*;
18mod builder;
19pub use builder::*;
20#[cfg(feature = "proptest")]
21pub mod proptest;
22
23#[derive(Clone)]
49pub struct BooleanArray {
50 dtype: ArrowDataType,
51 values: Bitmap,
52 validity: Option<Bitmap>,
53}
54
55impl BooleanArray {
56 pub fn try_new(
62 dtype: ArrowDataType,
63 values: Bitmap,
64 validity: Option<Bitmap>,
65 ) -> PolarsResult<Self> {
66 if validity
67 .as_ref()
68 .is_some_and(|validity| validity.len() != values.len())
69 {
70 polars_bail!(ComputeError: "validity mask length must match the number of values")
71 }
72
73 if dtype.to_physical_type() != PhysicalType::Boolean {
74 polars_bail!(ComputeError: "BooleanArray can only be initialized with a DataType whose physical type is Boolean")
75 }
76
77 Ok(Self {
78 dtype,
79 values,
80 validity,
81 })
82 }
83
84 pub fn new(dtype: ArrowDataType, values: Bitmap, validity: Option<Bitmap>) -> Self {
86 Self::try_new(dtype, values, validity).unwrap()
87 }
88
89 #[inline]
91 pub fn iter(&self) -> ZipValidity<bool, BitmapIter, BitmapIter> {
92 ZipValidity::new_with_validity(self.values().iter(), self.validity())
93 }
94
95 #[inline]
97 pub fn values_iter(&self) -> BitmapIter {
98 self.values().iter()
99 }
100
101 #[inline]
103 pub fn non_null_values_iter(&self) -> NonNullValuesIter<'_, BooleanArray> {
104 NonNullValuesIter::new(self, self.validity())
105 }
106
107 #[inline]
109 pub fn len(&self) -> usize {
110 self.values.len()
111 }
112
113 #[inline]
116 pub fn values(&self) -> &Bitmap {
117 &self.values
118 }
119
120 #[inline]
122 pub fn validity(&self) -> Option<&Bitmap> {
123 self.validity.as_ref()
124 }
125
126 #[inline]
128 pub fn dtype(&self) -> &ArrowDataType {
129 &self.dtype
130 }
131
132 #[inline]
136 pub fn value(&self, i: usize) -> bool {
137 self.values.get_bit(i)
138 }
139
140 #[inline]
145 pub unsafe fn value_unchecked(&self, i: usize) -> bool {
146 self.values.get_bit_unchecked(i)
147 }
148
149 #[inline]
153 pub fn get(&self, i: usize) -> Option<bool> {
154 if !self.is_null(i) {
155 unsafe { Some(self.value_unchecked(i)) }
157 } else {
158 None
159 }
160 }
161
162 #[inline]
168 pub fn slice(&mut self, offset: usize, length: usize) {
169 assert!(
170 offset + length <= self.len(),
171 "the offset of the new Buffer cannot exceed the existing length"
172 );
173 unsafe { self.slice_unchecked(offset, length) }
174 }
175
176 #[inline]
183 pub unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
184 self.validity = self
185 .validity
186 .take()
187 .map(|bitmap| bitmap.sliced_unchecked(offset, length))
188 .filter(|bitmap| bitmap.unset_bits() > 0);
189 self.values.slice_unchecked(offset, length);
190 }
191
192 impl_sliced!();
193 impl_mut_validity!();
194 impl_into_array!();
195
196 #[must_use]
200 pub fn with_values(&self, values: Bitmap) -> Self {
201 let mut out = self.clone();
202 out.set_values(values);
203 out
204 }
205
206 pub fn set_values(&mut self, values: Bitmap) {
210 assert_eq!(
211 values.len(),
212 self.len(),
213 "values length must be equal to this arrays length"
214 );
215 self.values = values;
216 }
217
218 pub fn apply_values_mut<F: Fn(&mut MutableBitmap)>(&mut self, f: F) {
228 let values = std::mem::take(&mut self.values);
229 let mut values = values.make_mut();
230 f(&mut values);
231 if let Some(validity) = &self.validity {
232 assert_eq!(validity.len(), values.len());
233 }
234 self.values = values.into();
235 }
236
237 pub fn into_mut(self) -> Either<Self, MutableBooleanArray> {
239 use Either::*;
240
241 if let Some(bitmap) = self.validity {
242 match bitmap.into_mut() {
243 Left(bitmap) => Left(BooleanArray::new(self.dtype, self.values, Some(bitmap))),
244 Right(mutable_bitmap) => match self.values.into_mut() {
245 Left(immutable) => Left(BooleanArray::new(
246 self.dtype,
247 immutable,
248 Some(mutable_bitmap.into()),
249 )),
250 Right(mutable) => Right(
251 MutableBooleanArray::try_new(self.dtype, mutable, Some(mutable_bitmap))
252 .unwrap(),
253 ),
254 },
255 }
256 } else {
257 match self.values.into_mut() {
258 Left(immutable) => Left(BooleanArray::new(self.dtype, immutable, None)),
259 Right(mutable) => {
260 Right(MutableBooleanArray::try_new(self.dtype, mutable, None).unwrap())
261 },
262 }
263 }
264 }
265
266 pub fn new_empty(dtype: ArrowDataType) -> Self {
268 Self::new(dtype, Bitmap::new(), None)
269 }
270
271 pub fn new_null(dtype: ArrowDataType, length: usize) -> Self {
273 let bitmap = Bitmap::new_zeroed(length);
274 Self::new(dtype, bitmap.clone(), Some(bitmap))
275 }
276
277 #[inline]
279 pub fn from_trusted_len_values_iter<I: TrustedLen<Item = bool>>(iterator: I) -> Self {
280 MutableBooleanArray::from_trusted_len_values_iter(iterator).into()
281 }
282
283 #[inline]
291 pub unsafe fn from_trusted_len_values_iter_unchecked<I: Iterator<Item = bool>>(
292 iterator: I,
293 ) -> Self {
294 MutableBooleanArray::from_trusted_len_values_iter_unchecked(iterator).into()
295 }
296
297 #[inline]
299 pub fn from_slice<P: AsRef<[bool]>>(slice: P) -> Self {
300 MutableBooleanArray::from_slice(slice).into()
301 }
302
303 #[inline]
311 pub unsafe fn from_trusted_len_iter_unchecked<I, P>(iterator: I) -> Self
312 where
313 P: std::borrow::Borrow<bool>,
314 I: Iterator<Item = Option<P>>,
315 {
316 MutableBooleanArray::from_trusted_len_iter_unchecked(iterator).into()
317 }
318
319 #[inline]
321 pub fn from_trusted_len_iter<I, P>(iterator: I) -> Self
322 where
323 P: std::borrow::Borrow<bool>,
324 I: TrustedLen<Item = Option<P>>,
325 {
326 MutableBooleanArray::from_trusted_len_iter(iterator).into()
327 }
328
329 #[inline]
335 pub unsafe fn try_from_trusted_len_iter_unchecked<E, I, P>(iterator: I) -> Result<Self, E>
336 where
337 P: std::borrow::Borrow<bool>,
338 I: Iterator<Item = Result<Option<P>, E>>,
339 {
340 Ok(MutableBooleanArray::try_from_trusted_len_iter_unchecked(iterator)?.into())
341 }
342
343 #[inline]
345 pub fn try_from_trusted_len_iter<E, I, P>(iterator: I) -> Result<Self, E>
346 where
347 P: std::borrow::Borrow<bool>,
348 I: TrustedLen<Item = Result<Option<P>, E>>,
349 {
350 Ok(MutableBooleanArray::try_from_trusted_len_iter(iterator)?.into())
351 }
352
353 pub fn true_and_valid(&self) -> Bitmap {
354 match &self.validity {
355 None => self.values.clone(),
356 Some(validity) => combine_validities_and(Some(&self.values), Some(validity)).unwrap(),
357 }
358 }
359
360 pub fn true_or_valid(&self) -> Bitmap {
361 match &self.validity {
362 None => self.values.clone(),
363 Some(validity) => combine_validities_or(Some(&self.values), Some(validity)).unwrap(),
364 }
365 }
366
367 #[must_use]
369 pub fn into_inner(self) -> (ArrowDataType, Bitmap, Option<Bitmap>) {
370 let Self {
371 dtype,
372 values,
373 validity,
374 } = self;
375 (dtype, values, validity)
376 }
377
378 pub unsafe fn from_inner_unchecked(
384 dtype: ArrowDataType,
385 values: Bitmap,
386 validity: Option<Bitmap>,
387 ) -> Self {
388 Self {
389 dtype,
390 values,
391 validity,
392 }
393 }
394}
395
396impl Array for BooleanArray {
397 impl_common_array!();
398
399 fn validity(&self) -> Option<&Bitmap> {
400 self.validity.as_ref()
401 }
402
403 #[inline]
404 fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
405 Box::new(self.clone().with_validity(validity))
406 }
407}
408
409impl Splitable for BooleanArray {
410 fn check_bound(&self, offset: usize) -> bool {
411 offset <= self.len()
412 }
413
414 unsafe fn _split_at_unchecked(&self, offset: usize) -> (Self, Self) {
415 let (lhs_values, rhs_values) = unsafe { self.values.split_at_unchecked(offset) };
416 let (lhs_validity, rhs_validity) = unsafe { self.validity.split_at_unchecked(offset) };
417
418 (
419 Self {
420 dtype: self.dtype.clone(),
421 values: lhs_values,
422 validity: lhs_validity,
423 },
424 Self {
425 dtype: self.dtype.clone(),
426 values: rhs_values,
427 validity: rhs_validity,
428 },
429 )
430 }
431}
432
433impl From<Bitmap> for BooleanArray {
434 fn from(values: Bitmap) -> Self {
435 Self {
436 dtype: ArrowDataType::Boolean,
437 values,
438 validity: None,
439 }
440 }
441}