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}