1pub struct Bitmap {
2 size: usize,
3 bits: Vec<u8>,
4}
5
6impl Bitmap {
7 pub fn new() -> Self {
9 Self::with_size(0)
10 }
11
12 pub fn with_size(size: usize) -> Self {
14 let mut bits = Vec::new();
15 let bits_size;
16 if size == 0 {
17 bits_size = 0;
18 } else {
19 bits_size = (size - 1) / 8 + 1;
20 }
21 for _ in 0..bits_size {
22 bits.push(0);
23 }
24
25 Self {
26 size,
27 bits,
28 }
29 }
30
31 pub fn size(&self) -> usize {
33 self.size
34 }
35
36 pub fn get(&self, idx: usize) -> bool {
38 if idx >= self.size {
39 panic!("Out of bound error");
40 }
41 let byte_idx = idx >> 3; let offset = idx & 0b111; let byte = self.bits[byte_idx];
44 (byte >> (7 - offset)) & 1 == 1
45 }
46
47 pub fn set(&mut self, idx: usize, value: bool) {
49 if idx >= self.size {
50 panic!("Out of bound error");
51 }
52 let byte_idx = idx >> 3; let offset = idx & 0b111; let mut byte = self.bits[byte_idx];
55
56 let curval = (byte >> (7 - offset)) & 1;
57 let mask;
58 if value {
59 mask = 1 ^ curval;
60 } else {
61 mask = 0 ^ curval;
62 }
63 byte = byte ^ (mask << (7 - offset)); self.bits[byte_idx] = byte;
65 }
66
67 pub fn push(&mut self, value: bool) {
69 if self.size & 0b111 == 0 { self.bits.push(0);
72 }
73 let idx = self.size;
74 self.size += 1;
75 self.set(idx, value);
76 }
77
78 #[allow(dead_code)]
79 fn dump(&self) -> String {
81 let mut s = vec![];
82 for byte in &self.bits {
83 s.push(format!("{:08b}", byte));
84 }
85 s.join("")[0..self.size].to_string()
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_push() {
95 let mut bm = Bitmap::new();
96 bm.push(false);
97 bm.push(true);
98 bm.push(false);
99 assert_eq!(bm.dump(), "010");
100 }
101
102 #[test]
103 fn test_get_and_set() {
104 let mut bm = Bitmap::with_size(24);
105 bm.set(13, true);
106 assert_eq!(bm.dump(), "000000000000010000000000");
107 bm.set(13, false);
108 assert_eq!(bm.dump(), "000000000000000000000000");
109 }
110}