1use std::mem::size_of_val;
7
8const L2_BIT_SIZE: usize = 512;
10const L1_BIT_SIZE: usize = 8 * L2_BIT_SIZE;
12
13pub trait RankedBitsAccess {
18 fn rank(&self, idx: usize) -> Option<usize>;
20
21 #[inline]
27 unsafe fn rank_impl<T: L12RankAccess>(bits: &[u64], l12_ranks: &T, idx: usize) -> Option<usize> {
28 let word_idx = idx / 64;
29 let bit_idx = idx % 64;
30 let word = *bits.get_unchecked(word_idx);
31
32 if (word & (1u64 << bit_idx)) == 0 {
33 return None;
34 }
35
36 let l1_pos = idx / L1_BIT_SIZE;
37 let l2_pos = (idx % L1_BIT_SIZE) / L2_BIT_SIZE;
38
39 let idx_within_l2 = idx % L2_BIT_SIZE;
40 let blocks_num = idx_within_l2 / 64;
41 let offset = (idx / L2_BIT_SIZE) * 8;
42 let block = bits.get_unchecked(offset..offset + blocks_num);
43
44 let block_rank = block.iter().map(|&x| x.count_ones() as usize).sum::<usize>();
45
46 let word = *bits.get_unchecked(offset + blocks_num);
47 let word_mask = ((1u64 << (idx_within_l2 % 64)) - 1) * (idx_within_l2 > 0) as u64;
48 let word_rank = (word & word_mask).count_ones() as usize;
49
50 let (l1_rank, l2_rank) = l12_ranks.l12_ranks(l1_pos, l2_pos);
51 let total_rank = l1_rank + l2_rank + block_rank + word_rank;
52
53 Some(total_rank)
54 }
55}
56
57#[derive(Debug, Default)]
58#[cfg_attr(feature = "rkyv_derive", derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize))]
59#[cfg_attr(feature = "rkyv_derive", archive_attr(derive(rkyv::CheckBytes)))]
60pub struct RankedBits {
61 pub(crate) bits: Box<[u64]>,
63 l12_ranks: Box<[L12Rank]>,
65}
66
67#[cfg(feature = "serde")]
75impl serde::Serialize for RankedBits {
76 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
77 where
78 S: serde::Serializer,
79 {
80 let mut out = serde_bytes::ByteBuf::with_capacity(self.bits.len() * 8);
81 for word in &self.bits {
82 out.extend_from_slice(&word.to_le_bytes());
83 }
84 out.serialize(serializer)
85 }
86}
87#[cfg(feature = "serde")]
88impl<'de> serde::Deserialize<'de> for RankedBits {
89 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
90 where
91 D: serde::Deserializer<'de>,
92 {
93 let buf = serde_bytes::ByteBuf::deserialize(deserializer)?;
94 if buf.len() % 8 != 0 {
95 return Err(serde::de::Error::invalid_length(
96 buf.len(),
97 &"a byte length that is a multiple of 8",
98 ));
99 }
100 let bits = buf
101 .as_chunks::<8>()
102 .0
103 .iter()
104 .map(|&c| u64::from_le_bytes(c))
105 .collect::<Box<[u64]>>();
106
107 Ok(RankedBits::new(bits))
108 }
109}
110
111#[derive(Debug)]
116#[cfg_attr(feature = "rkyv_derive", derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize))]
117#[cfg_attr(feature = "rkyv_derive", archive_attr(derive(rkyv::CheckBytes)))]
118#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
119pub struct L12Rank(#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))] [u8; 16]);
120
121pub trait L12RankAccess {
123 fn l12_rank(&self, l1_pos: usize) -> u128;
125
126 #[inline]
128 fn l12_ranks(&self, l1_pos: usize, l2_pos: usize) -> (usize, usize) {
129 let l12_rank = self.l12_rank(l1_pos);
130 let l1_rank = (l12_rank & 0xFFFFFFFFFFF) as usize;
131 let l2_rank = ((l12_rank >> (32 + 12 * l2_pos)) & 0xFFF) as usize;
132 (l1_rank, l2_rank)
133 }
134}
135
136impl L12RankAccess for Box<[L12Rank]> {
137 #[inline]
138 fn l12_rank(&self, l1_pos: usize) -> u128 {
139 u128::from_le_bytes(unsafe { self.get_unchecked(l1_pos).0 })
140 }
141}
142
143#[cfg(feature = "rkyv_derive")]
144impl L12RankAccess for rkyv::boxed::ArchivedBox<[ArchivedL12Rank]> {
145 #[inline]
146 fn l12_rank(&self, l1_pos: usize) -> u128 {
147 u128::from_le_bytes(unsafe { self.get_unchecked(l1_pos).0 })
148 }
149}
150
151impl From<u128> for L12Rank {
152 #[inline]
153 fn from(v: u128) -> Self {
154 L12Rank(v.to_le_bytes())
155 }
156}
157
158impl RankedBits {
159 pub fn count_ones(&self) -> usize {
161 self.bits.iter().map(|x| x.count_ones() as usize).sum()
162 }
163
164 pub fn new(bits: Box<[u64]>) -> Self {
166 let (blocks, remainder) = bits.as_chunks::<64>();
167 let mut l12_ranks = Vec::with_capacity(bits.len().div_ceil(64));
168 let mut l1_rank: u128 = 0;
169
170 for block64 in blocks {
171 let mut l12_rank = 0u128;
172 let mut sum = 0u16;
173 for (i, block8) in block64.as_chunks::<8>().0.iter().enumerate() {
174 sum += block8.iter().map(|&x| x.count_ones() as u16).sum::<u16>();
175 l12_rank += (sum as u128) << (i * 12);
176 }
177 l12_rank = (l12_rank << 44) | l1_rank;
178 l12_ranks.push(l12_rank.into());
179 l1_rank += sum as u128;
180 }
181
182 if !remainder.is_empty() {
183 let mut l12_rank = 0u128;
184 let mut sum = 0u16;
185 for (i, block) in remainder.chunks(8).enumerate() {
186 sum += block.iter().map(|&x| x.count_ones() as u16).sum::<u16>();
187 l12_rank += (sum as u128) << (i * 12);
188 }
189 l12_rank = (l12_rank << 44) | l1_rank;
190 l12_ranks.push(l12_rank.into());
191 }
192
193 RankedBits { bits, l12_ranks: l12_ranks.into_boxed_slice() }
194 }
195
196 pub fn size(&self) -> usize {
198 size_of_val(self) + size_of_val(self.bits.as_ref()) + size_of_val(self.l12_ranks.as_ref())
199 }
200}
201
202impl RankedBitsAccess for RankedBits {
204 #[inline]
205 fn rank(&self, idx: usize) -> Option<usize> {
206 unsafe { Self::rank_impl(&self.bits, &self.l12_ranks, idx) }
207 }
208}
209
210#[cfg(feature = "rkyv_derive")]
212impl RankedBitsAccess for ArchivedRankedBits {
213 #[inline]
214 fn rank(&self, idx: usize) -> Option<usize> {
215 unsafe { Self::rank_impl(&self.bits, &self.l12_ranks, idx) }
216 }
217}
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222 use bitvec::order::Lsb0;
223 use bitvec::vec::BitVec;
224 use rand::distributions::Standard;
225 use rand::Rng;
226
227 #[test]
228 fn test_rank_and_get() {
229 let bits = vec![
230 0b11001010, 0b00110111, 0b11110000, ];
234
235 let ranked_bits = RankedBits::new(bits.into_boxed_slice());
236 assert_eq!(ranked_bits.rank(0), None); assert_eq!(ranked_bits.rank(7), Some(3)); }
239
240 #[test]
241 fn test_random_bits() {
242 let rng = rand::thread_rng();
243 let bits: Vec<u64> = rng.sample_iter(Standard).take(1001).collect();
244 let ranked_bits = RankedBits::new(bits.clone().into_boxed_slice());
245 let bv = BitVec::<u64, Lsb0>::from_slice(&bits);
246
247 for idx in 0..bv.len() {
248 if bv[idx] {
249 assert_eq!(
250 ranked_bits.rank(idx).unwrap(),
251 bv[..idx].count_ones(),
252 "Rank mismatch at index {}",
253 idx
254 );
255 }
256 }
257 }
258
259 #[cfg(feature = "serde")]
260 #[test]
261 fn test_serde() {
262 let rng = rand::thread_rng();
263 let bits: Vec<u64> = rng.sample_iter(Standard).take(1001).collect();
264 let ranked_bits = RankedBits::new(bits.clone().into_boxed_slice());
265
266 let bytes = rmp_serde::to_vec(&ranked_bits).unwrap();
267 let de: RankedBits = rmp_serde::from_slice(&bytes).unwrap();
268
269 for idx in 0..bits.len() * 64 {
272 assert_eq!(ranked_bits.rank(idx), de.rank(idx), "rank mismatch at {}", idx);
273 }
274 }
275}