arrow2/bitmap/utils/
mod.rs1mod chunk_iterator;
3mod chunks_exact_mut;
4mod fmt;
5mod iterator;
6mod slice_iterator;
7mod zip_validity;
8
9use std::convert::TryInto;
10
11pub(crate) use chunk_iterator::merge_reversed;
12pub use chunk_iterator::{BitChunk, BitChunkIterExact, BitChunks, BitChunksExact};
13pub use chunks_exact_mut::BitChunksExactMut;
14pub use fmt::fmt;
15pub use iterator::BitmapIter;
16pub use slice_iterator::SlicesIterator;
17pub use zip_validity::{ZipValidity, ZipValidityIter};
18
19const BIT_MASK: [u8; 8] = [1, 2, 4, 8, 16, 32, 64, 128];
20const UNSET_BIT_MASK: [u8; 8] = [
21 255 - 1,
22 255 - 2,
23 255 - 4,
24 255 - 8,
25 255 - 16,
26 255 - 32,
27 255 - 64,
28 255 - 128,
29];
30
31#[inline]
33pub fn is_set(byte: u8, i: usize) -> bool {
34 (byte & BIT_MASK[i]) != 0
35}
36
37#[inline]
39pub fn set(byte: u8, i: usize, value: bool) -> u8 {
40 if value {
41 byte | BIT_MASK[i]
42 } else {
43 byte & UNSET_BIT_MASK[i]
44 }
45}
46
47#[inline]
51pub fn set_bit(data: &mut [u8], i: usize, value: bool) {
52 data[i / 8] = set(data[i / 8], i % 8, value);
53}
54
55#[inline]
59pub unsafe fn set_bit_unchecked(data: &mut [u8], i: usize, value: bool) {
60 let byte = data.get_unchecked_mut(i / 8);
61 *byte = set(*byte, i % 8, value);
62}
63
64#[inline]
68pub fn get_bit(bytes: &[u8], i: usize) -> bool {
69 is_set(bytes[i / 8], i % 8)
70}
71
72#[inline]
77pub unsafe fn get_bit_unchecked(data: &[u8], i: usize) -> bool {
78 (*data.as_ptr().add(i >> 3) & BIT_MASK[i & 7]) != 0
79}
80
81#[inline]
83pub fn bytes_for(bits: usize) -> usize {
84 bits.saturating_add(7) / 8
85}
86
87pub fn count_zeros(slice: &[u8], offset: usize, len: usize) -> usize {
92 if len == 0 {
93 return 0;
94 };
95
96 let mut slice = &slice[offset / 8..(offset + len).saturating_add(7) / 8];
97 let offset = offset % 8;
98
99 if (offset + len) / 8 == 0 {
100 let byte = (slice[0] >> offset) << (8 - len);
102 return len - byte.count_ones() as usize;
103 }
104
105 let mut set_count = 0;
110 if offset != 0 {
111 set_count += (slice[0] >> offset).count_ones() as usize;
114 slice = &slice[1..];
115 }
116 if (offset + len) % 8 != 0 {
117 let end_offset = (offset + len) % 8; let last_index = slice.len() - 1;
119 set_count += (slice[last_index] << (8 - end_offset)).count_ones() as usize;
122 slice = &slice[..last_index];
123 }
124
125 let mut chunks = slice.chunks_exact(8);
127 set_count += chunks
128 .by_ref()
129 .map(|chunk| {
130 let a = u64::from_ne_bytes(chunk.try_into().unwrap());
131 a.count_ones() as usize
132 })
133 .sum::<usize>();
134
135 set_count += chunks
137 .remainder()
138 .iter()
139 .map(|byte| byte.count_ones() as usize)
140 .sum::<usize>();
141
142 len - set_count
143}