1#![cfg_attr(nightly, deny(missing_docs))]
2#![cfg_attr(nightly, feature(external_doc))]
3#![cfg_attr(nightly, doc(include = "../README.md"))]
4#![cfg_attr(test, deny(warnings))]
5
6mod change;
7mod iter;
8
9pub use crate::change::Change;
10pub use crate::iter::Iter;
11
12use memory_pager::Pager;
13use std::fs::File;
14use std::io;
15
16#[derive(Debug)]
18pub struct Bitfield {
19 pub pages: Pager,
23
24 byte_length: usize,
25 page_length: usize,
26}
27
28impl Bitfield {
29 pub fn new(page_size: usize) -> Self {
34 assert!(page_size.is_power_of_two());
35 Bitfield {
36 pages: Pager::new(page_size),
37 page_length: 0,
38 byte_length: 0,
39 }
40 }
41
42 pub fn from_file(
44 file: &mut File,
45 page_size: usize,
46 offset: Option<usize>,
47 ) -> io::Result<Self> {
48 let pages = Pager::from_file(file, page_size, offset)?;
49 let page_length = pages.len();
50
51 let byte_length = page_length * page_size;
55
56 Ok(Self {
57 pages,
58 page_length,
59 byte_length,
60 })
61 }
62
63 #[inline]
66 pub fn set(&mut self, index: usize, value: bool) -> Change {
67 let index_mask = index & 7;
68 let byte_index = (index - index_mask) / 8;
69 let byte = self.get_byte(byte_index);
70
71 if value {
72 let byte = byte | (128 >> index_mask);
74 self.set_byte(byte_index, byte)
75 } else {
76 let byte = byte & (255 ^ (128 >> index_mask));
78 self.set_byte(byte_index, byte)
79 }
80 }
81
82 #[inline]
84 pub fn get(&mut self, index: usize) -> bool {
85 let byte_offset = index & 7;
86 let j = (index - byte_offset) / 8;
87
88 let num = self.get_byte(j) & (128 >> byte_offset);
89 match num {
90 0 => false,
91 _ => true,
92 }
93 }
94
95 #[inline]
97 pub fn get_byte(&self, index: usize) -> u8 {
98 let byte_offset = self.page_mask(index);
99 let page_num = index / self.page_size();
100 match self.pages.get(page_num) {
101 Some(page) => page[byte_offset],
102 None => 0,
103 }
104 }
105
106 #[inline]
108 pub fn set_byte(&mut self, index: usize, byte: u8) -> Change {
109 let byte_offset = self.page_mask(index);
110 let page_num = index / self.page_size();
111 let page = self.pages.get_mut_or_alloc(page_num);
112
113 if index >= self.byte_length {
114 self.byte_length = index + 1;
115 }
116
117 if page[byte_offset] == byte {
118 Change::Unchanged
119 } else {
120 page[byte_offset] = byte;
121 Change::Changed
122 }
123 }
124
125 #[inline]
127 pub fn page_size(&self) -> usize {
128 self.pages.page_size()
129 }
130
131 #[inline]
147 pub fn len(&self) -> usize {
148 self.byte_length * 8
149 }
150
151 #[inline]
167 pub fn byte_len(&self) -> usize {
168 self.byte_length
169 }
170
171 #[inline]
189 pub fn page_len(&self) -> usize {
190 self.pages.len()
191 }
192
193 #[inline]
205 pub fn is_empty(&self) -> bool {
206 self.pages.is_empty()
207 }
208
209 #[inline]
211 pub fn iter(&mut self) -> Iter {
212 Iter::new(self)
213 }
214
215 #[inline]
216 fn page_mask(&self, index: usize) -> usize {
218 index & (self.page_size() - 1)
219 }
220
221 pub fn to_bytes(&self) -> std::io::Result<Vec<u8>> {
223 use std::io::{Cursor, Write};
224
225 let mut all =
226 Cursor::new(Vec::with_capacity(self.page_len() * self.page_size()));
227
228 for index in 0..self.page_len() {
229 let next = self.pages.get(index);
230 if let Some(page) = next {
231 let all_offset = index * self.page_size();
232 all.set_position(all_offset as u64);
233 all.write_all(&page)?;
234 }
235 }
236
237 Ok(all.into_inner())
238 }
239}
240
241impl Default for Bitfield {
243 #[inline]
244 fn default() -> Self {
245 let page_size = 1024;
246 Bitfield::new(page_size)
247 }
248}