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