1use math::round;
2
3const LOW_SET_FLAGS: [u64; 65] = [
17 0x0000_0000_0000_0000,
18 0x0000_0000_0000_0001, 0x0000_0000_0000_0003, 0x0000_0000_0000_0007, 0x0000_0000_0000_000F,
19 0x0000_0000_0000_001F, 0x0000_0000_0000_003F, 0x0000_0000_0000_007F, 0x0000_0000_0000_00FF,
20 0x0000_0000_0000_01FF, 0x0000_0000_0000_03FF, 0x0000_0000_0000_07FF, 0x0000_0000_0000_0FFF,
21 0x0000_0000_0000_1FFF, 0x0000_0000_0000_3FFF, 0x0000_0000_0000_7FFF, 0x0000_0000_0000_FFFF,
22 0x0000_0000_0001_FFFF, 0x0000_0000_0003_FFFF, 0x0000_0000_0007_FFFF, 0x0000_0000_000F_FFFF,
23 0x0000_0000_001F_FFFF, 0x0000_0000_003F_FFFF, 0x0000_0000_007F_FFFF, 0x0000_0000_00FF_FFFF,
24 0x0000_0000_01FF_FFFF, 0x0000_0000_03FF_FFFF, 0x0000_0000_07FF_FFFF, 0x0000_0000_0FFF_FFFF,
25 0x0000_0000_1FFF_FFFF, 0x0000_0000_3FFF_FFFF, 0x0000_0000_7FFF_FFFF, 0x0000_0000_FFFF_FFFF,
26 0x0000_0001_FFFF_FFFF, 0x0000_0003_FFFF_FFFF, 0x0000_0007_FFFF_FFFF, 0x0000_000F_FFFF_FFFF,
27 0x0000_001F_FFFF_FFFF, 0x0000_003F_FFFF_FFFF, 0x0000_007F_FFFF_FFFF, 0x0000_00FF_FFFF_FFFF,
28 0x0000_01FF_FFFF_FFFF, 0x0000_03FF_FFFF_FFFF, 0x0000_07FF_FFFF_FFFF, 0x0000_0FFF_FFFF_FFFF,
29 0x0000_1FFF_FFFF_FFFF, 0x0000_3FFF_FFFF_FFFF, 0x0000_7FFF_FFFF_FFFF, 0x0000_FFFF_FFFF_FFFF,
30 0x0001_FFFF_FFFF_FFFF, 0x0003_FFFF_FFFF_FFFF, 0x0007_FFFF_FFFF_FFFF, 0x000F_FFFF_FFFF_FFFF,
31 0x001F_FFFF_FFFF_FFFF, 0x003F_FFFF_FFFF_FFFF, 0x007F_FFFF_FFFF_FFFF, 0x00FF_FFFF_FFFF_FFFF,
32 0x01FF_FFFF_FFFF_FFFF, 0x03FF_FFFF_FFFF_FFFF, 0x07FF_FFFF_FFFF_FFFF, 0x0FFF_FFFF_FFFF_FFFF,
33 0x1FFF_FFFF_FFFF_FFFF, 0x3FFF_FFFF_FFFF_FFFF, 0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF,
34];
35
36const INDEX_SHIFT: usize = 6;
38const INDEX_LOWER_MASK: u64 = LOW_SET_FLAGS[INDEX_SHIFT];
40
41#[derive(Clone,Default)]
43pub struct BitVecBlock {
44 pub bits: u64,
45 pub index: u64
46}
47
48pub struct IndexedBitVec {
51 index_size: usize,
52 data_vec: Vec<BitVecBlock>
53}
54
55impl IndexedBitVec {
56 #[inline]
65 pub fn with_capacity(size: usize) -> Self {
66 let index_size: usize = (round::ceil((size as f64) / 64.0, 0) as usize)+1;
67 Self {
68 index_size,
69 data_vec: vec![Default::default(); index_size]
70 }
71 }
72
73 #[inline]
83 pub fn set_bit(&mut self, pos: usize) {
84 self.data_vec[pos >> INDEX_SHIFT].bits |= 0x1 << (pos & INDEX_LOWER_MASK as usize);
85 }
86
87 #[inline]
89 pub fn get_bit(&mut self, pos: usize) -> bool {
90 ((self.data_vec[pos >> INDEX_SHIFT].bits >> (pos & INDEX_LOWER_MASK as usize)) & 0x1) != 0
91 }
92
93 pub fn build_index(&mut self, initial_rank: u64) {
105 let mut current_rank = initial_rank;
106 for bv_val in self.data_vec.iter_mut().take(self.index_size-1) {
108 bv_val.index = current_rank;
109 current_rank += bv_val.bits.count_ones() as u64;
110 }
111 self.data_vec[self.index_size-1].index = current_rank;
113 }
114
115 #[inline]
129 pub fn rank(&self, pos: usize) -> u64 {
130 let offset: usize = pos >> INDEX_SHIFT;
131 self.data_vec[offset].index +
133 (self.data_vec[offset].bits & LOW_SET_FLAGS[pos & INDEX_LOWER_MASK as usize]).count_ones() as u64
134 }
135
136 #[inline]
154 pub unsafe fn rank_unchecked(&self, pos:usize) -> u64 {
155 let vec_offset: usize = pos >> INDEX_SHIFT;
156 self.data_vec.get_unchecked(vec_offset).index +
158 (self.data_vec.get_unchecked(vec_offset).bits & LOW_SET_FLAGS.get_unchecked(pos & INDEX_LOWER_MASK as usize)).count_ones() as u64
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165
166 #[test]
167 fn test_allocation() {
168 let ibv = IndexedBitVec::with_capacity(63);
170 assert_eq!(ibv.data_vec.len(), 2);
171 let ibv = IndexedBitVec::with_capacity(64);
172 assert_eq!(ibv.data_vec.len(), 2);
173 let ibv = IndexedBitVec::with_capacity(65);
174 assert_eq!(ibv.data_vec.len(), 3);
175 }
176
177 #[test]
178 fn test_set_bit() {
179 let mut ibv = IndexedBitVec::with_capacity(257);
181 for i in 0..128 {
182 ibv.set_bit(i);
183 }
184 ibv.set_bit(256);
185
186 for i in 0..128 {
188 assert_eq!(ibv.get_bit(i), true);
189 }
190 for i in 128..256 {
191 assert_eq!(ibv.get_bit(i), false);
192 }
193 assert_eq!(ibv.get_bit(256), true);
194
195 let slice: &[BitVecBlock] = ibv.data_vec.as_slice();
197 assert_eq!(slice.len(), 6);
198 for i in 0..2 {
199 assert_eq!(slice[i].bits, 0xffffffffffffffff);
200 }
201 for i in 2..4 {
202 assert_eq!(slice[i].bits, 0x0);
203 }
204 assert_eq!(slice[4].bits, 0x1)
205 }
206
207 #[test]
208 fn test_indexing() {
209 let mut ibv = IndexedBitVec::with_capacity(257);
211 for i in 0..128 {
212 ibv.set_bit(i);
213 }
214 ibv.set_bit(256);
215
216 ibv.build_index(0);
217 let slice: &[BitVecBlock] = ibv.data_vec.as_slice();
218 assert_eq!(slice.len(), 6);
219 let counts = vec![0, 64, 128, 128, 128, 129];
220 for i in 0..slice.len() {
221 assert_eq!(counts[i], slice[i].index);
222 }
223
224 let mut ibv = IndexedBitVec::with_capacity(64);
226 for i in 0..64 {
227 ibv.set_bit(i);
228 ibv.build_index(0);
229 let slice: &[BitVecBlock] = ibv.data_vec.as_slice();
230 assert_eq!(slice[1].index, (i+1) as u64);
231 }
232 }
233
234 #[test]
235 fn test_offset() {
236 let mut ibv = IndexedBitVec::with_capacity(64);
238 for i in 0..64 {
239 ibv.set_bit(i);
240 }
241 ibv.build_index(100);
242 let slice: &[BitVecBlock] = ibv.data_vec.as_slice();
243 assert_eq!(slice[1].index, 164);
244 }
245
246 #[test]
247 fn test_rank() {
248 let mut ibv = IndexedBitVec::with_capacity(257);
250 for i in 0..128 {
251 ibv.set_bit(i);
252 }
253 ibv.set_bit(256);
254 ibv.build_index(0);
255
256 for i in 0..128 {
257 assert_eq!(ibv.rank(i), i as u64);
258 }
259 for i in 128..257 {
260 assert_eq!(ibv.rank(i), 128);
261 }
262 assert_eq!(ibv.rank(257), 129);
263 }
264}