sparse_hash_map/
sparse_array.rs1#[cfg(not(target_pointer_width = "64"))]
11use crate::popcount::popcount;
12#[cfg(target_pointer_width = "64")]
13use crate::popcount::popcountll;
14
15#[cfg(target_pointer_width = "64")]
20pub const BITMAP_NB_BITS: usize = 64;
21#[cfg(not(target_pointer_width = "64"))]
23pub const BITMAP_NB_BITS: usize = 32;
24
25#[cfg(target_pointer_width = "64")]
26const BUCKET_SHIFT: usize = 6;
27#[cfg(not(target_pointer_width = "64"))]
28const BUCKET_SHIFT: usize = 5;
29
30const BUCKET_MASK: usize = BITMAP_NB_BITS - 1;
31
32#[cfg(target_pointer_width = "64")]
34pub type Bitmap = u64;
35#[cfg(not(target_pointer_width = "64"))]
37pub type Bitmap = u32;
38
39#[inline]
41pub fn sparse_ibucket(ibucket: usize) -> usize {
42 ibucket >> BUCKET_SHIFT
43}
44
45#[inline]
47pub fn index_in_sparse_bucket(ibucket: usize) -> u8 {
48 (ibucket & BUCKET_MASK) as u8
49}
50
51#[inline]
53pub fn nb_sparse_buckets(bucket_count: usize) -> usize {
54 if bucket_count == 0 {
55 return 0;
56 }
57 let rounded = crate::util::round_up_to_power_of_two(bucket_count);
58 core::cmp::max(1, sparse_ibucket(rounded))
59}
60
61#[inline]
63pub(crate) fn popcount_bitmap(val: Bitmap) -> u8 {
64 #[cfg(target_pointer_width = "64")]
65 {
66 popcountll(val) as u8
67 }
68 #[cfg(not(target_pointer_width = "64"))]
69 {
70 popcount(val) as u8
71 }
72}
73
74pub struct SparseArray<T> {
79 values: Vec<T>,
80 bitmap_vals: Bitmap,
81 bitmap_deleted_vals: Bitmap,
82 last_array: bool,
83}
84
85impl<T> SparseArray<T> {
86 pub fn new() -> Self {
88 Self {
89 values: Vec::new(),
90 bitmap_vals: 0,
91 bitmap_deleted_vals: 0,
92 last_array: false,
93 }
94 }
95
96 #[inline]
98 pub fn is_empty(&self) -> bool {
99 self.values.is_empty()
100 }
101
102 #[inline]
104 pub fn len(&self) -> usize {
105 self.values.len()
106 }
107
108 #[cfg(test)]
113 #[inline]
114 pub fn capacity(&self) -> usize {
115 self.values.capacity()
116 }
117
118 #[inline]
120 pub fn last(&self) -> bool {
121 self.last_array
122 }
123
124 #[inline]
126 pub fn set_as_last(&mut self) {
127 self.last_array = true;
128 }
129
130 #[inline]
132 pub fn bitmap_vals(&self) -> Bitmap {
133 self.bitmap_vals
134 }
135
136 #[inline]
138 pub fn bitmap_deleted_vals(&self) -> Bitmap {
139 self.bitmap_deleted_vals
140 }
141
142 #[inline]
144 pub fn values(&self) -> &[T] {
145 &self.values
146 }
147
148 #[inline]
150 pub fn values_mut(&mut self) -> &mut [T] {
151 &mut self.values
152 }
153
154 #[inline]
156 pub fn has_value(&self, index: u8) -> bool {
157 (self.bitmap_vals & (1 as Bitmap) << index) != 0
158 }
159
160 #[inline]
162 pub fn has_deleted_value(&self, index: u8) -> bool {
163 (self.bitmap_deleted_vals & (1 as Bitmap) << index) != 0
164 }
165
166 #[inline]
168 pub fn index_to_offset(&self, index: u8) -> usize {
169 let mask = ((1 as Bitmap) << index).wrapping_sub(1);
170 popcount_bitmap(self.bitmap_vals & mask) as usize
171 }
172
173 pub fn offset_to_index(&self, offset: usize) -> u8 {
175 let mut bitmap = self.bitmap_vals;
176 let mut index: u8 = 0;
177 let mut nb_ones = 0;
178 while bitmap != 0 {
179 if bitmap & 0x1 == 1 {
180 if nb_ones == offset {
181 break;
182 }
183 nb_ones += 1;
184 }
185 index += 1;
186 bitmap >>= 1;
187 }
188 index
189 }
190
191 #[inline]
195 pub fn value(&self, index: u8) -> &T {
196 &self.values[self.index_to_offset(index)]
197 }
198
199 #[inline]
201 pub fn value_mut(&mut self, index: u8) -> &mut T {
202 let offset = self.index_to_offset(index);
203 &mut self.values[offset]
204 }
205
206 pub fn set(&mut self, index: u8, value: T, growth_step: usize) -> usize {
213 debug_assert!(!self.has_value(index));
214 let offset = self.index_to_offset(index);
215 if self.values.len() == self.values.capacity() {
216 self.values.reserve_exact(growth_step.max(1));
217 }
218 self.values.insert(offset, value);
219 self.bitmap_vals |= (1 as Bitmap) << index;
220 self.bitmap_deleted_vals &= !((1 as Bitmap) << index);
221 offset
222 }
223
224 pub fn remove_value(&mut self, offset: usize, index: u8) -> T {
228 debug_assert!(self.has_value(index));
229 let value = self.values.remove(offset);
230 self.bitmap_vals &= !((1 as Bitmap) << index);
231 self.bitmap_deleted_vals |= (1 as Bitmap) << index;
232 value
233 }
234
235 pub fn erase_all(&mut self) -> usize {
241 let removed = self.values.len();
242 self.values.clear();
243 self.bitmap_deleted_vals |= self.bitmap_vals;
244 self.bitmap_vals = 0;
245 removed
246 }
247
248 #[inline]
250 pub fn into_values(self) -> Vec<T> {
251 self.values
252 }
253
254 pub fn from_parts(bitmap_vals: Bitmap, bitmap_deleted_vals: Bitmap, values: Vec<T>) -> Self {
259 debug_assert_eq!(popcount_bitmap(bitmap_vals) as usize, values.len());
260 Self {
261 values,
262 bitmap_vals,
263 bitmap_deleted_vals,
264 last_array: false,
265 }
266 }
267}
268
269impl<T: Clone> Clone for SparseArray<T> {
270 fn clone(&self) -> Self {
271 Self {
272 values: self.values.clone(),
273 bitmap_vals: self.bitmap_vals,
274 bitmap_deleted_vals: self.bitmap_deleted_vals,
275 last_array: self.last_array,
276 }
277 }
278}
279
280impl<T> Default for SparseArray<T> {
281 fn default() -> Self {
282 Self::new()
283 }
284}
285
286#[cfg(test)]
287mod tests {
288 use super::*;
289
290 #[test]
293 fn capacity_grows_by_fixed_step() {
294 const STEP: usize = 4;
295 let mut array: SparseArray<i32> = SparseArray::new();
296 for index in 0..8u8 {
297 array.set(index, index as i32, STEP);
298 let expected = array.len().div_ceil(STEP) * STEP;
301 assert_eq!(array.capacity(), expected, "at len {}", array.len());
302 }
303 }
304
305 #[test]
306 fn a_larger_step_reserves_more_slack() {
307 let mut high: SparseArray<i32> = SparseArray::new();
308 let mut low: SparseArray<i32> = SparseArray::new();
309 high.set(0, 0, 2);
311 low.set(0, 0, 8);
312 assert_eq!(high.capacity(), 2);
313 assert_eq!(low.capacity(), 8);
314 }
315}