sparse_bitfield/
lib.rs

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/// Bitfield instance.
17#[derive(Debug)]
18pub struct Bitfield {
19  /// A [memory-pager] instance.
20  ///
21  /// [memory-pager]: https://docs.rs/memory-pager/
22  pub pages: Pager,
23
24  byte_length: usize,
25  page_length: usize,
26}
27
28impl Bitfield {
29  /// Create a new instance.
30  ///
31  /// ## Panics
32  /// The page size must be a multiple of 2, and bigger than 0.
33  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  /// Create a new instance from a `File`.
43  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    // NOTE: empty pages are initialized as `0` filled. So when we reinitialize
52    // a page, in essence our byte length becomes the amount of bytes we have
53    // times the amount of pages we have.
54    let byte_length = page_length * page_size;
55
56    Ok(Self {
57      pages,
58      page_length,
59      byte_length,
60    })
61  }
62
63  /// Set a bit to true or false. Returns a boolean indicating if the value was
64  /// changed.
65  #[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      // Mask the byte to flip a bit to `1`.
73      let byte = byte | (128 >> index_mask);
74      self.set_byte(byte_index, byte)
75    } else {
76      // Mask the byte to flip a bit to `0`.
77      let byte = byte & (255 ^ (128 >> index_mask));
78      self.set_byte(byte_index, byte)
79    }
80  }
81
82  /// Get the value of a bit.
83  #[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  /// Get a byte from our internal buffers.
96  #[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  /// Set a byte to the right value inside our internal buffers.
107  #[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  /// Get the memory page size in bytes.
126  #[inline]
127  pub fn page_size(&self) -> usize {
128    self.pages.page_size()
129  }
130
131  /// Get the amount of bits in the bitfield.
132  ///
133  /// ## Examples
134  /// ```rust
135  /// # extern crate sparse_bitfield;
136  /// # use sparse_bitfield::Bitfield;
137  /// let mut bits = Bitfield::new(1024);
138  /// assert_eq!(bits.len(), 0);
139  /// bits.set(0, true);
140  /// assert_eq!(bits.len(), 8);
141  /// bits.set(1, true);
142  /// assert_eq!(bits.len(), 8);
143  /// bits.set(9, false);
144  /// assert_eq!(bits.len(), 16);
145  /// ```
146  #[inline]
147  pub fn len(&self) -> usize {
148    self.byte_length * 8
149  }
150
151  /// Get the amount of bytes in the bitfield.
152  ///
153  /// ## Examples
154  /// ```rust
155  /// # extern crate sparse_bitfield;
156  /// # use sparse_bitfield::Bitfield;
157  /// let mut bits = Bitfield::new(1024);
158  /// assert_eq!(bits.byte_len(), 0);
159  /// bits.set(0, true);
160  /// assert_eq!(bits.byte_len(), 1);
161  /// bits.set(1, true);
162  /// assert_eq!(bits.byte_len(), 1);
163  /// bits.set(9, false);
164  /// assert_eq!(bits.byte_len(), 2);
165  /// ```
166  #[inline]
167  pub fn byte_len(&self) -> usize {
168    self.byte_length
169  }
170
171  /// Get the amount of memory pages in the bitfield.
172  ///
173  /// ## Examples
174  /// ```rust
175  /// # extern crate sparse_bitfield;
176  /// # use sparse_bitfield::Bitfield;
177  /// let mut bits = Bitfield::new(1024);
178  /// assert_eq!(bits.page_len(), 0);
179  /// bits.set(0, true);
180  /// assert_eq!(bits.page_len(), 1);
181  /// bits.set(1, true);
182  /// assert_eq!(bits.page_len(), 1);
183  /// bits.set(2, false);
184  /// assert_eq!(bits.page_len(), 1);
185  /// bits.set(1024 * 8 + 1, true);
186  /// assert_eq!(bits.page_len(), 2);
187  /// ```
188  #[inline]
189  pub fn page_len(&self) -> usize {
190    self.pages.len()
191  }
192
193  /// Returns `true` if no bits are stored.
194  ///
195  /// ## Examples
196  /// ```rust
197  /// # extern crate sparse_bitfield;
198  /// # use sparse_bitfield::Bitfield;
199  /// let mut bits = Bitfield::new(1024);
200  /// assert!(bits.is_empty());
201  /// bits.set(0, true);
202  /// assert!(!bits.is_empty());
203  /// ```
204  #[inline]
205  pub fn is_empty(&self) -> bool {
206    self.pages.is_empty()
207  }
208
209  /// Create an `Iterator` that iterates over all pages.
210  #[inline]
211  pub fn iter(&mut self) -> Iter {
212    Iter::new(self)
213  }
214
215  #[inline]
216  /// Find which page we should write to.
217  fn page_mask(&self, index: usize) -> usize {
218    index & (self.page_size() - 1)
219  }
220
221  /// Based on [Bitfield.prototype.toBuffer](https://github.com/mafintosh/sparse-bitfield/blob/master/index.js#L54-L64)
222  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
241/// Create a new instance with a `page_size` of `1kb`.
242impl Default for Bitfield {
243  #[inline]
244  fn default() -> Self {
245    let page_size = 1024;
246    Bitfield::new(page_size)
247  }
248}