Skip to main content

narrow/bitmap/
mod.rs

1//! A collection of bits.
2
3use crate::{
4    Index, Length,
5    buffer::{Buffer, BufferMut, BufferRef, BufferRefMut, BufferType, VecBuffer},
6};
7use std::{
8    any,
9    borrow::Borrow,
10    fmt::{Debug, Formatter, Result},
11    ops,
12};
13
14mod iter;
15use self::iter::{BitPackedExt, BitUnpackedExt};
16pub use self::iter::{BitmapIntoIter, BitmapIter};
17
18mod fmt;
19use self::fmt::BitsDisplayExt;
20
21mod validity;
22pub use self::validity::ValidityBitmap;
23
24/// An immutable reference to a bitmap.
25pub trait BitmapRef {
26    /// The buffer type of the bitmap.
27    type Buffer: BufferType;
28
29    /// Returns a reference to an immutable [Bitmap].
30    fn bitmap_ref(&self) -> &Bitmap<Self::Buffer>;
31}
32
33/// A mutable reference to a bitmap.
34pub trait BitmapRefMut: BitmapRef {
35    /// Returns a mutable reference to a [Bitmap].
36    fn bitmap_ref_mut(&mut self) -> &mut Bitmap<Self::Buffer>;
37}
38
39/// A collection of bits.
40///
41/// The validity bits are stored LSB-first in the bytes of the `Buffer`.
42// todo(mb): implement ops
43pub struct Bitmap<Buffer: BufferType = VecBuffer> {
44    /// The bits are stored in this buffer of bytes.
45    pub(crate) buffer: <Buffer as BufferType>::Buffer<u8>,
46
47    /// The number of bits stored in the bitmap.
48    pub(crate) bits: usize,
49
50    /// An offset (in number of bits) in the buffer. This enables zero-copy
51    /// slicing of the bitmap on non-byte boundaries.
52    pub(crate) offset: usize,
53}
54
55impl<Buffer: BufferType> BitmapRef for Bitmap<Buffer> {
56    type Buffer = Buffer;
57
58    fn bitmap_ref(&self) -> &Bitmap<Self::Buffer> {
59        self
60    }
61}
62
63impl<Buffer: BufferType> Bitmap<Buffer> {
64    /// Returns an iterator over the bits in this [`Bitmap`].
65    pub fn iter(&self) -> BitmapIter<'_> {
66        <&Self as IntoIterator>::into_iter(self)
67    }
68
69    /// Forms a Bitmap from a buffer, a number of bits and an offset (in
70    /// bits).
71    ///
72    /// # Safety
73    ///
74    /// Caller must ensure that the buffer contains enough bytes for the
75    /// specified number of bits including the offset.
76    pub unsafe fn from_raw_parts(
77        buffer: <Buffer as BufferType>::Buffer<u8>,
78        bits: usize,
79        offset: usize,
80    ) -> Self {
81        Bitmap {
82            buffer,
83            bits,
84            offset,
85        }
86    }
87
88    /// Returns the bit at given bit index. Returns `None` when the index is out
89    /// of bounds.
90    #[inline]
91    pub fn get(&self, index: usize) -> Option<bool> {
92        (index < self.len()).then(||
93            // Safety:
94            // - Bound checked
95            unsafe { self.get_unchecked(index) })
96    }
97
98    /// Returns the bit at given bit index. Skips bound checking.
99    ///
100    /// # Safety
101    ///
102    /// Caller must ensure index is within bounds.
103    #[inline]
104    pub unsafe fn get_unchecked(&self, index: usize) -> bool {
105        self.buffer.as_slice().get_unchecked(self.byte_index(index)) & (1 << self.bit_index(index))
106            != 0
107    }
108
109    /// Returns the number of leading padding bits in the first byte(s) of the
110    /// buffer that contain no meaningful bits. These bits should be ignored
111    /// when inspecting the raw byte buffer.
112    #[inline]
113    pub fn leading_bits(&self) -> usize {
114        self.offset
115    }
116
117    /// Returns the number of trailing padding bits in the last byte of the
118    /// buffer that contain no meaningful bits. These bits should be ignored when
119    /// inspecting the raw byte buffer.
120    #[inline]
121    pub fn trailing_bits(&self) -> usize {
122        let trailing_bits = self.bit_index(self.bits);
123        if trailing_bits == 0 {
124            0
125        } else {
126            8 - trailing_bits
127        }
128    }
129
130    /// Returns the bit index for the element at the provided index.
131    /// See [`Bitmap::byte_index`].
132    #[inline]
133    pub fn bit_index(&self, index: usize) -> usize {
134        (self.offset + index) % 8
135    }
136
137    /// Returns the byte index for the element at the provided index.
138    /// See [`Bitmap::bit_index`].
139    #[inline]
140    pub fn byte_index(&self, index: usize) -> usize {
141        (self.offset + index) / 8
142    }
143
144    /// Returns a [`Bitmap`] with `len` bits set.
145    #[must_use]
146    pub fn new_valid(len: usize) -> Self
147    where
148        Self: FromIterator<bool>,
149    {
150        std::iter::repeat_n(true, len).collect::<Self>()
151    }
152}
153
154impl<Buffer: BufferType> BufferRef<u8> for Bitmap<Buffer> {
155    type Buffer = <Buffer as BufferType>::Buffer<u8>;
156
157    fn buffer_ref(&self) -> &Self::Buffer {
158        &self.buffer
159    }
160}
161
162impl<Buffer> BufferRefMut<u8> for Bitmap<Buffer>
163where
164    Buffer: BufferType<Buffer<u8>: BufferMut<u8>>,
165{
166    type BufferMut = <Buffer as BufferType>::Buffer<u8>;
167
168    fn buffer_ref_mut(&mut self) -> &mut Self::BufferMut {
169        &mut self.buffer
170    }
171}
172
173impl<Buffer> Clone for Bitmap<Buffer>
174where
175    Buffer: BufferType<Buffer<u8>: Clone>,
176{
177    fn clone(&self) -> Self {
178        Bitmap {
179            buffer: self.buffer.clone(),
180            bits: self.bits,
181            offset: self.offset,
182        }
183    }
184}
185
186impl<Buffer: BufferType> Debug for Bitmap<Buffer> {
187    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
188        f.debug_struct(&format!("Bitmap<{}>", any::type_name::<Buffer>()))
189            .field("bits", &self.bits)
190            .field("buffer", &format!("{}", self.buffer.bits_display()))
191            .field("offset", &self.offset)
192            .finish()
193    }
194}
195
196impl<Buffer> Default for Bitmap<Buffer>
197where
198    Buffer: BufferType<Buffer<u8>: Default>,
199{
200    fn default() -> Self {
201        Self {
202            buffer: Default::default(),
203            bits: Default::default(),
204            offset: Default::default(),
205        }
206    }
207}
208
209impl<T, Buffer> Extend<T> for Bitmap<Buffer>
210where
211    T: Borrow<bool>,
212    Buffer: BufferType<Buffer<u8>: BufferMut<u8> + Extend<u8>>,
213{
214    fn extend<I>(&mut self, iter: I)
215    where
216        I: IntoIterator<Item = T>,
217    {
218        let mut additional_bits = 0;
219        let mut items = iter.into_iter().inspect(|_| {
220            additional_bits += 1;
221        });
222
223        let trailing_bits = self.trailing_bits();
224        if trailing_bits != 0 {
225            let last_byte_index = self.byte_index(self.bits);
226            let last_byte = &mut self.buffer.as_mut_slice()[last_byte_index];
227            for bit_position in 8 - trailing_bits..8 {
228                if let Some(x) = items.next() {
229                    if *x.borrow() {
230                        *last_byte |= 1 << bit_position;
231                    }
232                }
233            }
234        }
235
236        self.buffer.extend(items.bit_packed());
237        self.bits += additional_bits;
238    }
239}
240
241impl<Buffer, T> FromIterator<T> for Bitmap<Buffer>
242where
243    T: Borrow<bool>,
244    Buffer: BufferType<Buffer<u8>: FromIterator<u8>>,
245{
246    fn from_iter<I>(iter: I) -> Self
247    where
248        I: IntoIterator<Item = T>,
249    {
250        let mut bits = 0;
251        let buffer = iter
252            .into_iter()
253            .inspect(|_| {
254                bits += 1;
255            })
256            .bit_packed()
257            .collect();
258        Self {
259            buffer,
260            bits,
261            offset: 0,
262        }
263    }
264}
265
266impl<Buffer: BufferType> Index for Bitmap<Buffer> {
267    type Item<'a>
268        = bool
269    where
270        Self: 'a;
271
272    unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
273        self.get_unchecked(index)
274    }
275}
276
277impl<Buffer: BufferType> ops::Index<usize> for Bitmap<Buffer> {
278    type Output = bool;
279
280    fn index(&self, index: usize) -> &Self::Output {
281        /// Panic when out of bounds.
282        #[cold]
283        #[inline(never)]
284        fn assert_failed(index: usize, len: usize) -> ! {
285            panic!("index (is {index}) should be < len (is {len})");
286        }
287
288        let len = self.bits;
289        if index >= len {
290            assert_failed(index, len);
291        }
292
293        // Safety:
294        // - Bounds checked above.
295        if unsafe { self.get_unchecked(index) } {
296            &true
297        } else {
298            &false
299        }
300    }
301}
302
303impl<'a, Buffer: BufferType> IntoIterator for &'a Bitmap<Buffer> {
304    type Item = bool;
305    type IntoIter = BitmapIter<'a>;
306
307    fn into_iter(self) -> Self::IntoIter {
308        self.buffer
309            .as_slice()
310            .iter()
311            .bit_unpacked()
312            .skip(self.offset)
313            .take(self.bits)
314    }
315}
316
317impl<Buffer> IntoIterator for Bitmap<Buffer>
318where
319    Buffer: BufferType<Buffer<u8>: IntoIterator<Item = u8>>,
320{
321    type Item = bool;
322    type IntoIter = BitmapIntoIter<<<Buffer as BufferType>::Buffer<u8> as IntoIterator>::IntoIter>;
323
324    fn into_iter(self) -> Self::IntoIter {
325        self.buffer
326            .into_iter()
327            .bit_unpacked()
328            .skip(self.offset)
329            .take(self.bits)
330    }
331}
332
333impl<Buffer: BufferType> Length for Bitmap<Buffer> {
334    fn len(&self) -> usize {
335        self.bits
336    }
337}
338
339impl<Buffer: BufferType> PartialEq for Bitmap<Buffer> {
340    fn eq(&self, other: &Self) -> bool {
341        self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b)
342    }
343}
344
345impl<const N: usize, Buffer: BufferType> PartialEq<[bool; N]> for Bitmap<Buffer> {
346    fn eq(&self, other: &[bool; N]) -> bool {
347        self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == *b)
348    }
349}
350
351impl<Buffer: BufferType> ValidityBitmap for Bitmap<Buffer> {}
352
353#[cfg(test)]
354mod tests {
355    use crate::buffer::{ArrayBuffer, BoxBuffer, SliceBuffer};
356
357    use super::*;
358    use std::mem;
359
360    #[test]
361    fn offset_byte_slice() {
362        let mut bitmap = [true; 32].iter().collect::<Bitmap>();
363        // "unset" last byte
364        let slice = bitmap.buffer_ref_mut();
365        slice[3] = 0;
366        // "construct" new bitmap with last byte sliced off
367        // Safety:
368        // - There are 24 bits in vec.
369        let bitmap_sliced = unsafe { Bitmap::<SliceBuffer>::from_raw_parts(&slice[..3], 24, 0) };
370        assert!(bitmap_sliced.all_valid());
371    }
372
373    #[test]
374    fn offset_bit_slice() {
375        use crate::buffer::ArrayBuffer;
376        // Safety:
377        // - 1 byte has 3 bits.
378        let bitmap = unsafe { Bitmap::<ArrayBuffer<1>>::from_raw_parts([0b1010_0000], 3, 4) };
379        assert_eq!(bitmap.len(), 3);
380        assert_eq!(bitmap.leading_bits(), 4);
381        assert_eq!(bitmap.trailing_bits(), 1);
382        assert_eq!(bitmap.get(0), Some(false));
383        assert_eq!(bitmap.get(1), Some(true));
384        assert_eq!(bitmap.get(2), Some(false));
385        assert_eq!((&bitmap).into_iter().filter(|x| !x).count(), 2);
386        assert_eq!((&bitmap).into_iter().filter(|x| *x).count(), 1);
387        assert_eq!(
388            (&bitmap).into_iter().collect::<Vec<_>>(),
389            [false, true, false]
390        );
391    }
392
393    #[test]
394    fn offset_byte_vec() {
395        let mut bitmap = [true; 32].iter().collect::<Bitmap>();
396        // "unset" last byte
397        let vec: &mut Vec<u8> = bitmap.buffer_ref_mut();
398        vec[3] = 0;
399        // "construct" new bitmap with last byte sliced off
400        // Safety:
401        // - There are 24 bits in vec.
402        let bitmap_sliced = unsafe { Bitmap::<SliceBuffer>::from_raw_parts(&vec[..3], 24, 0) };
403        assert!(bitmap_sliced.all_valid());
404    }
405
406    #[test]
407    fn from_slice() {
408        let bitmap = Bitmap::<SliceBuffer> {
409            bits: 5,
410            buffer: &[42_u8],
411            offset: 0,
412        };
413        let slice: &[u8] = bitmap.buffer_ref();
414        assert_eq!(&slice[0], &42);
415        let mut bitmap_22 = Bitmap::<ArrayBuffer<1>> {
416            bits: 5,
417            buffer: [22_u8],
418            offset: 0,
419        };
420        let slice_22: &mut [u8] = bitmap_22.buffer_ref_mut();
421        slice_22[0] += 20;
422        assert_eq!(&slice_22[0], &42);
423    }
424
425    #[test]
426    fn as_ref() {
427        let bitmap = [false, true, true, false, true].iter().collect::<Bitmap>();
428        let slice: &[u8] = bitmap.buffer_ref();
429        assert_eq!(&slice[0], &22);
430    }
431
432    #[test]
433    fn as_ref_u8() {
434        let bitmap = [false, true, false, true, false, true]
435            .iter()
436            .collect::<Bitmap>();
437        let bytes = bitmap.buffer_ref();
438        assert_eq!(bytes.len(), 1);
439        assert_eq!(bytes[0], 42);
440    }
441
442    #[test]
443    #[should_panic(expected = "out of bounds")]
444    fn as_ref_u8_out_of_bounds() {
445        let bitmap = [false, true, false, true, false, true]
446            .iter()
447            .collect::<Bitmap>();
448        let bits: &[u8] = bitmap.buffer_ref();
449        let _ = bits[std::mem::size_of::<usize>()];
450    }
451
452    #[test]
453    fn as_ref_bitslice() {
454        let bits = [
455            false, true, false, true, false, true, false, false, false, true,
456        ]
457        .iter()
458        .collect::<Bitmap>();
459        assert_eq!(bits.len(), 10);
460        assert!(!bits[0]);
461        assert!(bits[1]);
462        assert!(!bits[2]);
463        assert!(bits[3]);
464        assert!(!bits[4]);
465        assert!(bits[5]);
466        assert!(!bits[6]);
467        assert!(!bits[7]);
468        assert!(!bits[8]);
469        assert!(bits[9]);
470    }
471
472    #[test]
473    #[should_panic(expected = "should be < len")]
474    fn as_ref_bitslice_out_of_bounds() {
475        let bitmap = [false, true, false, true, false, true]
476            .iter()
477            .collect::<Bitmap>();
478        let _ = bitmap[bitmap.bits];
479    }
480
481    #[test]
482    fn count() {
483        let vec = [false, true, false, true, false, true];
484        let bitmap = vec.iter().collect::<Bitmap>();
485        assert_eq!(bitmap.len(), 6);
486        assert!(!bitmap.is_empty());
487        vec.iter().zip(bitmap).for_each(|(a, b)| assert_eq!(*a, b));
488    }
489
490    #[test]
491    fn from_iter() {
492        let vec = vec![true, false, true, false];
493        let bitmap = vec.iter().collect::<Bitmap>();
494        assert_eq!(bitmap.len(), vec.len());
495        assert_eq!(vec, bitmap.into_iter().collect::<Vec<_>>());
496    }
497
498    #[test]
499    fn from_iter_ref() {
500        let array = [true, false, true, false];
501        let bitmap = array.iter().collect::<Bitmap>();
502        assert_eq!(bitmap.len(), array.len());
503        assert_eq!(array.to_vec(), bitmap.into_iter().collect::<Vec<_>>());
504    }
505
506    #[test]
507    fn into_iter() {
508        let vec = vec![true, false, true, false];
509        let bitmap = vec.iter().collect::<Bitmap>();
510        assert_eq!(bitmap.into_iter().collect::<Vec<_>>(), vec);
511    }
512
513    #[test]
514    fn size_of() {
515        assert_eq!(
516            mem::size_of::<Bitmap>(),
517            mem::size_of::<Vec<u8>>() + 2 * mem::size_of::<usize>()
518        );
519
520        assert_eq!(
521            mem::size_of::<Bitmap<BoxBuffer>>(),
522            mem::size_of::<Box<[u8]>>() + 2 * mem::size_of::<usize>()
523        );
524    }
525}