Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-arrow/src/array/indexable.rs
6939 views
1
#![allow(unsafe_op_in_unsafe_fn)]
2
use std::borrow::Borrow;
3
4
use crate::array::{
5
MutableArray, MutableBinaryArray, MutableBinaryValuesArray, MutableBinaryViewArray,
6
MutableBooleanArray, MutableFixedSizeBinaryArray, MutablePrimitiveArray, MutableUtf8Array,
7
MutableUtf8ValuesArray, ViewType,
8
};
9
use crate::offset::Offset;
10
use crate::types::NativeType;
11
12
/// Trait for arrays that can be indexed directly to extract a value.
13
pub trait Indexable {
14
/// The type of the element at index `i`; may be a reference type or a value type.
15
type Value<'a>: Borrow<Self::Type>
16
where
17
Self: 'a;
18
19
type Type: ?Sized;
20
21
/// Returns the element at index `i`.
22
/// # Panic
23
/// May panic if `i >= self.len()`.
24
fn value_at(&self, index: usize) -> Self::Value<'_>;
25
26
/// Returns the element at index `i`.
27
///
28
/// # Safety
29
/// Assumes that the `i < self.len`.
30
#[inline]
31
unsafe fn value_unchecked_at(&self, index: usize) -> Self::Value<'_> {
32
self.value_at(index)
33
}
34
}
35
36
pub trait AsIndexed<M: Indexable> {
37
fn as_indexed(&self) -> &M::Type;
38
}
39
40
impl Indexable for MutableBooleanArray {
41
type Value<'a> = bool;
42
type Type = bool;
43
44
#[inline]
45
fn value_at(&self, i: usize) -> Self::Value<'_> {
46
self.values().get(i)
47
}
48
}
49
50
impl AsIndexed<MutableBooleanArray> for bool {
51
#[inline]
52
fn as_indexed(&self) -> &bool {
53
self
54
}
55
}
56
57
impl<O: Offset> Indexable for MutableBinaryArray<O> {
58
type Value<'a> = &'a [u8];
59
type Type = [u8];
60
61
#[inline]
62
fn value_at(&self, i: usize) -> Self::Value<'_> {
63
// TODO: add .value() / .value_unchecked() to MutableBinaryArray?
64
assert!(i < self.len());
65
unsafe { self.value_unchecked_at(i) }
66
}
67
68
#[inline]
69
unsafe fn value_unchecked_at(&self, i: usize) -> Self::Value<'_> {
70
// TODO: add .value() / .value_unchecked() to MutableBinaryArray?
71
// soundness: the invariant of the function
72
let (start, end) = self.offsets().start_end_unchecked(i);
73
// soundness: the invariant of the struct
74
self.values().get_unchecked(start..end)
75
}
76
}
77
78
impl<O: Offset> AsIndexed<MutableBinaryArray<O>> for &[u8] {
79
#[inline]
80
fn as_indexed(&self) -> &[u8] {
81
self
82
}
83
}
84
85
impl<O: Offset> Indexable for MutableBinaryValuesArray<O> {
86
type Value<'a> = &'a [u8];
87
type Type = [u8];
88
89
#[inline]
90
fn value_at(&self, i: usize) -> Self::Value<'_> {
91
self.value(i)
92
}
93
94
#[inline]
95
unsafe fn value_unchecked_at(&self, i: usize) -> Self::Value<'_> {
96
self.value_unchecked(i)
97
}
98
}
99
100
impl<O: Offset> AsIndexed<MutableBinaryValuesArray<O>> for &[u8] {
101
#[inline]
102
fn as_indexed(&self) -> &[u8] {
103
self
104
}
105
}
106
107
impl Indexable for MutableFixedSizeBinaryArray {
108
type Value<'a> = &'a [u8];
109
type Type = [u8];
110
111
#[inline]
112
fn value_at(&self, i: usize) -> Self::Value<'_> {
113
self.value(i)
114
}
115
116
#[inline]
117
unsafe fn value_unchecked_at(&self, i: usize) -> Self::Value<'_> {
118
// soundness: the invariant of the struct
119
self.value_unchecked(i)
120
}
121
}
122
123
impl AsIndexed<MutableFixedSizeBinaryArray> for &[u8] {
124
#[inline]
125
fn as_indexed(&self) -> &[u8] {
126
self
127
}
128
}
129
130
impl<T: ViewType + ?Sized> Indexable for MutableBinaryViewArray<T> {
131
type Value<'a> = &'a T;
132
type Type = T;
133
134
fn value_at(&self, index: usize) -> Self::Value<'_> {
135
self.value(index)
136
}
137
138
unsafe fn value_unchecked_at(&self, index: usize) -> Self::Value<'_> {
139
self.value_unchecked(index)
140
}
141
}
142
143
impl<T: ViewType + ?Sized> AsIndexed<MutableBinaryViewArray<T>> for &T {
144
#[inline]
145
fn as_indexed(&self) -> &T {
146
self
147
}
148
}
149
150
// TODO: should NativeType derive from Hash?
151
impl<T: NativeType> Indexable for MutablePrimitiveArray<T> {
152
type Value<'a> = T;
153
type Type = T;
154
155
#[inline]
156
fn value_at(&self, i: usize) -> Self::Value<'_> {
157
assert!(i < self.len());
158
// TODO: add Length trait? (for both Array and MutableArray)
159
unsafe { self.value_unchecked_at(i) }
160
}
161
162
#[inline]
163
unsafe fn value_unchecked_at(&self, i: usize) -> Self::Value<'_> {
164
*self.values().get_unchecked(i)
165
}
166
}
167
168
impl<T: NativeType> AsIndexed<MutablePrimitiveArray<T>> for T {
169
#[inline]
170
fn as_indexed(&self) -> &T {
171
self
172
}
173
}
174
175
impl<O: Offset> Indexable for MutableUtf8Array<O> {
176
type Value<'a> = &'a str;
177
type Type = str;
178
179
#[inline]
180
fn value_at(&self, i: usize) -> Self::Value<'_> {
181
self.value(i)
182
}
183
184
#[inline]
185
unsafe fn value_unchecked_at(&self, i: usize) -> Self::Value<'_> {
186
self.value_unchecked(i)
187
}
188
}
189
190
impl<O: Offset, V: AsRef<str>> AsIndexed<MutableUtf8Array<O>> for V {
191
#[inline]
192
fn as_indexed(&self) -> &str {
193
self.as_ref()
194
}
195
}
196
197
impl<O: Offset> Indexable for MutableUtf8ValuesArray<O> {
198
type Value<'a> = &'a str;
199
type Type = str;
200
201
#[inline]
202
fn value_at(&self, i: usize) -> Self::Value<'_> {
203
self.value(i)
204
}
205
206
#[inline]
207
unsafe fn value_unchecked_at(&self, i: usize) -> Self::Value<'_> {
208
self.value_unchecked(i)
209
}
210
}
211
212
impl<O: Offset, V: AsRef<str>> AsIndexed<MutableUtf8ValuesArray<O>> for V {
213
#[inline]
214
fn as_indexed(&self) -> &str {
215
self.as_ref()
216
}
217
}
218
219