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}