Skip to content

Commit 6b9915e

Browse files
authored
Merge pull request #5 from cuviper/iter-opt
Optimize the iterators and release 0.1.1
2 parents 2d9e930 + 1100437 commit 6b9915e

File tree

4 files changed

+88
-27
lines changed

4 files changed

+88
-27
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "ringmap"
33
edition = "2021"
4-
version = "0.1.0"
4+
version = "0.1.1"
55
documentation = "https://docs.rs/ringmap/"
66
repository = "https://github.com/indexmap-rs/ringmap"
77
license = "Apache-2.0 OR MIT"

RELEASES.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Releases
22

3+
## 0.1.1
4+
5+
- Optimized the branch behavior of the iterators.
6+
37
## 0.1.0
48

59
- Initial release, based on `indexmap v2.7.1`.

src/macros.rs

+14
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ macro_rules! iterator_methods {
9898
self.next_back()
9999
}
100100

101+
fn fold<Acc, F>(self, acc: Acc, f: F) -> Acc
102+
where
103+
F: FnMut(Acc, Self::Item) -> Acc,
104+
{
105+
self.iter.map($map_elt).fold(acc, f)
106+
}
107+
101108
fn collect<C>(self) -> C
102109
where
103110
C: FromIterator<Self::Item>,
@@ -120,6 +127,13 @@ macro_rules! double_ended_iterator_methods {
120127
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
121128
self.iter.nth_back(n).map($map_elt)
122129
}
130+
131+
fn rfold<Acc, F>(self, acc: Acc, f: F) -> Acc
132+
where
133+
F: FnMut(Acc, Self::Item) -> Acc,
134+
{
135+
self.iter.map($map_elt).rfold(acc, f)
136+
}
123137
};
124138
}
125139

src/map/iter.rs

+69-26
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ use super::core::RingMapCore;
22
use super::{Bucket, Entries, RingMap};
33

44
use alloc::collections::vec_deque::{self, VecDeque};
5-
use core::fmt;
65
use core::hash::{BuildHasher, Hash};
76
use core::iter::FusedIterator;
87
use core::ops::{Index, RangeBounds};
9-
use core::slice;
8+
use core::{fmt, mem, slice};
109

1110
impl<'a, K, V, S> IntoIterator for &'a RingMap<K, V, S> {
1211
type Item = (&'a K, &'a V);
@@ -64,7 +63,12 @@ impl<'a, K, V> Iterator for Buckets<'a, K, V> {
6463
fn next(&mut self) -> Option<Self::Item> {
6564
match self.head.next() {
6665
next @ Some(_) => next,
67-
None => self.tail.next(),
66+
None => {
67+
// Swap so the rest is found on the first branch next time.
68+
// (Like `VecDeque` does in its own iterators.)
69+
mem::swap(&mut self.head, &mut self.tail);
70+
self.head.next()
71+
}
6872
}
6973
}
7074

@@ -78,20 +82,26 @@ impl<'a, K, V> Iterator for Buckets<'a, K, V> {
7882
}
7983

8084
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
81-
if n < self.head.len() {
82-
return self.head.nth(n);
83-
}
84-
if self.head.len() > 0 {
85+
if n >= self.head.len() {
8586
n -= self.head.len();
8687
self.head = [].iter();
88+
mem::swap(&mut self.head, &mut self.tail);
8789
}
88-
self.tail.nth(n)
90+
self.head.nth(n)
8991
}
9092

9193
fn last(mut self) -> Option<Self::Item> {
9294
self.next_back()
9395
}
9496

97+
fn fold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
98+
where
99+
F: FnMut(Acc, Self::Item) -> Acc,
100+
{
101+
acc = self.head.fold(acc, &mut f);
102+
self.tail.fold(acc, &mut f)
103+
}
104+
95105
fn collect<C>(self) -> C
96106
where
97107
C: FromIterator<Self::Item>,
@@ -104,19 +114,30 @@ impl<K, V> DoubleEndedIterator for Buckets<'_, K, V> {
104114
fn next_back(&mut self) -> Option<Self::Item> {
105115
match self.tail.next_back() {
106116
next @ Some(_) => next,
107-
None => self.head.next_back(),
117+
None => {
118+
// Swap so the rest is found on the first branch next time.
119+
// (Like `VecDeque` does in its own iterators.)
120+
mem::swap(&mut self.head, &mut self.tail);
121+
self.tail.next_back()
122+
}
108123
}
109124
}
110125

111126
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
112-
if n < self.tail.len() {
113-
return self.tail.nth_back(n);
114-
}
115-
if self.tail.len() > 0 {
127+
if n >= self.tail.len() {
116128
n -= self.tail.len();
117129
self.tail = [].iter();
130+
mem::swap(&mut self.head, &mut self.tail);
118131
}
119-
self.head.nth_back(n)
132+
self.tail.nth_back(n)
133+
}
134+
135+
fn rfold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
136+
where
137+
F: FnMut(Acc, Self::Item) -> Acc,
138+
{
139+
acc = self.tail.rfold(acc, &mut f);
140+
self.head.rfold(acc, &mut f)
120141
}
121142
}
122143

@@ -180,7 +201,12 @@ impl<'a, K, V> Iterator for BucketsMut<'a, K, V> {
180201
fn next(&mut self) -> Option<Self::Item> {
181202
match self.head.next() {
182203
next @ Some(_) => next,
183-
None => self.tail.next(),
204+
None => {
205+
// Swap so the rest is found on the first branch next time.
206+
// (Like `VecDeque` does in its own iterators.)
207+
mem::swap(&mut self.head, &mut self.tail);
208+
self.head.next()
209+
}
184210
}
185211
}
186212

@@ -194,20 +220,26 @@ impl<'a, K, V> Iterator for BucketsMut<'a, K, V> {
194220
}
195221

196222
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
197-
if n < self.head.len() {
198-
return self.head.nth(n);
199-
}
200-
if self.head.len() > 0 {
223+
if n >= self.head.len() {
201224
n -= self.head.len();
202225
self.head = [].iter_mut();
226+
mem::swap(&mut self.head, &mut self.tail);
203227
}
204-
self.tail.nth(n)
228+
self.head.nth(n)
205229
}
206230

207231
fn last(mut self) -> Option<Self::Item> {
208232
self.next_back()
209233
}
210234

235+
fn fold<Acc, F>(self, acc: Acc, mut f: F) -> Acc
236+
where
237+
F: FnMut(Acc, Self::Item) -> Acc,
238+
{
239+
let acc = self.head.fold(acc, &mut f);
240+
self.tail.fold(acc, &mut f)
241+
}
242+
211243
fn collect<C>(self) -> C
212244
where
213245
C: FromIterator<Self::Item>,
@@ -220,19 +252,30 @@ impl<K, V> DoubleEndedIterator for BucketsMut<'_, K, V> {
220252
fn next_back(&mut self) -> Option<Self::Item> {
221253
match self.tail.next_back() {
222254
next @ Some(_) => next,
223-
None => self.head.next_back(),
255+
None => {
256+
// Swap so the rest is found on the first branch next time.
257+
// (Like `VecDeque` does in its own iterators.)
258+
mem::swap(&mut self.head, &mut self.tail);
259+
self.tail.next_back()
260+
}
224261
}
225262
}
226263

227264
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
228-
if n < self.tail.len() {
229-
return self.tail.nth_back(n);
230-
}
231-
if self.tail.len() > 0 {
265+
if n >= self.tail.len() {
232266
n -= self.tail.len();
233267
self.tail = [].iter_mut();
268+
mem::swap(&mut self.head, &mut self.tail);
234269
}
235-
self.head.nth_back(n)
270+
self.tail.nth_back(n)
271+
}
272+
273+
fn rfold<Acc, F>(self, acc: Acc, mut f: F) -> Acc
274+
where
275+
F: FnMut(Acc, Self::Item) -> Acc,
276+
{
277+
let acc = self.tail.rfold(acc, &mut f);
278+
self.head.rfold(acc, &mut f)
236279
}
237280
}
238281

0 commit comments

Comments
 (0)