use super::mapref::multiple::{RefMulti, RefMutMulti}; use super::util; use crate::lock::{RwLockReadGuard, RwLockWriteGuard}; use crate::t::Map; use crate::util::SharedValue; use crate::{DashMap, HashMap}; use core::hash::{BuildHasher, Hash}; use core::mem; use hashbrown::hash_map; use std::collections::hash_map::RandomState; use std::sync::Arc; /// Iterator over a DashMap yielding key value pairs. /// /// # Examples /// /// ``` /// use dashmap::DashMap; /// /// let map = DashMap::new(); /// map.insert("hello", "world"); /// map.insert("alex", "steve"); /// let pairs: Vec<(&'static str, &'static str)> = map.into_iter().collect(); /// assert_eq!(pairs.len(), 2); /// ``` pub struct OwningIter { map: DashMap, shard_i: usize, current: Option>, } impl OwningIter { pub(crate) fn new(map: DashMap) -> Self { Self { map, shard_i: 0, current: None, } } } type GuardOwningIter = hash_map::IntoIter>; impl Iterator for OwningIter { type Item = (K, V); fn next(&mut self) -> Option { loop { if let Some(current) = self.current.as_mut() { if let Some((k, v)) = current.next() { return Some((k, v.into_inner())); } } if self.shard_i == self.map._shard_count() { return None; } //let guard = unsafe { self.map._yield_read_shard(self.shard_i) }; let mut shard_wl = unsafe { self.map._yield_write_shard(self.shard_i) }; let hasher = self.map._hasher(); let map = mem::replace(&mut *shard_wl, HashMap::with_hasher(hasher)); drop(shard_wl); let iter = map.into_iter(); //unsafe { ptr::write(&mut self.current, Some((arcee, iter))); } self.current = Some(iter); self.shard_i += 1; } } } unsafe impl Send for OwningIter where K: Eq + Hash + Send, V: Send, S: BuildHasher + Clone + Send, { } unsafe impl Sync for OwningIter where K: Eq + Hash + Sync, V: Sync, S: BuildHasher + Clone + Sync, { } type GuardIter<'a, K, V, S> = ( Arc>>, hash_map::Iter<'a, K, SharedValue>, ); type GuardIterMut<'a, K, V, S> = ( Arc>>, hash_map::IterMut<'a, K, SharedValue>, ); /// Iterator over a DashMap yielding immutable references. /// /// # Examples /// /// ``` /// use dashmap::DashMap; /// /// let map = DashMap::new(); /// map.insert("hello", "world"); /// assert_eq!(map.iter().count(), 1); /// ``` pub struct Iter<'a, K, V, S = RandomState, M = DashMap> { map: &'a M, shard_i: usize, current: Option>, } impl<'a, 'i, K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for Iter<'i, K, V, S> { fn clone(&self) -> Self { Iter::new(self.map) } } unsafe impl<'a, 'i, K, V, S, M> Send for Iter<'i, K, V, S, M> where K: 'a + Eq + Hash + Send, V: 'a + Send, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>, { } unsafe impl<'a, 'i, K, V, S, M> Sync for Iter<'i, K, V, S, M> where K: 'a + Eq + Hash + Sync, V: 'a + Sync, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>, { } impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter<'a, K, V, S, M> { pub(crate) fn new(map: &'a M) -> Self { Self { map, shard_i: 0, current: None, } } } impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator for Iter<'a, K, V, S, M> { type Item = RefMulti<'a, K, V, S>; fn next(&mut self) -> Option { loop { if let Some(current) = self.current.as_mut() { if let Some((k, v)) = current.1.next() { let guard = current.0.clone(); return unsafe { Some(RefMulti::new(guard, k, v.get())) }; } } if self.shard_i == self.map._shard_count() { return None; } let guard = unsafe { self.map._yield_read_shard(self.shard_i) }; let sref: &HashMap = unsafe { util::change_lifetime_const(&*guard) }; let iter = sref.iter(); self.current = Some((Arc::new(guard), iter)); self.shard_i += 1; } } } /// Iterator over a DashMap yielding mutable references. /// /// # Examples /// /// ``` /// use dashmap::DashMap; /// /// let map = DashMap::new(); /// map.insert("Johnny", 21); /// map.iter_mut().for_each(|mut r| *r += 1); /// assert_eq!(*map.get("Johnny").unwrap(), 22); /// ``` pub struct IterMut<'a, K, V, S = RandomState, M = DashMap> { map: &'a M, shard_i: usize, current: Option>, } unsafe impl<'a, 'i, K, V, S, M> Send for IterMut<'i, K, V, S, M> where K: 'a + Eq + Hash + Send, V: 'a + Send, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>, { } unsafe impl<'a, 'i, K, V, S, M> Sync for IterMut<'i, K, V, S, M> where K: 'a + Eq + Hash + Sync, V: 'a + Sync, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>, { } impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> IterMut<'a, K, V, S, M> { pub(crate) fn new(map: &'a M) -> Self { Self { map, shard_i: 0, current: None, } } } impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator for IterMut<'a, K, V, S, M> { type Item = RefMutMulti<'a, K, V, S>; fn next(&mut self) -> Option { loop { if let Some(current) = self.current.as_mut() { if let Some((k, v)) = current.1.next() { let guard = current.0.clone(); unsafe { let k = util::change_lifetime_const(k); let v = &mut *v.as_ptr(); return Some(RefMutMulti::new(guard, k, v)); } } } if self.shard_i == self.map._shard_count() { return None; } let mut guard = unsafe { self.map._yield_write_shard(self.shard_i) }; let sref: &mut HashMap = unsafe { util::change_lifetime_mut(&mut *guard) }; let iter = sref.iter_mut(); self.current = Some((Arc::new(guard), iter)); self.shard_i += 1; } } } #[cfg(test)] mod tests { use crate::DashMap; #[test] fn iter_mut_manual_count() { let map = DashMap::new(); map.insert("Johnny", 21); assert_eq!(map.len(), 1); let mut c = 0; for shard in map.shards() { c += shard.write().iter_mut().count(); } assert_eq!(c, 1); } #[test] fn iter_mut_count() { let map = DashMap::new(); map.insert("Johnny", 21); assert_eq!(map.len(), 1); assert_eq!(map.iter_mut().count(), 1); } #[test] fn iter_count() { let map = DashMap::new(); map.insert("Johnny", 21); assert_eq!(map.len(), 1); assert_eq!(map.iter().count(), 1); } }