1use crate::FrozenHashMap;
2
3pub struct RawBucketIter<'a> {
5 base: *const u8,
6 cur: *const u8,
7 end: *const u8,
8 bucket_size: usize,
9 items: usize,
10 _memory: &'a [u8],
11}
12
13impl<S> FrozenHashMap<S> {
14 pub fn raw_iter(&self) -> Option<RawBucketIter<'_>> {
15 if let Some((offset, layout)) = self.hashmap.table.table.reallocation(&self.table_layout) {
16 if self.memory.is_empty() {
17 return None;
18 }
19 if layout.size() != self.memory.len() {
20 return None;
21 }
22 let base = unsafe { self.memory.as_ptr().add(offset) };
23 Some(RawBucketIter {
24 base,
25 cur: base,
26 end: unsafe { self.memory.as_ptr().add(self.memory.len()) },
27 bucket_size: self.table_layout.size,
28 items: self.hashmap.table.table.items,
29 _memory: &self.memory,
30 })
31 } else {
32 None
33 }
34 }
35}
36
37impl<'a> Iterator for RawBucketIter<'a> {
38 type Item = *const u8;
40
41 fn next(&mut self) -> Option<Self::Item> {
42 if self.items == 0 {
43 return None;
44 }
45 while self.cur < self.end {
46 let full = (unsafe { *self.cur } & 0x80) == 0;
48 self.cur = unsafe { self.cur.add(1) };
49 if full {
50 let offset = unsafe { self.cur.offset_from(self.base) } * self.bucket_size as isize;
51 assert!(offset >= 0);
52 self.items -= 1;
53 return Some(unsafe { self.base.sub(offset as usize) });
54 }
55 }
56 return None;
57 }
58
59 #[inline]
60 fn size_hint(&self) -> (usize, Option<usize>) {
61 (self.items, Some(self.items))
62 }
63}