flurry/iter/
mod.rs

1mod traverser;
2pub(crate) use traverser::NodeIter;
3
4use crate::reclaim::{Guard, Shared};
5use std::sync::atomic::Ordering;
6
7/// An iterator over a map's entries.
8///
9/// See [`HashMap::iter`](crate::HashMap::iter) for details.
10#[derive(Debug)]
11pub struct Iter<'g, K, V> {
12    pub(crate) node_iter: NodeIter<'g, K, V>,
13    pub(crate) guard: &'g Guard<'g>,
14}
15
16impl<'g, K, V> Iter<'g, K, V> {
17    pub(crate) fn next_internal(&mut self) -> Option<(&'g K, Shared<'g, V>)> {
18        let node = self.node_iter.next()?;
19        let value = node.value.load(Ordering::SeqCst, self.guard);
20        Some((&node.key, value))
21    }
22}
23
24impl<'g, K, V> Iterator for Iter<'g, K, V> {
25    type Item = (&'g K, &'g V);
26    fn next(&mut self) -> Option<Self::Item> {
27        // safety: flurry does not drop or move until after guard drop
28        self.next_internal()
29            .map(|(k, v)| unsafe { (k, &**v.deref()) })
30    }
31}
32
33/// An iterator over a map's keys.
34///
35/// See [`HashMap::keys`](crate::HashMap::keys) for details.
36#[derive(Debug)]
37pub struct Keys<'g, K, V> {
38    pub(crate) node_iter: NodeIter<'g, K, V>,
39}
40
41impl<'g, K, V> Iterator for Keys<'g, K, V> {
42    type Item = &'g K;
43    fn next(&mut self) -> Option<Self::Item> {
44        let node = self.node_iter.next()?;
45        Some(&node.key)
46    }
47}
48
49/// An iterator over a map's values.
50///
51/// See [`HashMap::values`](crate::HashMap::values) for details.
52#[derive(Debug)]
53pub struct Values<'g, K, V> {
54    pub(crate) node_iter: NodeIter<'g, K, V>,
55    pub(crate) guard: &'g Guard<'g>,
56}
57
58impl<'g, K, V> Iterator for Values<'g, K, V> {
59    type Item = &'g V;
60    fn next(&mut self) -> Option<Self::Item> {
61        let node = self.node_iter.next()?;
62        let value = node.value.load(Ordering::SeqCst, self.guard);
63        // safety: flurry does not drop or move until after guard drop
64        let value = unsafe { value.deref() };
65        Some(value)
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use crate::HashMap;
72    use std::collections::HashSet;
73    use std::iter::FromIterator;
74
75    #[test]
76    fn iter() {
77        let map = HashMap::<usize, usize>::new();
78
79        let guard = map.guard();
80        map.insert(1, 42, &guard);
81        map.insert(2, 84, &guard);
82
83        let guard = map.guard();
84        assert_eq!(
85            map.iter(&guard).collect::<HashSet<(&usize, &usize)>>(),
86            HashSet::from_iter(vec![(&1, &42), (&2, &84)])
87        );
88    }
89
90    #[test]
91    fn keys() {
92        let map = HashMap::<usize, usize>::new();
93
94        let guard = map.guard();
95        map.insert(1, 42, &guard);
96        map.insert(2, 84, &guard);
97
98        let guard = map.guard();
99        assert_eq!(
100            map.keys(&guard).collect::<HashSet<&usize>>(),
101            HashSet::from_iter(vec![&1, &2])
102        );
103    }
104
105    #[test]
106    fn values() {
107        let map = HashMap::<usize, usize>::new();
108
109        let mut guard = map.guard();
110        map.insert(1, 42, &guard);
111        map.insert(2, 84, &guard);
112        guard.refresh();
113
114        assert_eq!(
115            map.values(&guard).collect::<HashSet<&usize>>(),
116            HashSet::from_iter(vec![&42, &84])
117        );
118    }
119}