Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-arrow/src/array/iterator.rs
6939 views
1
use crate::bitmap::Bitmap;
2
use crate::bitmap::iterator::TrueIdxIter;
3
use crate::trusted_len::TrustedLen;
4
5
mod private {
6
pub trait Sealed {}
7
8
impl<'a, T: super::ArrayAccessor<'a> + ?Sized> Sealed for T {}
9
}
10
11
/// Sealed trait representing access to a value of an array.
12
/// # Safety
13
/// Implementers of this trait guarantee that
14
/// `value_unchecked` is safe when called up to `len`
15
pub unsafe trait ArrayAccessor<'a>: private::Sealed {
16
type Item: 'a;
17
/// # Safety
18
/// The index must be in-bounds in the array.
19
unsafe fn value_unchecked(&'a self, index: usize) -> Self::Item;
20
fn len(&self) -> usize;
21
}
22
23
/// Iterator of values of an [`ArrayAccessor`].
24
#[derive(Debug, Clone)]
25
pub struct ArrayValuesIter<'a, A: ArrayAccessor<'a>> {
26
array: &'a A,
27
index: usize,
28
end: usize,
29
}
30
31
impl<'a, A: ArrayAccessor<'a>> ArrayValuesIter<'a, A> {
32
/// Creates a new [`ArrayValuesIter`]
33
#[inline]
34
pub fn new(array: &'a A) -> Self {
35
Self {
36
array,
37
index: 0,
38
end: array.len(),
39
}
40
}
41
}
42
43
impl<'a, A: ArrayAccessor<'a>> Iterator for ArrayValuesIter<'a, A> {
44
type Item = A::Item;
45
46
#[inline]
47
fn next(&mut self) -> Option<Self::Item> {
48
if self.index == self.end {
49
return None;
50
}
51
let old = self.index;
52
self.index += 1;
53
Some(unsafe { self.array.value_unchecked(old) })
54
}
55
56
#[inline]
57
fn size_hint(&self) -> (usize, Option<usize>) {
58
(self.end - self.index, Some(self.end - self.index))
59
}
60
61
#[inline]
62
fn nth(&mut self, n: usize) -> Option<Self::Item> {
63
let new_index = self.index + n;
64
if new_index > self.end {
65
self.index = self.end;
66
None
67
} else {
68
self.index = new_index;
69
self.next()
70
}
71
}
72
}
73
74
impl<'a, A: ArrayAccessor<'a>> DoubleEndedIterator for ArrayValuesIter<'a, A> {
75
#[inline]
76
fn next_back(&mut self) -> Option<Self::Item> {
77
if self.index == self.end {
78
None
79
} else {
80
self.end -= 1;
81
Some(unsafe { self.array.value_unchecked(self.end) })
82
}
83
}
84
}
85
86
unsafe impl<'a, A: ArrayAccessor<'a>> TrustedLen for ArrayValuesIter<'a, A> {}
87
impl<'a, A: ArrayAccessor<'a>> ExactSizeIterator for ArrayValuesIter<'a, A> {}
88
89
pub struct NonNullValuesIter<'a, A: ?Sized> {
90
accessor: &'a A,
91
idxs: TrueIdxIter<'a>,
92
}
93
94
impl<'a, A: ArrayAccessor<'a> + ?Sized> NonNullValuesIter<'a, A> {
95
pub fn new(accessor: &'a A, validity: Option<&'a Bitmap>) -> Self {
96
Self {
97
idxs: TrueIdxIter::new(accessor.len(), validity),
98
accessor,
99
}
100
}
101
}
102
103
impl<'a, A: ArrayAccessor<'a> + ?Sized> Iterator for NonNullValuesIter<'a, A> {
104
type Item = A::Item;
105
106
#[inline]
107
fn next(&mut self) -> Option<Self::Item> {
108
if let Some(i) = self.idxs.next() {
109
return Some(unsafe { self.accessor.value_unchecked(i) });
110
}
111
None
112
}
113
114
fn size_hint(&self) -> (usize, Option<usize>) {
115
self.idxs.size_hint()
116
}
117
}
118
119
unsafe impl<'a, A: ArrayAccessor<'a> + ?Sized> TrustedLen for NonNullValuesIter<'a, A> {}
120
121
impl<A: ?Sized> Clone for NonNullValuesIter<'_, A> {
122
fn clone(&self) -> Self {
123
Self {
124
accessor: self.accessor,
125
idxs: self.idxs.clone(),
126
}
127
}
128
}
129
130