Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-parquet/src/arrow/read/deserialize/utils/array_chunks.rs
8431 views
1
use arrow::types::AlignedBytes;
2
3
/// A slice of chunks that fit an [`AlignedBytes`] type.
4
///
5
/// This is essentially the equivalent of [`ChunksExact`][std::slice::ChunksExact], but with a size
6
/// and type known at compile-time. This makes the compiler able to reason much more about the
7
/// code. Especially, since the chunk-sizes for this type are almost always powers of 2 and
8
/// bitshifts or special instructions would be much better to use.
9
#[derive(Debug, Clone, Copy)]
10
pub(crate) struct ArrayChunks<'a, B: AlignedBytes> {
11
pub(crate) bytes: &'a [B::Unaligned],
12
}
13
14
impl<'a, B: AlignedBytes> ArrayChunks<'a, B> {
15
/// Create a new [`ArrayChunks`]
16
///
17
/// This returns null if the `bytes` slice's length is not a multiple of the size of `P::Bytes`.
18
pub(crate) fn new(bytes: &'a [u8]) -> Option<Self> {
19
if !bytes.len().is_multiple_of(B::SIZE) {
20
return None;
21
}
22
23
let bytes = bytemuck::cast_slice(bytes);
24
25
Some(Self { bytes })
26
}
27
28
pub(crate) unsafe fn get_unchecked(&self, at: usize) -> B {
29
B::from_unaligned(*unsafe { self.bytes.get_unchecked(at) })
30
}
31
32
pub fn truncate(&self, length: usize) -> ArrayChunks<'a, B> {
33
let length = length.min(self.bytes.len());
34
35
Self {
36
bytes: unsafe { self.bytes.get_unchecked(..length) },
37
}
38
}
39
40
pub fn slice(&self, start: usize, length: usize) -> ArrayChunks<'a, B> {
41
assert!(start <= self.bytes.len());
42
assert!(start + length <= self.bytes.len());
43
unsafe { self.slice_unchecked(start, length) }
44
}
45
46
pub unsafe fn slice_unchecked(&self, start: usize, length: usize) -> ArrayChunks<'a, B> {
47
debug_assert!(start <= self.bytes.len());
48
debug_assert!(start + length <= self.bytes.len());
49
Self {
50
bytes: unsafe { self.bytes.get_unchecked(start..start + length) },
51
}
52
}
53
54
pub fn as_ptr(&self) -> *const B::Unaligned {
55
self.bytes.as_ptr()
56
}
57
58
pub fn is_empty(&self) -> bool {
59
self.len() == 0
60
}
61
}
62
63
impl<'a, B: AlignedBytes> Iterator for ArrayChunks<'a, B> {
64
type Item = &'a B::Unaligned;
65
66
#[inline(always)]
67
fn next(&mut self) -> Option<Self::Item> {
68
let item = self.bytes.first()?;
69
self.bytes = &self.bytes[1..];
70
Some(item)
71
}
72
73
#[inline(always)]
74
fn size_hint(&self) -> (usize, Option<usize>) {
75
(self.bytes.len(), Some(self.bytes.len()))
76
}
77
}
78
79
impl<B: AlignedBytes> ExactSizeIterator for ArrayChunks<'_, B> {}
80
81