visi_core/core/engine/
bitmask.rs1use crate::core::SharedVec;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct Bitmask {
21 data: SharedVec<u8>,
22 pub len: usize,
25}
26
27impl Bitmask {
28 pub(crate) fn with_size(size: usize) -> Self {
29 Self {
30 data: vec![0; size.div_ceil(8)].into(),
31 len: size,
32 }
33 }
34 pub(crate) fn push(&mut self, value: bool) {
35 let byte_idx = self.len / 8;
36 let bit_idx = self.len % 8;
37 if byte_idx >= self.data.len() {
38 self.data.push(0);
39 }
40 if value {
41 self.data[byte_idx] |= 1 << bit_idx;
42 } else {
43 self.data[byte_idx] &= !(1 << bit_idx);
44 }
45 self.len += 1;
46 }
47 pub fn get(&self, index: usize) -> bool {
51 if index >= self.len {
52 return false;
53 }
54 let byte_idx = index / 8;
55 let bit_idx = index % 8;
56 (self.data[byte_idx] & (1 << bit_idx)) != 0
57 }
58 pub(crate) fn set(&mut self, index: usize, value: bool) {
59 if index >= self.len {
60 return;
61 }
62 let byte_idx = index / 8;
63 let bit_idx = index % 8;
64 if value {
65 self.data[byte_idx] |= 1 << bit_idx;
66 } else {
67 self.data[byte_idx] &= !(1 << bit_idx);
68 }
69 }
70 pub(crate) fn insert(&mut self, index: usize, value: bool) {
71 if index >= self.len {
72 self.push(value);
73 return;
74 }
75 self.push(false);
76 for i in (index + 1..self.len).rev() {
77 let prev = self.get(i - 1);
78 self.set(i, prev);
79 }
80 self.set(index, value);
81 }
82 pub(crate) fn remove(&mut self, index: usize) {
83 if index >= self.len {
84 return;
85 }
86 for i in index..self.len - 1 {
87 let next = self.get(i + 1);
88 self.set(i, next);
89 }
90 self.len -= 1;
91 let required_bytes = self.len.div_ceil(8);
92 if self.data.len() > required_bytes {
93 self.data.pop();
94 }
95 }
96 pub(crate) fn drain<R: std::ops::RangeBounds<usize> + Clone>(&mut self, range: R) {
97 let start = match range.start_bound() {
98 std::ops::Bound::Included(&n) => n,
99 std::ops::Bound::Excluded(&n) => n + 1,
100 std::ops::Bound::Unbounded => 0,
101 };
102 let end = match range.end_bound() {
103 std::ops::Bound::Included(&n) => n + 1,
104 std::ops::Bound::Excluded(&n) => n,
105 std::ops::Bound::Unbounded => self.len,
106 };
107 let start = start.min(self.len);
108 let end = end.min(self.len);
109 if start >= end {
110 return;
111 }
112 let count = end - start;
113 for i in end..self.len {
114 let val = self.get(i);
115 self.set(i - count, val);
116 }
117 self.len -= count;
118 self.data.truncate(self.len.div_ceil(8));
119 }
120}