Skip to main content

visi_core/core/engine/
bitmask.rs

1use crate::core::SharedVec;
2use serde::{Deserialize, Serialize};
3
4/// One bit per row, bookkeeping which cells of a [`ColumnData`]
5/// are populated (1) vs blank (0).
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Bitmask {
8    data: SharedVec<u8>,
9    /// Column length (row count)
10    pub len: usize,
11}
12
13impl Bitmask {
14    pub(crate) fn with_size(size: usize) -> Self {
15        Self {
16            data: vec![0; size.div_ceil(8)].into(),
17            len: size,
18        }
19    }
20    pub(crate) fn push(&mut self, value: bool) {
21        let byte_idx = self.len / 8;
22        let bit_idx = self.len % 8;
23        if byte_idx >= self.data.len() {
24            self.data.push(0);
25        }
26        if value {
27            self.data[byte_idx] |= 1 << bit_idx;
28        } else {
29            self.data[byte_idx] &= !(1 << bit_idx);
30        }
31        self.len += 1;
32    }
33    /// Whether the entry at `index` holds a value,
34    /// returns false for out-of-bounds
35    pub fn get(&self, index: usize) -> bool {
36        if index >= self.len {
37            return false;
38        }
39        let byte_idx = index / 8;
40        let bit_idx = index % 8;
41        (self.data[byte_idx] & (1 << bit_idx)) != 0
42    }
43    pub(crate) fn set(&mut self, index: usize, value: bool) {
44        if index >= self.len {
45            return;
46        }
47        let byte_idx = index / 8;
48        let bit_idx = index % 8;
49        if value {
50            self.data[byte_idx] |= 1 << bit_idx;
51        } else {
52            self.data[byte_idx] &= !(1 << bit_idx);
53        }
54    }
55    pub(crate) fn insert(&mut self, index: usize, value: bool) {
56        if index >= self.len {
57            self.push(value);
58            return;
59        }
60        self.push(false);
61        for i in (index + 1..self.len).rev() {
62            let prev = self.get(i - 1);
63            self.set(i, prev);
64        }
65        self.set(index, value);
66    }
67    pub(crate) fn remove(&mut self, index: usize) {
68        if index >= self.len {
69            return;
70        }
71        for i in index..self.len - 1 {
72            let next = self.get(i + 1);
73            self.set(i, next);
74        }
75        self.len -= 1;
76        let required_bytes = self.len.div_ceil(8);
77        if self.data.len() > required_bytes {
78            self.data.pop();
79        }
80    }
81    pub(crate) fn drain<R: std::ops::RangeBounds<usize> + Clone>(&mut self, range: R) {
82        let start = match range.start_bound() {
83            std::ops::Bound::Included(&n) => n,
84            std::ops::Bound::Excluded(&n) => n + 1,
85            std::ops::Bound::Unbounded => 0,
86        };
87        let end = match range.end_bound() {
88            std::ops::Bound::Included(&n) => n + 1,
89            std::ops::Bound::Excluded(&n) => n,
90            std::ops::Bound::Unbounded => self.len,
91        };
92        let start = start.min(self.len);
93        let end = end.min(self.len);
94        if start >= end {
95            return;
96        }
97        let count = end - start;
98        for i in end..self.len {
99            let val = self.get(i);
100            self.set(i - count, val);
101        }
102        self.len -= count;
103        self.data.truncate(self.len.div_ceil(8));
104    }
105}