moka/cht/
iter.rs

1use std::hash::Hash;
2
3pub(crate) trait ScanningGet<K, V>
4where
5    K: Clone,
6    V: Clone,
7{
8    /// Returns a _clone_ of the value corresponding to the key.
9    fn scanning_get(&self, key: &K) -> Option<V>;
10
11    /// Returns a vec of keys in a specified segment of the concurrent hash table.
12    fn keys(&self, cht_segment: usize) -> Option<Vec<K>>;
13}
14
15pub(crate) struct Iter<'i, K, V> {
16    keys: Option<Vec<K>>,
17    map: &'i dyn ScanningGet<K, V>,
18    num_segments: usize,
19    seg_index: usize,
20    is_done: bool,
21}
22
23impl<'i, K, V> Iter<'i, K, V> {
24    pub(crate) fn with_single_cache_segment(
25        map: &'i dyn ScanningGet<K, V>,
26        num_segments: usize,
27    ) -> Self {
28        Self {
29            keys: None,
30            map,
31            num_segments,
32            seg_index: 0,
33            is_done: false,
34        }
35    }
36}
37
38impl<K, V> Iterator for Iter<'_, K, V>
39where
40    K: Eq + Hash + Clone + Send + Sync + 'static,
41    V: Clone + Send + Sync + 'static,
42{
43    type Item = (K, V);
44
45    fn next(&mut self) -> Option<Self::Item> {
46        if self.is_done {
47            return None;
48        }
49
50        while let Some(key) = self.next_key() {
51            if let Some(v) = self.map.scanning_get(&key) {
52                return Some((key, v));
53            }
54        }
55
56        self.is_done = true;
57        None
58    }
59}
60
61impl<K, V> Iter<'_, K, V>
62where
63    K: Eq + Hash + Clone + Send + Sync + 'static,
64    V: Clone + Send + Sync + 'static,
65{
66    fn next_key(&mut self) -> Option<K> {
67        while let Some(keys) = self.current_keys() {
68            if let key @ Some(_) = keys.pop() {
69                return key;
70            }
71        }
72        None
73    }
74
75    fn current_keys(&mut self) -> Option<&mut Vec<K>> {
76        // If keys is none or some but empty, try to get next keys.
77        while self.keys.as_ref().map_or(true, Vec::is_empty) {
78            // Adjust indices.
79            if self.seg_index >= self.num_segments {
80                return None;
81            }
82
83            self.keys = self.map.keys(self.seg_index);
84            self.seg_index += 1;
85        }
86
87        self.keys.as_mut()
88    }
89}