Skip to main content

vortex_buffer/bit/
meta.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4/// In-memory metadata describing a packed bitset: a normalized bit `offset` (always `< 8`) and a
5/// logical bit `len`.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub struct BitBufferMeta {
8    offset: usize,
9    len: usize,
10}
11
12impl BitBufferMeta {
13    /// Create metadata for a bitset starting at bit `offset` with `len` bits.
14    ///
15    /// Panics if `offset >= 8`. Use [`from_raw_offset`](Self::from_raw_offset) to normalize a
16    /// larger offset.
17    pub fn new(offset: usize, len: usize) -> Self {
18        assert!(offset < 8, "BitBufferMeta offset must be < 8, got {offset}");
19        Self { offset, len }
20    }
21
22    /// Normalize a raw bit `offset` into a whole-byte offset plus metadata whose `offset` is
23    /// `< 8`.
24    ///
25    /// Returns `(byte_offset, meta)` so the caller can slice its backing buffer by `byte_offset`
26    /// and store the remaining sub-byte offset in `meta`.
27    pub fn from_raw_offset(offset: usize, len: usize) -> (usize, Self) {
28        (
29            offset / 8,
30            Self {
31                offset: offset % 8,
32                len,
33            },
34        )
35    }
36
37    /// The sub-byte bit offset. Always `< 8`.
38    #[inline(always)]
39    pub fn offset(&self) -> usize {
40        self.offset
41    }
42
43    /// The logical length of the bitset in bits.
44    #[inline(always)]
45    pub fn len(&self) -> usize {
46        self.len
47    }
48
49    /// Returns `true` if the bitset is empty.
50    #[inline(always)]
51    pub fn is_empty(&self) -> bool {
52        self.len == 0
53    }
54
55    /// The number of backing bytes required to hold `offset + len` bits.
56    #[inline]
57    pub fn byte_len(&self) -> usize {
58        (self.offset + self.len).div_ceil(8)
59    }
60}