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