polars_arrow/bitmap/utils/chunk_iterator/
chunks_exact.rs1use std::slice::ChunksExact;
2
3use super::{BitChunk, BitChunkIterExact};
4use crate::trusted_len::TrustedLen;
5
6#[derive(Debug)]
8pub struct BitChunksExact<'a, T: BitChunk> {
9 iter: ChunksExact<'a, u8>,
10 remainder: &'a [u8],
11 remainder_len: usize,
12 phantom: std::marker::PhantomData<T>,
13}
14
15impl<'a, T: BitChunk> BitChunksExact<'a, T> {
16 #[inline]
18 pub fn new(bitmap: &'a [u8], length: usize) -> Self {
19 assert!(length <= bitmap.len() * 8);
20 let size_of = size_of::<T>();
21
22 let bitmap = &bitmap[..length.saturating_add(7) / 8];
23
24 let split = (length / 8 / size_of) * size_of;
25 let (chunks, remainder) = bitmap.split_at(split);
26 let remainder_len = length - chunks.len() * 8;
27 let iter = chunks.chunks_exact(size_of);
28
29 Self {
30 iter,
31 remainder,
32 remainder_len,
33 phantom: std::marker::PhantomData,
34 }
35 }
36
37 #[inline]
39 pub fn len(&self) -> usize {
40 self.iter.len()
41 }
42
43 #[inline]
45 pub fn is_empty(&self) -> bool {
46 self.len() == 0
47 }
48
49 #[inline]
51 pub fn remainder(&self) -> T {
52 let remainder_bytes = self.remainder;
53 if remainder_bytes.is_empty() {
54 return T::zero();
55 }
56 let remainder = match remainder_bytes.try_into() {
57 Ok(a) => a,
58 Err(_) => {
59 let mut remainder = T::zero().to_ne_bytes();
60 remainder_bytes
61 .iter()
62 .enumerate()
63 .for_each(|(index, b)| remainder[index] = *b);
64 remainder
65 },
66 };
67 T::from_ne_bytes(remainder)
68 }
69}
70
71impl<T: BitChunk> Iterator for BitChunksExact<'_, T> {
72 type Item = T;
73
74 #[inline]
75 fn next(&mut self) -> Option<Self::Item> {
76 self.iter.next().map(|x| match x.try_into() {
77 Ok(a) => T::from_ne_bytes(a),
78 Err(_) => unreachable!(),
79 })
80 }
81
82 #[inline]
83 fn size_hint(&self) -> (usize, Option<usize>) {
84 self.iter.size_hint()
85 }
86}
87
88unsafe impl<T: BitChunk> TrustedLen for BitChunksExact<'_, T> {}
89
90impl<T: BitChunk> BitChunkIterExact<T> for BitChunksExact<'_, T> {
91 #[inline]
92 fn remainder(&self) -> T {
93 self.remainder()
94 }
95
96 #[inline]
97 fn remainder_len(&self) -> usize {
98 self.remainder_len
99 }
100}