From a0ba18fd594c08102b642cd783b8aedb5e041bbe Mon Sep 17 00:00:00 2001 From: Paul Schoenfelder Date: Thu, 16 Apr 2020 17:51:11 -0400 Subject: [PATCH] avoid unnecessary recursion in iterators --- src/iter.rs | 102 ++++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/iter.rs b/src/iter.rs index d9d8f254..e2a2ba65 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -53,27 +53,27 @@ impl Iterator for OwningIter { #[inline] fn next(&mut self) -> Option { - if let Some(current) = self.current.as_mut() { - if let Some((k, v)) = current.next() { - return Some((k, v.into_inner())); + 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; - } + 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; - - self.next() + //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; + } } } @@ -155,24 +155,24 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter #[inline] fn next(&mut self) -> Option { - if let Some(current) = self.current.as_mut() { - if let Some((k, v)) = current.1.next() { - let guard = current.0.clone(); - return Some(RefMulti::new(guard, k, v.get())); + loop { + if let Some(current) = self.current.as_mut() { + if let Some((k, v)) = current.1.next() { + let guard = current.0.clone(); + return 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; + if self.shard_i == self.map._shard_count() { + return None; + } - self.next() + 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; + } } } @@ -231,28 +231,28 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter #[inline] fn next(&mut self) -> Option { - 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)); + 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; + if self.shard_i == self.map._shard_count() { + return None; + } - self.next() + 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; + } } }