Skip to main content

robinxx_map/
iter.rs

1//! Safe traversal iterators: `Iter`, `IterMut`, `Keys`, `Values`, `Drain`.
2//!
3//! Guarantees yield-safe iteration over `SoA` blocks with invariant-checked traversal state.
4//! Iterators hold internal `MutexGuard` to block concurrent mutation during traversal.
5
6use crate::hash::RobinHoodKey;
7use crate::sync::MutexGuard;
8use crate::table::RawTable;
9use core::marker::PhantomData;
10use core::ptr;
11
12/// Iterator over immutable key-value pairs.
13///
14/// # Summary
15/// Yields `(&K, &V)` for all occupied slots.
16///
17/// # Description
18/// Traverses metadata array linearly, yielding initialized entries.
19/// Order is undefined and may vary across runs.
20///
21/// # Examples
22/// ```
23/// use robinxx_map::RobinHoodMap;
24/// let map = RobinHoodMap::new();
25/// map.insert(1, "a");
26/// for (k, v) in map.iter() {
27///     println!("{}: {}", k, v);
28/// }
29/// ```
30///
31/// # Panics
32/// Never panics.
33///
34/// # Errors
35/// Not applicable.
36///
37/// # Safety
38/// Iterator borrows lock. Thread-safe.
39///
40/// # See Also
41/// - [`IterMut`]
42pub struct Iter<'a, K: RobinHoodKey + PartialEq, V> {
43    guard: MutexGuard<'a, RawTable<K, V>>,
44    idx: usize,
45    remaining: usize,
46    _marker: PhantomData<(K, V)>,
47}
48
49impl<'a, K: RobinHoodKey + PartialEq, V> Iter<'a, K, V> {
50    /// Creates a new immutable iterator over the map.
51    ///
52    /// # Summary
53    /// Initializes traversal state from a locked `RawTable`.
54    ///
55    /// # Description
56    /// Stores the mutex guard and resets the cursor to index 0. Used internally
57    /// by `RobinHoodMap::iter()`.
58    ///
59    /// # Examples
60    /// Internal use only.
61    ///
62    /// # Panics
63    /// Never panics.
64    ///
65    /// # Errors
66    /// Not applicable.
67    ///
68    /// # Safety
69    /// Caller must provide an active `MutexGuard` to prevent concurrent mutation.
70    ///
71    /// # See Also
72    /// - [`RobinHoodMap::iter`](crate::map::RobinHoodMap::iter)
73    #[inline]
74    pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
75        let remaining = guard.size();
76        Self {
77            guard,
78            idx: 0,
79            remaining,
80            _marker: PhantomData,
81        }
82    }
83}
84
85impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for Iter<'a, K, V> {
86    type Item = (&'a K, &'a V);
87    fn next(&mut self) -> Option<Self::Item> {
88        while self.remaining > 0 {
89            let meta = unsafe { *self.guard.meta_ptr.add(self.idx) };
90            if meta != 0 {
91                let k = unsafe { &*self.guard.keys_ptr.add(self.idx) };
92                let v = unsafe { &*self.guard.vals_ptr.add(self.idx) };
93                self.idx += 1;
94                self.remaining -= 1;
95                return Some((k, v));
96            }
97            self.idx += 1;
98        }
99        None
100    }
101}
102
103/// Iterator over mutable values.
104///
105/// # Summary
106/// Yields `&mut V` for all occupied slots.
107///
108/// # Description
109/// Allows in-place mutation while preserving key stability.
110///
111/// # Examples
112/// ```
113/// use robinxx_map::RobinHoodMap;
114/// let map = RobinHoodMap::new();
115/// map.insert(1, 0);
116/// for v in map.iter_mut() { *v = 42; }
117/// ```
118///
119/// # Panics
120/// Never panics.
121///
122/// # Errors
123/// Not applicable.
124///
125/// # Safety
126/// Not applicable. This is a safe function, thread-safety is guaranteed
127/// internally by `SpinMutex` acquisition.
128///
129/// # See Also
130/// - [`Iter`]
131pub struct IterMut<'a, K: RobinHoodKey + PartialEq, V> {
132    guard: MutexGuard<'a, RawTable<K, V>>,
133    idx: usize,
134    remaining: usize,
135    _marker: PhantomData<K>,
136}
137
138impl<'a, K: RobinHoodKey + PartialEq, V> IterMut<'a, K, V> {
139    /// Creates a new mutable iterator over the map.
140    ///
141    /// # Summary
142    /// Initializes traversal state from a locked `RawTable`.
143    ///
144    /// # Description
145    /// Stores the mutex guard and resets the cursor to index 0. Used internally
146    /// by `RobinHoodMap::iter_mut()`.
147    ///
148    /// # Examples
149    /// Internal use only.
150    ///
151    /// # Panics
152    /// Never panics.
153    ///
154    /// # Errors
155    /// Not applicable.
156    ///
157    /// # Safety
158    /// Caller must provide an active `MutexGuard` to ensure exclusive access.
159    ///
160    /// # See Also
161    /// - [`RobinHoodMap::iter_mut`](crate::map::RobinHoodMap::iter_mut)
162    #[inline]
163    pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
164        let remaining = guard.size();
165        Self {
166            guard,
167            idx: 0,
168            remaining,
169            _marker: PhantomData,
170        }
171    }
172}
173
174impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for IterMut<'a, K, V> {
175    type Item = &'a mut V;
176    fn next(&mut self) -> Option<Self::Item> {
177        while self.remaining > 0 {
178            let meta = unsafe { *self.guard.meta_ptr.add(self.idx) };
179            if meta != 0 {
180                let v = unsafe { &mut *self.guard.vals_ptr.add(self.idx) };
181                self.idx += 1;
182                self.remaining -= 1;
183                return Some(v);
184            }
185            self.idx += 1;
186        }
187        None
188    }
189}
190
191/// Iterator over immutable keys.
192///
193/// # Summary
194/// Yields `&K` for all occupied slots.
195///
196/// # Description
197/// Projects key component from `Iter`.
198///
199/// # Examples
200/// ```
201/// use robinxx_map::RobinHoodMap;
202/// let map = RobinHoodMap::new();
203/// map.insert(1, "a");
204/// for k in map.keys() { println!("{}", k); }
205/// ```
206///
207/// # Panics
208/// Never panics.
209///
210/// # Errors
211/// Not applicable.
212///
213/// # Safety
214/// Not applicable. This is a safe function, thread-safety is guaranteed
215/// internally by `SpinMutex` acquisition.
216///
217/// # See Also
218/// - [`Iter`]
219pub struct Keys<'a, K: RobinHoodKey + PartialEq, V> {
220    inner: Iter<'a, K, V>,
221}
222
223impl<'a, K: RobinHoodKey + PartialEq, V> Keys<'a, K, V> {
224    /// Creates a new keys iterator.
225    ///
226    /// # Summary
227    /// Wraps `Iter` to yield only keys.
228    ///
229    /// # Description
230    /// Delegates traversal to the inner `Iter` instance. Used internally
231    /// by `RobinHoodMap::keys()`.
232    ///
233    /// # Examples
234    /// Internal use only.
235    ///
236    /// # Panics
237    /// Never panics.
238    ///
239    /// # Errors
240    /// Not applicable.
241    ///
242    /// # Safety
243    /// Inherits lock guarantees from `Iter`.
244    ///
245    /// # See Also
246    /// - [`RobinHoodMap::keys`](crate::map::RobinHoodMap::keys)
247    #[inline]
248    pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
249        Self {
250            inner: Iter::new(guard),
251        }
252    }
253}
254
255impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for Keys<'a, K, V> {
256    type Item = &'a K;
257    fn next(&mut self) -> Option<Self::Item> {
258        self.inner.next().map(|(k, _)| k)
259    }
260}
261
262/// Iterator over immutable values.
263///
264/// # Summary
265/// Yields `&V` for all occupied slots.
266///
267/// # Description
268/// Projects value component from `Iter`.
269///
270/// # Examples
271/// ```
272/// use robinxx_map::RobinHoodMap;
273/// let map = RobinHoodMap::new();
274/// map.insert(1, "a");
275/// for v in map.values() { println!("{}", v); }
276/// ```
277///
278/// # Panics
279/// Never panics.
280///
281/// # Errors
282/// Not applicable.
283///
284/// # Safety
285/// Not applicable. This is a safe function, thread-safety is guaranteed
286/// internally by `SpinMutex` acquisition.
287///
288/// # See Also
289/// - [`Iter`]
290pub struct Values<'a, K: RobinHoodKey + PartialEq, V> {
291    inner: Iter<'a, K, V>,
292}
293
294impl<'a, K: RobinHoodKey + PartialEq, V> Values<'a, K, V> {
295    /// Creates a new values iterator.
296    ///
297    /// # Summary
298    /// Wraps `Iter` to yield only values.
299    ///
300    /// # Description
301    /// Delegates traversal to the inner `Iter` instance. Used internally
302    /// by `RobinHoodMap::values()`.
303    ///
304    /// # Examples
305    /// Internal use only.
306    ///
307    /// # Panics
308    /// Never panics.
309    ///
310    /// # Errors
311    /// Not applicable.
312    ///
313    /// # Safety
314    /// Inherits lock guarantees from `Iter`.
315    ///
316    /// # See Also
317    /// - [`RobinHoodMap::values`](crate::map::RobinHoodMap::values)
318    #[inline]
319    pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
320        Self {
321            inner: Iter::new(guard),
322        }
323    }
324}
325
326impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for Values<'a, K, V> {
327    type Item = &'a V;
328    fn next(&mut self) -> Option<Self::Item> {
329        self.inner.next().map(|(_, v)| v)
330    }
331}
332
333/// Iterator that clears and yields owned elements.
334///
335/// # Summary
336/// Yields `(K, V)` while dropping from map.
337///
338/// # Description
339/// Drains all occupied slots, dropping each after yield. Capacity retained.
340///
341/// # Examples
342/// ```
343/// use robinxx_map::RobinHoodMap;
344/// let map = RobinHoodMap::new();
345/// map.insert(1, "a");
346/// let items: Vec<_> = map.drain().collect();
347/// assert_eq!(items.len(), 1);
348/// ```
349///
350/// # Panics
351/// Never panics.
352///
353/// # Errors
354/// Not applicable.
355///
356/// # Safety
357/// Drops elements safely under lock.
358///
359/// # See Also
360/// - [`clear`](crate::map::RobinHoodMap::clear)
361pub struct Drain<'a, K: RobinHoodKey + PartialEq, V> {
362    guard: MutexGuard<'a, RawTable<K, V>>,
363    idx: usize,
364    remaining: usize,
365    _marker: PhantomData<(K, V)>,
366}
367
368impl<'a, K: RobinHoodKey + PartialEq, V> Drain<'a, K, V> {
369    /// Creates a new draining iterator.
370    ///
371    /// # Summary
372    /// Initializes traversal state for owned element extraction.
373    ///
374    /// # Description
375    /// Stores the mutex guard and captures current size. Used internally
376    /// by `RobinHoodMap::drain()`.
377    ///
378    /// # Examples
379    /// Internal use only.
380    ///
381    /// # Panics
382    /// Never panics.
383    ///
384    /// # Errors
385    /// Not applicable.
386    ///
387    /// # Safety
388    /// Caller must provide an active `MutexGuard` to prevent concurrent mutation
389    /// during drain operation.
390    ///
391    /// # See Also
392    /// - [`RobinHoodMap::drain`](crate::map::RobinHoodMap::drain)
393    #[inline]
394    pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
395        let remaining = (*guard).size();
396        Self {
397            guard,
398            idx: 0,
399            remaining,
400            _marker: PhantomData,
401        }
402    }
403}
404
405impl<K: RobinHoodKey + PartialEq, V> Iterator for Drain<'_, K, V> {
406    type Item = (K, V);
407    fn next(&mut self) -> Option<Self::Item> {
408        while self.remaining > 0 {
409            let meta = unsafe { *self.guard.meta_ptr.add(self.idx) };
410            if meta != 0 {
411                let k = unsafe { ptr::read(self.guard.keys_ptr.add(self.idx)) };
412                let v = unsafe { ptr::read(self.guard.vals_ptr.add(self.idx)) };
413                unsafe {
414                    *self.guard.meta_ptr.add(self.idx) = 0;
415                };
416                (*self.guard).decrement_size();
417                self.idx += 1;
418                self.remaining -= 1;
419                return Some((k, v));
420            }
421            self.idx += 1;
422        }
423        None
424    }
425}