Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-arrow/src/array/primitive/mod.rs
6939 views
1
use std::ops::Range;
2
3
use either::Either;
4
5
use super::{Array, Splitable};
6
use crate::array::iterator::NonNullValuesIter;
7
use crate::bitmap::Bitmap;
8
use crate::bitmap::utils::{BitmapIter, ZipValidity};
9
use crate::buffer::Buffer;
10
use crate::datatypes::*;
11
use crate::trusted_len::TrustedLen;
12
use crate::types::{NativeType, days_ms, f16, i256, months_days_ns};
13
14
mod ffi;
15
pub(super) mod fmt;
16
mod from_natural;
17
pub mod iterator;
18
#[cfg(feature = "proptest")]
19
pub mod proptest;
20
21
mod mutable;
22
pub use mutable::*;
23
mod builder;
24
pub use builder::*;
25
use polars_error::{PolarsResult, polars_bail};
26
use polars_utils::index::{Bounded, Indexable, NullCount};
27
use polars_utils::slice::SliceAble;
28
29
/// A [`PrimitiveArray`] is Arrow's semantically equivalent of an immutable `Vec<Option<T>>` where
30
/// T is [`NativeType`] (e.g. [`i32`]). It implements [`Array`].
31
///
32
/// One way to think about a [`PrimitiveArray`] is `(DataType, Arc<Vec<T>>, Option<Arc<Vec<u8>>>)`
33
/// where:
34
/// * the first item is the array's logical type
35
/// * the second is the immutable values
36
/// * the third is the immutable validity (whether a value is null or not as a bitmap).
37
///
38
/// The size of this struct is `O(1)`, as all data is stored behind an [`std::sync::Arc`].
39
/// # Example
40
/// ```
41
/// use polars_arrow::array::PrimitiveArray;
42
/// use polars_arrow::bitmap::Bitmap;
43
/// use polars_arrow::buffer::Buffer;
44
///
45
/// let array = PrimitiveArray::from([Some(1i32), None, Some(10)]);
46
/// assert_eq!(array.value(0), 1);
47
/// assert_eq!(array.iter().collect::<Vec<_>>(), vec![Some(&1i32), None, Some(&10)]);
48
/// assert_eq!(array.values_iter().copied().collect::<Vec<_>>(), vec![1, 0, 10]);
49
/// // the underlying representation
50
/// assert_eq!(array.values(), &Buffer::from(vec![1i32, 0, 10]));
51
/// assert_eq!(array.validity(), Some(&Bitmap::from([true, false, true])));
52
///
53
/// ```
54
#[derive(Clone)]
55
pub struct PrimitiveArray<T: NativeType> {
56
dtype: ArrowDataType,
57
values: Buffer<T>,
58
validity: Option<Bitmap>,
59
}
60
61
pub(super) fn check<T: NativeType>(
62
dtype: &ArrowDataType,
63
values: &[T],
64
validity_len: Option<usize>,
65
) -> PolarsResult<()> {
66
if validity_len.is_some_and(|len| len != values.len()) {
67
polars_bail!(ComputeError: "validity mask length must match the number of values")
68
}
69
70
if dtype.to_physical_type() != PhysicalType::Primitive(T::PRIMITIVE) {
71
polars_bail!(ComputeError: "PrimitiveArray can only be initialized with a DataType whose physical type is Primitive")
72
}
73
Ok(())
74
}
75
76
impl<T: NativeType> PrimitiveArray<T> {
77
/// The canonical method to create a [`PrimitiveArray`] out of its internal components.
78
/// # Implementation
79
/// This function is `O(1)`.
80
///
81
/// # Errors
82
/// This function errors iff:
83
/// * The validity is not `None` and its length is different from `values`'s length
84
/// * The `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive(T::PRIMITIVE)`]
85
pub fn try_new(
86
dtype: ArrowDataType,
87
values: Buffer<T>,
88
validity: Option<Bitmap>,
89
) -> PolarsResult<Self> {
90
check(&dtype, &values, validity.as_ref().map(|v| v.len()))?;
91
Ok(Self {
92
dtype,
93
values,
94
validity,
95
})
96
}
97
98
/// # Safety
99
/// Doesn't check invariants
100
pub unsafe fn new_unchecked(
101
dtype: ArrowDataType,
102
values: Buffer<T>,
103
validity: Option<Bitmap>,
104
) -> Self {
105
if cfg!(debug_assertions) {
106
check(&dtype, &values, validity.as_ref().map(|v| v.len())).unwrap();
107
}
108
109
Self {
110
dtype,
111
values,
112
validity,
113
}
114
}
115
116
/// Returns a new [`PrimitiveArray`] with a different logical type.
117
///
118
/// This function is useful to assign a different [`ArrowDataType`] to the array.
119
/// Used to change the arrays' logical type (see example).
120
/// # Example
121
/// ```
122
/// use polars_arrow::array::Int32Array;
123
/// use polars_arrow::datatypes::ArrowDataType;
124
///
125
/// let array = Int32Array::from(&[Some(1), None, Some(2)]).to(ArrowDataType::Date32);
126
/// assert_eq!(
127
/// format!("{:?}", array),
128
/// "Date32[1970-01-02, None, 1970-01-03]"
129
/// );
130
/// ```
131
/// # Panics
132
/// Panics iff the `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive(T::PRIMITIVE)`]
133
#[inline]
134
#[must_use]
135
pub fn to(self, dtype: ArrowDataType) -> Self {
136
check(
137
&dtype,
138
&self.values,
139
self.validity.as_ref().map(|v| v.len()),
140
)
141
.unwrap();
142
Self {
143
dtype,
144
values: self.values,
145
validity: self.validity,
146
}
147
}
148
149
/// Creates a (non-null) [`PrimitiveArray`] from a vector of values.
150
/// This function is `O(1)`.
151
/// # Examples
152
/// ```
153
/// use polars_arrow::array::PrimitiveArray;
154
///
155
/// let array = PrimitiveArray::from_vec(vec![1, 2, 3]);
156
/// assert_eq!(format!("{:?}", array), "Int32[1, 2, 3]");
157
/// ```
158
pub fn from_vec(values: Vec<T>) -> Self {
159
Self::new(T::PRIMITIVE.into(), values.into(), None)
160
}
161
162
/// Returns an iterator over the values and validity, `Option<&T>`.
163
#[inline]
164
pub fn iter(&self) -> ZipValidity<&T, std::slice::Iter<'_, T>, BitmapIter<'_>> {
165
ZipValidity::new_with_validity(self.values().iter(), self.validity())
166
}
167
168
/// Returns an iterator of the values, `&T`, ignoring the arrays' validity.
169
#[inline]
170
pub fn values_iter(&self) -> std::slice::Iter<'_, T> {
171
self.values().iter()
172
}
173
174
/// Returns an iterator of the non-null values `T`.
175
#[inline]
176
pub fn non_null_values_iter(&self) -> NonNullValuesIter<'_, [T]> {
177
NonNullValuesIter::new(self.values(), self.validity())
178
}
179
180
/// Returns the length of this array
181
#[inline]
182
pub fn len(&self) -> usize {
183
self.values.len()
184
}
185
186
/// The values [`Buffer`].
187
/// Values on null slots are undetermined (they can be anything).
188
#[inline]
189
pub fn values(&self) -> &Buffer<T> {
190
&self.values
191
}
192
193
/// Returns the optional validity.
194
#[inline]
195
pub fn validity(&self) -> Option<&Bitmap> {
196
self.validity.as_ref()
197
}
198
199
/// Returns the arrays' [`ArrowDataType`].
200
#[inline]
201
pub fn dtype(&self) -> &ArrowDataType {
202
&self.dtype
203
}
204
205
/// Returns the value at slot `i`.
206
///
207
/// Equivalent to `self.values()[i]`. The value of a null slot is undetermined (it can be anything).
208
/// # Panic
209
/// This function panics iff `i >= self.len`.
210
#[inline]
211
pub fn value(&self, i: usize) -> T {
212
self.values[i]
213
}
214
215
/// Returns the value at index `i`.
216
/// The value on null slots is undetermined (it can be anything).
217
///
218
/// # Safety
219
/// Caller must be sure that `i < self.len()`
220
#[inline]
221
pub unsafe fn value_unchecked(&self, i: usize) -> T {
222
*self.values.get_unchecked(i)
223
}
224
225
// /// Returns the element at index `i` or `None` if it is null
226
// /// # Panics
227
// /// iff `i >= self.len()`
228
// #[inline]
229
// pub fn get(&self, i: usize) -> Option<T> {
230
// if !self.is_null(i) {
231
// // soundness: Array::is_null panics if i >= self.len
232
// unsafe { Some(self.value_unchecked(i)) }
233
// } else {
234
// None
235
// }
236
// }
237
238
/// Slices this [`PrimitiveArray`] by an offset and length.
239
/// # Implementation
240
/// This operation is `O(1)`.
241
#[inline]
242
pub fn slice(&mut self, offset: usize, length: usize) {
243
assert!(
244
offset + length <= self.len(),
245
"offset + length may not exceed length of array"
246
);
247
unsafe { self.slice_unchecked(offset, length) }
248
}
249
250
/// Slices this [`PrimitiveArray`] by an offset and length.
251
/// # Implementation
252
/// This operation is `O(1)`.
253
///
254
/// # Safety
255
/// The caller must ensure that `offset + length <= self.len()`.
256
#[inline]
257
pub unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
258
self.validity = self
259
.validity
260
.take()
261
.map(|bitmap| bitmap.sliced_unchecked(offset, length))
262
.filter(|bitmap| bitmap.unset_bits() > 0);
263
self.values.slice_unchecked(offset, length);
264
}
265
266
impl_sliced!();
267
impl_mut_validity!();
268
impl_into_array!();
269
270
/// Returns this [`PrimitiveArray`] with new values.
271
/// # Panics
272
/// This function panics iff `values.len() != self.len()`.
273
#[must_use]
274
pub fn with_values(mut self, values: Buffer<T>) -> Self {
275
self.set_values(values);
276
self
277
}
278
279
/// Update the values of this [`PrimitiveArray`].
280
/// # Panics
281
/// This function panics iff `values.len() != self.len()`.
282
pub fn set_values(&mut self, values: Buffer<T>) {
283
assert_eq!(
284
values.len(),
285
self.len(),
286
"values' length must be equal to this arrays' length"
287
);
288
self.values = values;
289
}
290
291
/// Applies a function `f` to the validity of this array.
292
///
293
/// This is an API to leverage clone-on-write
294
/// # Panics
295
/// This function panics if the function `f` modifies the length of the [`Bitmap`].
296
pub fn apply_validity<F: FnOnce(Bitmap) -> Bitmap>(&mut self, f: F) {
297
if let Some(validity) = std::mem::take(&mut self.validity) {
298
self.set_validity(Some(f(validity)))
299
}
300
}
301
302
/// Returns an option of a mutable reference to the values of this [`PrimitiveArray`].
303
pub fn get_mut_values(&mut self) -> Option<&mut [T]> {
304
self.values.get_mut_slice()
305
}
306
307
/// Returns its internal representation
308
#[must_use]
309
pub fn into_inner(self) -> (ArrowDataType, Buffer<T>, Option<Bitmap>) {
310
let Self {
311
dtype,
312
values,
313
validity,
314
} = self;
315
(dtype, values, validity)
316
}
317
318
/// Creates a [`PrimitiveArray`] from its internal representation.
319
/// This is the inverted from [`PrimitiveArray::into_inner`]
320
pub fn from_inner(
321
dtype: ArrowDataType,
322
values: Buffer<T>,
323
validity: Option<Bitmap>,
324
) -> PolarsResult<Self> {
325
check(&dtype, &values, validity.as_ref().map(|v| v.len()))?;
326
Ok(unsafe { Self::from_inner_unchecked(dtype, values, validity) })
327
}
328
329
/// Creates a [`PrimitiveArray`] from its internal representation.
330
/// This is the inverted from [`PrimitiveArray::into_inner`]
331
///
332
/// # Safety
333
/// Callers must ensure all invariants of this struct are upheld.
334
pub unsafe fn from_inner_unchecked(
335
dtype: ArrowDataType,
336
values: Buffer<T>,
337
validity: Option<Bitmap>,
338
) -> Self {
339
Self {
340
dtype,
341
values,
342
validity,
343
}
344
}
345
346
/// Try to convert this [`PrimitiveArray`] to a [`MutablePrimitiveArray`] via copy-on-write semantics.
347
///
348
/// A [`PrimitiveArray`] is backed by a [`Buffer`] and [`Bitmap`] which are essentially `Arc<Vec<_>>`.
349
/// This function returns a [`MutablePrimitiveArray`] (via [`std::sync::Arc::get_mut`]) iff both values
350
/// and validity have not been cloned / are unique references to their underlying vectors.
351
///
352
/// This function is primarily used to reuse memory regions.
353
#[must_use]
354
pub fn into_mut(self) -> Either<Self, MutablePrimitiveArray<T>> {
355
use Either::*;
356
357
if let Some(bitmap) = self.validity {
358
match bitmap.into_mut() {
359
Left(bitmap) => Left(PrimitiveArray::new(self.dtype, self.values, Some(bitmap))),
360
Right(mutable_bitmap) => match self.values.into_mut() {
361
Right(values) => Right(
362
MutablePrimitiveArray::try_new(self.dtype, values, Some(mutable_bitmap))
363
.unwrap(),
364
),
365
Left(values) => Left(PrimitiveArray::new(
366
self.dtype,
367
values,
368
Some(mutable_bitmap.into()),
369
)),
370
},
371
}
372
} else {
373
match self.values.into_mut() {
374
Right(values) => {
375
Right(MutablePrimitiveArray::try_new(self.dtype, values, None).unwrap())
376
},
377
Left(values) => Left(PrimitiveArray::new(self.dtype, values, None)),
378
}
379
}
380
}
381
382
/// Returns a new empty (zero-length) [`PrimitiveArray`].
383
pub fn new_empty(dtype: ArrowDataType) -> Self {
384
Self::new(dtype, Buffer::new(), None)
385
}
386
387
/// Returns a new [`PrimitiveArray`] where all slots are null / `None`.
388
#[inline]
389
pub fn new_null(dtype: ArrowDataType, length: usize) -> Self {
390
Self::new(
391
dtype,
392
vec![T::default(); length].into(),
393
Some(Bitmap::new_zeroed(length)),
394
)
395
}
396
397
/// Creates a (non-null) [`PrimitiveArray`] from an iterator of values.
398
/// # Implementation
399
/// This does not assume that the iterator has a known length.
400
pub fn from_values<I: IntoIterator<Item = T>>(iter: I) -> Self {
401
Self::new(T::PRIMITIVE.into(), Vec::<T>::from_iter(iter).into(), None)
402
}
403
404
/// Creates a (non-null) [`PrimitiveArray`] from a slice of values.
405
/// # Implementation
406
/// This is essentially a memcopy and is thus `O(N)`
407
pub fn from_slice<P: AsRef<[T]>>(slice: P) -> Self {
408
Self::new(
409
T::PRIMITIVE.into(),
410
Vec::<T>::from(slice.as_ref()).into(),
411
None,
412
)
413
}
414
415
/// Creates a (non-null) [`PrimitiveArray`] from a [`TrustedLen`] of values.
416
/// # Implementation
417
/// This does not assume that the iterator has a known length.
418
pub fn from_trusted_len_values_iter<I: TrustedLen<Item = T>>(iter: I) -> Self {
419
MutablePrimitiveArray::<T>::from_trusted_len_values_iter(iter).into()
420
}
421
422
/// Creates a new [`PrimitiveArray`] from an iterator over values
423
///
424
/// # Safety
425
/// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
426
/// I.e. that `size_hint().1` correctly reports its length.
427
pub unsafe fn from_trusted_len_values_iter_unchecked<I: Iterator<Item = T>>(iter: I) -> Self {
428
MutablePrimitiveArray::<T>::from_trusted_len_values_iter_unchecked(iter).into()
429
}
430
431
/// Creates a [`PrimitiveArray`] from a [`TrustedLen`] of optional values.
432
pub fn from_trusted_len_iter<I: TrustedLen<Item = Option<T>>>(iter: I) -> Self {
433
MutablePrimitiveArray::<T>::from_trusted_len_iter(iter).into()
434
}
435
436
/// Creates a [`PrimitiveArray`] from an iterator of optional values.
437
///
438
/// # Safety
439
/// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
440
/// I.e. that `size_hint().1` correctly reports its length.
441
pub unsafe fn from_trusted_len_iter_unchecked<I: Iterator<Item = Option<T>>>(iter: I) -> Self {
442
MutablePrimitiveArray::<T>::from_trusted_len_iter_unchecked(iter).into()
443
}
444
445
/// Alias for `Self::try_new(..).unwrap()`.
446
/// # Panics
447
/// This function errors iff:
448
/// * The validity is not `None` and its length is different from `values`'s length
449
/// * The `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive`].
450
pub fn new(dtype: ArrowDataType, values: Buffer<T>, validity: Option<Bitmap>) -> Self {
451
Self::try_new(dtype, values, validity).unwrap()
452
}
453
454
/// Transmute this PrimitiveArray into another PrimitiveArray.
455
///
456
/// T and U must have the same size and alignment.
457
pub fn transmute<U: NativeType>(self) -> PrimitiveArray<U> {
458
let PrimitiveArray {
459
values, validity, ..
460
} = self;
461
PrimitiveArray::new(
462
U::PRIMITIVE.into(),
463
Buffer::try_transmute::<U>(values).unwrap(),
464
validity,
465
)
466
}
467
468
/// Fills this entire array with the given value, leaving the validity mask intact.
469
///
470
/// Reuses the memory of the PrimitiveArray if possible.
471
pub fn fill_with(mut self, value: T) -> Self {
472
if let Some(values) = self.get_mut_values() {
473
for x in values.iter_mut() {
474
*x = value;
475
}
476
self
477
} else {
478
let values = vec![value; self.len()];
479
Self::new(T::PRIMITIVE.into(), values.into(), self.validity)
480
}
481
}
482
}
483
484
impl<T: NativeType> Array for PrimitiveArray<T> {
485
impl_common_array!();
486
487
fn validity(&self) -> Option<&Bitmap> {
488
self.validity.as_ref()
489
}
490
491
#[inline]
492
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
493
Box::new(self.clone().with_validity(validity))
494
}
495
}
496
497
impl<T: NativeType> Splitable for PrimitiveArray<T> {
498
#[inline(always)]
499
fn check_bound(&self, offset: usize) -> bool {
500
offset <= self.len()
501
}
502
503
unsafe fn _split_at_unchecked(&self, offset: usize) -> (Self, Self) {
504
let (lhs_values, rhs_values) = unsafe { self.values.split_at_unchecked(offset) };
505
let (lhs_validity, rhs_validity) = unsafe { self.validity.split_at_unchecked(offset) };
506
507
(
508
Self {
509
dtype: self.dtype.clone(),
510
values: lhs_values,
511
validity: lhs_validity,
512
},
513
Self {
514
dtype: self.dtype.clone(),
515
values: rhs_values,
516
validity: rhs_validity,
517
},
518
)
519
}
520
}
521
522
impl<T: NativeType> SliceAble for PrimitiveArray<T> {
523
unsafe fn slice_unchecked(&self, range: Range<usize>) -> Self {
524
self.clone().sliced_unchecked(range.start, range.len())
525
}
526
527
fn slice(&self, range: Range<usize>) -> Self {
528
self.clone().sliced(range.start, range.len())
529
}
530
}
531
532
impl<T: NativeType> Indexable for PrimitiveArray<T> {
533
type Item = Option<T>;
534
535
fn get(&self, i: usize) -> Self::Item {
536
if !self.is_null(i) {
537
// soundness: Array::is_null panics if i >= self.len
538
unsafe { Some(self.value_unchecked(i)) }
539
} else {
540
None
541
}
542
}
543
544
unsafe fn get_unchecked(&self, i: usize) -> Self::Item {
545
if !self.is_null_unchecked(i) {
546
Some(self.value_unchecked(i))
547
} else {
548
None
549
}
550
}
551
}
552
553
/// A type definition [`PrimitiveArray`] for `i8`
554
pub type Int8Array = PrimitiveArray<i8>;
555
/// A type definition [`PrimitiveArray`] for `i16`
556
pub type Int16Array = PrimitiveArray<i16>;
557
/// A type definition [`PrimitiveArray`] for `i32`
558
pub type Int32Array = PrimitiveArray<i32>;
559
/// A type definition [`PrimitiveArray`] for `i64`
560
pub type Int64Array = PrimitiveArray<i64>;
561
/// A type definition [`PrimitiveArray`] for `i128`
562
pub type Int128Array = PrimitiveArray<i128>;
563
/// A type definition [`PrimitiveArray`] for `i256`
564
pub type Int256Array = PrimitiveArray<i256>;
565
/// A type definition [`PrimitiveArray`] for [`days_ms`]
566
pub type DaysMsArray = PrimitiveArray<days_ms>;
567
/// A type definition [`PrimitiveArray`] for [`months_days_ns`]
568
pub type MonthsDaysNsArray = PrimitiveArray<months_days_ns>;
569
/// A type definition [`PrimitiveArray`] for `f16`
570
pub type Float16Array = PrimitiveArray<f16>;
571
/// A type definition [`PrimitiveArray`] for `f32`
572
pub type Float32Array = PrimitiveArray<f32>;
573
/// A type definition [`PrimitiveArray`] for `f64`
574
pub type Float64Array = PrimitiveArray<f64>;
575
/// A type definition [`PrimitiveArray`] for `u8`
576
pub type UInt8Array = PrimitiveArray<u8>;
577
/// A type definition [`PrimitiveArray`] for `u16`
578
pub type UInt16Array = PrimitiveArray<u16>;
579
/// A type definition [`PrimitiveArray`] for `u32`
580
pub type UInt32Array = PrimitiveArray<u32>;
581
/// A type definition [`PrimitiveArray`] for `u64`
582
pub type UInt64Array = PrimitiveArray<u64>;
583
584
/// A type definition [`MutablePrimitiveArray`] for `i8`
585
pub type Int8Vec = MutablePrimitiveArray<i8>;
586
/// A type definition [`MutablePrimitiveArray`] for `i16`
587
pub type Int16Vec = MutablePrimitiveArray<i16>;
588
/// A type definition [`MutablePrimitiveArray`] for `i32`
589
pub type Int32Vec = MutablePrimitiveArray<i32>;
590
/// A type definition [`MutablePrimitiveArray`] for `i64`
591
pub type Int64Vec = MutablePrimitiveArray<i64>;
592
/// A type definition [`MutablePrimitiveArray`] for `i128`
593
pub type Int128Vec = MutablePrimitiveArray<i128>;
594
/// A type definition [`MutablePrimitiveArray`] for `i256`
595
pub type Int256Vec = MutablePrimitiveArray<i256>;
596
/// A type definition [`MutablePrimitiveArray`] for [`days_ms`]
597
pub type DaysMsVec = MutablePrimitiveArray<days_ms>;
598
/// A type definition [`MutablePrimitiveArray`] for [`months_days_ns`]
599
pub type MonthsDaysNsVec = MutablePrimitiveArray<months_days_ns>;
600
/// A type definition [`MutablePrimitiveArray`] for `f16`
601
pub type Float16Vec = MutablePrimitiveArray<f16>;
602
/// A type definition [`MutablePrimitiveArray`] for `f32`
603
pub type Float32Vec = MutablePrimitiveArray<f32>;
604
/// A type definition [`MutablePrimitiveArray`] for `f64`
605
pub type Float64Vec = MutablePrimitiveArray<f64>;
606
/// A type definition [`MutablePrimitiveArray`] for `u8`
607
pub type UInt8Vec = MutablePrimitiveArray<u8>;
608
/// A type definition [`MutablePrimitiveArray`] for `u16`
609
pub type UInt16Vec = MutablePrimitiveArray<u16>;
610
/// A type definition [`MutablePrimitiveArray`] for `u32`
611
pub type UInt32Vec = MutablePrimitiveArray<u32>;
612
/// A type definition [`MutablePrimitiveArray`] for `u64`
613
pub type UInt64Vec = MutablePrimitiveArray<u64>;
614
615
impl<T: NativeType> Default for PrimitiveArray<T> {
616
fn default() -> Self {
617
PrimitiveArray::new(T::PRIMITIVE.into(), Default::default(), None)
618
}
619
}
620
621
impl<T: NativeType> Bounded for PrimitiveArray<T> {
622
fn len(&self) -> usize {
623
self.values.len()
624
}
625
}
626
627
impl<T: NativeType> NullCount for PrimitiveArray<T> {
628
fn null_count(&self) -> usize {
629
<Self as Array>::null_count(self)
630
}
631
}
632
633