1#![allow(unsafe_op_in_unsafe_fn)]
21use std::any::Any;
22use std::sync::Arc;
23
24use crate::bitmap::{Bitmap, MutableBitmap};
25use crate::datatypes::ArrowDataType;
26
27pub mod physical_binary;
28#[cfg(feature = "proptest")]
29pub mod proptest;
30
31pub trait Splitable: Sized {
32 fn check_bound(&self, offset: usize) -> bool;
33
34 #[inline]
36 #[must_use]
37 fn split_at(&self, offset: usize) -> (Self, Self) {
38 assert!(self.check_bound(offset));
39 unsafe { self._split_at_unchecked(offset) }
40 }
41
42 #[inline]
48 #[must_use]
49 unsafe fn split_at_unchecked(&self, offset: usize) -> (Self, Self) {
50 debug_assert!(self.check_bound(offset));
51 unsafe { self._split_at_unchecked(offset) }
52 }
53
54 unsafe fn _split_at_unchecked(&self, offset: usize) -> (Self, Self);
61}
62
63pub trait Array: Send + Sync + dyn_clone::DynClone + 'static {
66 fn as_any(&self) -> &dyn Any;
68
69 fn as_any_mut(&mut self) -> &mut dyn Any;
71
72 fn len(&self) -> usize;
75
76 fn is_empty(&self) -> bool {
78 self.len() == 0
79 }
80
81 fn dtype(&self) -> &ArrowDataType;
84
85 fn validity(&self) -> Option<&Bitmap>;
89
90 #[inline]
94 fn null_count(&self) -> usize {
95 if self.dtype() == &ArrowDataType::Null {
96 return self.len();
97 };
98 self.validity()
99 .as_ref()
100 .map(|x| x.unset_bits())
101 .unwrap_or(0)
102 }
103
104 #[inline]
105 fn has_nulls(&self) -> bool {
106 self.null_count() > 0
107 }
108
109 #[inline]
113 fn is_null(&self, i: usize) -> bool {
114 assert!(i < self.len());
115 unsafe { self.is_null_unchecked(i) }
116 }
117
118 #[inline]
123 unsafe fn is_null_unchecked(&self, i: usize) -> bool {
124 self.validity()
125 .as_ref()
126 .map(|x| !x.get_bit_unchecked(i))
127 .unwrap_or(false)
128 }
129
130 #[inline]
134 fn is_valid(&self, i: usize) -> bool {
135 !self.is_null(i)
136 }
137
138 #[must_use]
140 fn split_at_boxed(&self, offset: usize) -> (Box<dyn Array>, Box<dyn Array>);
141
142 #[must_use]
148 unsafe fn split_at_boxed_unchecked(&self, offset: usize) -> (Box<dyn Array>, Box<dyn Array>);
149
150 fn slice(&mut self, offset: usize, length: usize);
156
157 unsafe fn slice_unchecked(&mut self, offset: usize, length: usize);
164
165 #[must_use]
171 fn sliced(&self, offset: usize, length: usize) -> Box<dyn Array> {
172 if length == 0 {
173 return new_empty_array(self.dtype().clone());
174 }
175 let mut new = self.to_boxed();
176 new.slice(offset, length);
177 new
178 }
179
180 #[must_use]
188 unsafe fn sliced_unchecked(&self, offset: usize, length: usize) -> Box<dyn Array> {
189 debug_assert!(offset + length <= self.len());
190 let mut new = self.to_boxed();
191 new.slice_unchecked(offset, length);
192 new
193 }
194
195 fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array>;
199
200 fn to_boxed(&self) -> Box<dyn Array>;
202}
203
204dyn_clone::clone_trait_object!(Array);
205
206pub trait IntoBoxedArray {
207 fn into_boxed(self) -> Box<dyn Array>;
208}
209
210impl<A: Array> IntoBoxedArray for A {
211 #[inline(always)]
212 fn into_boxed(self) -> Box<dyn Array> {
213 Box::new(self) as _
214 }
215}
216impl IntoBoxedArray for Box<dyn Array> {
217 #[inline(always)]
218 fn into_boxed(self) -> Box<dyn Array> {
219 self
220 }
221}
222
223pub trait MutableArray: std::fmt::Debug + Send + Sync {
229 fn dtype(&self) -> &ArrowDataType;
231
232 fn len(&self) -> usize;
234
235 fn is_empty(&self) -> bool {
237 self.len() == 0
238 }
239
240 fn validity(&self) -> Option<&MutableBitmap>;
242
243 fn as_box(&mut self) -> Box<dyn Array>;
245
246 fn as_arc(&mut self) -> std::sync::Arc<dyn Array> {
251 self.as_box().into()
252 }
253
254 fn as_any(&self) -> &dyn Any;
256
257 fn as_mut_any(&mut self) -> &mut dyn Any;
259
260 fn push_null(&mut self);
262
263 #[inline]
267 fn is_valid(&self, index: usize) -> bool {
268 self.validity()
269 .as_ref()
270 .map(|x| x.get(index))
271 .unwrap_or(true)
272 }
273
274 fn reserve(&mut self, additional: usize);
276
277 fn shrink_to_fit(&mut self);
279}
280
281impl MutableArray for Box<dyn MutableArray> {
282 fn len(&self) -> usize {
283 self.as_ref().len()
284 }
285
286 fn validity(&self) -> Option<&MutableBitmap> {
287 self.as_ref().validity()
288 }
289
290 fn as_box(&mut self) -> Box<dyn Array> {
291 self.as_mut().as_box()
292 }
293
294 fn as_arc(&mut self) -> Arc<dyn Array> {
295 self.as_mut().as_arc()
296 }
297
298 fn dtype(&self) -> &ArrowDataType {
299 self.as_ref().dtype()
300 }
301
302 fn as_any(&self) -> &dyn std::any::Any {
303 self.as_ref().as_any()
304 }
305
306 fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
307 self.as_mut().as_mut_any()
308 }
309
310 #[inline]
311 fn push_null(&mut self) {
312 self.as_mut().push_null()
313 }
314
315 fn shrink_to_fit(&mut self) {
316 self.as_mut().shrink_to_fit();
317 }
318
319 fn reserve(&mut self, additional: usize) {
320 self.as_mut().reserve(additional);
321 }
322}
323
324macro_rules! general_dyn {
325 ($array:expr, $ty:ty, $f:expr) => {{
326 let array = $array.as_any().downcast_ref::<$ty>().unwrap();
327 ($f)(array)
328 }};
329}
330
331macro_rules! fmt_dyn {
332 ($array:expr, $ty:ty, $f:expr) => {{
333 let mut f = |x: &$ty| x.fmt($f);
334 general_dyn!($array, $ty, f)
335 }};
336}
337
338impl std::fmt::Debug for dyn Array + '_ {
339 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
340 use crate::datatypes::PhysicalType::*;
341 match self.dtype().to_physical_type() {
342 Null => fmt_dyn!(self, NullArray, f),
343 Boolean => fmt_dyn!(self, BooleanArray, f),
344 Primitive(primitive) => with_match_primitive_type_full!(primitive, |$T| {
345 fmt_dyn!(self, PrimitiveArray<$T>, f)
346 }),
347 BinaryView => fmt_dyn!(self, BinaryViewArray, f),
348 Utf8View => fmt_dyn!(self, Utf8ViewArray, f),
349 Binary => fmt_dyn!(self, BinaryArray<i32>, f),
350 LargeBinary => fmt_dyn!(self, BinaryArray<i64>, f),
351 FixedSizeBinary => fmt_dyn!(self, FixedSizeBinaryArray, f),
352 Utf8 => fmt_dyn!(self, Utf8Array::<i32>, f),
353 LargeUtf8 => fmt_dyn!(self, Utf8Array::<i64>, f),
354 List => fmt_dyn!(self, ListArray::<i32>, f),
355 LargeList => fmt_dyn!(self, ListArray::<i64>, f),
356 FixedSizeList => fmt_dyn!(self, FixedSizeListArray, f),
357 Struct => fmt_dyn!(self, StructArray, f),
358 Union => fmt_dyn!(self, UnionArray, f),
359 Dictionary(key_type) => {
360 match_integer_type!(key_type, |$T| {
361 fmt_dyn!(self, DictionaryArray::<$T>, f)
362 })
363 },
364 Map => fmt_dyn!(self, MapArray, f),
365 }
366 }
367}
368
369pub fn new_empty_array(dtype: ArrowDataType) -> Box<dyn Array> {
371 use crate::datatypes::PhysicalType::*;
372 match dtype.to_physical_type() {
373 Null => Box::new(NullArray::new_empty(dtype)),
374 Boolean => Box::new(BooleanArray::new_empty(dtype)),
375 Primitive(primitive) => with_match_primitive_type_full!(primitive, |$T| {
376 Box::new(PrimitiveArray::<$T>::new_empty(dtype))
377 }),
378 Binary => Box::new(BinaryArray::<i32>::new_empty(dtype)),
379 LargeBinary => Box::new(BinaryArray::<i64>::new_empty(dtype)),
380 FixedSizeBinary => Box::new(FixedSizeBinaryArray::new_empty(dtype)),
381 Utf8 => Box::new(Utf8Array::<i32>::new_empty(dtype)),
382 LargeUtf8 => Box::new(Utf8Array::<i64>::new_empty(dtype)),
383 List => Box::new(ListArray::<i32>::new_empty(dtype)),
384 LargeList => Box::new(ListArray::<i64>::new_empty(dtype)),
385 FixedSizeList => Box::new(FixedSizeListArray::new_empty(dtype)),
386 Struct => Box::new(StructArray::new_empty(dtype)),
387 Union => Box::new(UnionArray::new_empty(dtype)),
388 Map => Box::new(MapArray::new_empty(dtype)),
389 Utf8View => Box::new(Utf8ViewArray::new_empty(dtype)),
390 BinaryView => Box::new(BinaryViewArray::new_empty(dtype)),
391 Dictionary(key_type) => {
392 match_integer_type!(key_type, |$T| {
393 Box::new(DictionaryArray::<$T>::new_empty(dtype))
394 })
395 },
396 }
397}
398
399pub fn new_null_array(dtype: ArrowDataType, length: usize) -> Box<dyn Array> {
404 use crate::datatypes::PhysicalType::*;
405 match dtype.to_physical_type() {
406 Null => Box::new(NullArray::new_null(dtype, length)),
407 Boolean => Box::new(BooleanArray::new_null(dtype, length)),
408 Primitive(primitive) => with_match_primitive_type_full!(primitive, |$T| {
409 Box::new(PrimitiveArray::<$T>::new_null(dtype, length))
410 }),
411 Binary => Box::new(BinaryArray::<i32>::new_null(dtype, length)),
412 LargeBinary => Box::new(BinaryArray::<i64>::new_null(dtype, length)),
413 FixedSizeBinary => Box::new(FixedSizeBinaryArray::new_null(dtype, length)),
414 Utf8 => Box::new(Utf8Array::<i32>::new_null(dtype, length)),
415 LargeUtf8 => Box::new(Utf8Array::<i64>::new_null(dtype, length)),
416 List => Box::new(ListArray::<i32>::new_null(dtype, length)),
417 LargeList => Box::new(ListArray::<i64>::new_null(dtype, length)),
418 FixedSizeList => Box::new(FixedSizeListArray::new_null(dtype, length)),
419 Struct => Box::new(StructArray::new_null(dtype, length)),
420 Union => Box::new(UnionArray::new_null(dtype, length)),
421 Map => Box::new(MapArray::new_null(dtype, length)),
422 BinaryView => Box::new(BinaryViewArray::new_null(dtype, length)),
423 Utf8View => Box::new(Utf8ViewArray::new_null(dtype, length)),
424 Dictionary(key_type) => {
425 match_integer_type!(key_type, |$T| {
426 Box::new(DictionaryArray::<$T>::new_null(dtype, length))
427 })
428 },
429 }
430}
431
432macro_rules! clone_dyn {
433 ($array:expr, $ty:ty) => {{
434 let f = |x: &$ty| Box::new(x.clone());
435 general_dyn!($array, $ty, f)
436 }};
437}
438
439macro_rules! impl_sliced {
441 () => {
442 #[inline]
448 #[must_use]
449 pub fn sliced(self, offset: usize, length: usize) -> Self {
450 let total = offset
451 .checked_add(length)
452 .expect("offset + length overflowed");
453 assert!(
454 total <= self.len(),
455 "the offset of the new Buffer cannot exceed the existing length"
456 );
457 unsafe { Self::sliced_unchecked(self, offset, length) }
458 }
459
460 #[inline]
467 #[must_use]
468 pub unsafe fn sliced_unchecked(mut self, offset: usize, length: usize) -> Self {
469 Self::slice_unchecked(&mut self, offset, length);
470 self
471 }
472 };
473}
474
475macro_rules! impl_mut_validity {
477 () => {
478 #[must_use]
482 #[inline]
483 pub fn with_validity(mut self, validity: Option<Bitmap>) -> Self {
484 self.set_validity(validity);
485 self
486 }
487
488 #[inline]
492 pub fn set_validity(&mut self, validity: Option<Bitmap>) {
493 if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
494 panic!("validity must be equal to the array's length")
495 }
496 self.validity = validity;
497 }
498
499 #[inline]
501 pub fn take_validity(&mut self) -> Option<Bitmap> {
502 self.validity.take()
503 }
504 }
505}
506
507macro_rules! impl_mutable_array_mut_validity {
509 () => {
510 #[must_use]
514 #[inline]
515 pub fn with_validity(mut self, validity: Option<MutableBitmap>) -> Self {
516 self.set_validity(validity);
517 self
518 }
519
520 #[inline]
524 pub fn set_validity(&mut self, validity: Option<MutableBitmap>) {
525 if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
526 panic!("validity must be equal to the array's length")
527 }
528 self.validity = validity;
529 }
530
531 #[inline]
537 pub fn apply_validity<F: FnOnce(MutableBitmap) -> MutableBitmap>(&mut self, f: F) {
538 if let Some(validity) = std::mem::take(&mut self.validity) {
539 self.set_validity(Some(f(validity)))
540 }
541 }
542
543 }
544}
545
546macro_rules! impl_into_array {
548 () => {
549 pub fn boxed(self) -> Box<dyn Array> {
551 Box::new(self)
552 }
553
554 pub fn arced(self) -> std::sync::Arc<dyn Array> {
556 std::sync::Arc::new(self)
557 }
558 };
559}
560
561macro_rules! impl_common_array {
563 () => {
564 #[inline]
565 fn as_any(&self) -> &dyn std::any::Any {
566 self
567 }
568
569 #[inline]
570 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
571 self
572 }
573
574 #[inline]
575 fn len(&self) -> usize {
576 self.len()
577 }
578
579 #[inline]
580 fn dtype(&self) -> &ArrowDataType {
581 &self.dtype
582 }
583
584 #[inline]
585 fn split_at_boxed(&self, offset: usize) -> (Box<dyn Array>, Box<dyn Array>) {
586 let (lhs, rhs) = $crate::array::Splitable::split_at(self, offset);
587 (Box::new(lhs), Box::new(rhs))
588 }
589
590 #[inline]
591 unsafe fn split_at_boxed_unchecked(
592 &self,
593 offset: usize,
594 ) -> (Box<dyn Array>, Box<dyn Array>) {
595 let (lhs, rhs) = unsafe { $crate::array::Splitable::split_at_unchecked(self, offset) };
596 (Box::new(lhs), Box::new(rhs))
597 }
598
599 #[inline]
600 fn slice(&mut self, offset: usize, length: usize) {
601 self.slice(offset, length);
602 }
603
604 #[inline]
605 unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
606 self.slice_unchecked(offset, length);
607 }
608
609 #[inline]
610 fn to_boxed(&self) -> Box<dyn Array> {
611 Box::new(self.clone())
612 }
613 };
614}
615
616pub fn clone(array: &dyn Array) -> Box<dyn Array> {
621 use crate::datatypes::PhysicalType::*;
622 match array.dtype().to_physical_type() {
623 Null => clone_dyn!(array, NullArray),
624 Boolean => clone_dyn!(array, BooleanArray),
625 Primitive(primitive) => with_match_primitive_type_full!(primitive, |$T| {
626 clone_dyn!(array, PrimitiveArray<$T>)
627 }),
628 Binary => clone_dyn!(array, BinaryArray<i32>),
629 LargeBinary => clone_dyn!(array, BinaryArray<i64>),
630 FixedSizeBinary => clone_dyn!(array, FixedSizeBinaryArray),
631 Utf8 => clone_dyn!(array, Utf8Array::<i32>),
632 LargeUtf8 => clone_dyn!(array, Utf8Array::<i64>),
633 List => clone_dyn!(array, ListArray::<i32>),
634 LargeList => clone_dyn!(array, ListArray::<i64>),
635 FixedSizeList => clone_dyn!(array, FixedSizeListArray),
636 Struct => clone_dyn!(array, StructArray),
637 Union => clone_dyn!(array, UnionArray),
638 Map => clone_dyn!(array, MapArray),
639 BinaryView => clone_dyn!(array, BinaryViewArray),
640 Utf8View => clone_dyn!(array, Utf8ViewArray),
641 Dictionary(key_type) => {
642 match_integer_type!(key_type, |$T| {
643 clone_dyn!(array, DictionaryArray::<$T>)
644 })
645 },
646 }
647}
648
649impl<'a> AsRef<dyn Array + 'a> for dyn Array {
652 fn as_ref(&self) -> &(dyn Array + 'a) {
653 self
654 }
655}
656
657mod binary;
658mod boolean;
659pub mod builder;
660mod dictionary;
661mod fixed_size_binary;
662mod fixed_size_list;
663mod list;
664pub use list::LIST_VALUES_NAME;
665mod map;
666mod null;
667mod primitive;
668pub mod specification;
669mod static_array;
670mod static_array_collect;
671mod struct_;
672mod total_ord;
673mod union;
674mod utf8;
675
676mod equal;
677mod ffi;
678mod fmt;
679#[doc(hidden)]
680pub mod indexable;
681pub mod iterator;
682
683mod binview;
684mod values;
685
686pub use binary::{
687 BinaryArray, BinaryArrayBuilder, BinaryValueIter, MutableBinaryArray, MutableBinaryValuesArray,
688};
689pub use binview::{
690 BinaryViewArray, BinaryViewArrayBuilder, BinaryViewArrayGeneric, BinaryViewArrayGenericBuilder,
691 MutableBinaryViewArray, MutablePlBinary, MutablePlString, Utf8ViewArray, Utf8ViewArrayBuilder,
692 View, ViewType,
693};
694pub use boolean::{BooleanArray, BooleanArrayBuilder, MutableBooleanArray};
695pub use dictionary::{DictionaryArray, DictionaryKey, MutableDictionaryArray};
696pub use equal::equal;
697pub use fixed_size_binary::{
698 FixedSizeBinaryArray, FixedSizeBinaryArrayBuilder, MutableFixedSizeBinaryArray,
699};
700pub use fixed_size_list::{
701 FixedSizeListArray, FixedSizeListArrayBuilder, MutableFixedSizeListArray,
702};
703pub use fmt::{get_display, get_value_display};
704pub(crate) use iterator::ArrayAccessor;
705pub use iterator::ArrayValuesIter;
706pub use list::{ListArray, ListArrayBuilder, ListValuesIter, MutableListArray};
707pub use map::MapArray;
708pub use null::{MutableNullArray, NullArray, NullArrayBuilder};
709use polars_error::PolarsResult;
710pub use primitive::*;
711pub use static_array::{ParameterFreeDtypeStaticArray, StaticArray};
712pub use static_array_collect::{ArrayCollectIterExt, ArrayFromIter, ArrayFromIterDtype};
713pub use struct_::{StructArray, StructArrayBuilder};
714pub use union::UnionArray;
715pub use utf8::{MutableUtf8Array, MutableUtf8ValuesArray, Utf8Array, Utf8ValuesIter};
716pub use values::ValueSize;
717
718#[cfg(feature = "proptest")]
719pub use self::boolean::proptest::boolean_array;
720pub(crate) use self::ffi::{FromFfi, ToFfi, offset_buffers_children_dictionary};
721use crate::{match_integer_type, with_match_primitive_type_full};
722
723pub trait TryExtend<A> {
726 fn try_extend<I: IntoIterator<Item = A>>(&mut self, iter: I) -> PolarsResult<()>;
728}
729
730pub trait TryPush<A> {
732 fn try_push(&mut self, item: A) -> PolarsResult<()>;
734}
735
736pub trait PushUnchecked<A> {
738 unsafe fn push_unchecked(&mut self, item: A);
744}
745
746pub trait TryExtendFromSelf {
749 fn try_extend_from_self(&mut self, other: &Self) -> PolarsResult<()>;
751}
752
753pub unsafe trait GenericBinaryArray<O: crate::offset::Offset>: Array {
760 fn values(&self) -> &[u8];
762 fn offsets(&self) -> &[O];
764}
765
766pub type ArrayRef = Box<dyn Array>;
767
768impl Splitable for Option<Bitmap> {
769 #[inline(always)]
770 fn check_bound(&self, offset: usize) -> bool {
771 self.as_ref().is_none_or(|v| offset <= v.len())
772 }
773
774 unsafe fn _split_at_unchecked(&self, offset: usize) -> (Self, Self) {
775 self.as_ref().map_or((None, None), |bm| {
776 let (lhs, rhs) = unsafe { bm.split_at_unchecked(offset) };
777 (
778 (lhs.unset_bits() > 0).then_some(lhs),
779 (rhs.unset_bits() > 0).then_some(rhs),
780 )
781 })
782 }
783}