Skip to content

Commit cd5a90f

Browse files
committed
Auto merge of #86031 - ssomers:btree_lazy_iterator, r=Mark-Simulacrum
BTree: lazily locate leaves in rangeless iterators BTree iterators always locate both the first and last leaf edge and often only need either one, i.e., whenever they are traversed in a single direction, like in for-loops and in the common use of `iter().next()` or `iter().next_back()` to retrieve the first or last key/value-pair (#62924). It's fairly easy to avoid because the iterators with this disadvantage already are quite separate from other iterators. r? `@Mark-Simulacrum`
2 parents 2827db2 + 35d02e2 commit cd5a90f

File tree

2 files changed

+171
-68
lines changed

2 files changed

+171
-68
lines changed

library/alloc/src/collections/btree/map.rs

+26-31
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use core::ops::{Index, RangeBounds};
99
use core::ptr;
1010

1111
use super::borrow::DormantMutRef;
12-
use super::navigate::LeafRange;
12+
use super::navigate::{LazyLeafRange, LeafRange};
1313
use super::node::{self, marker, ForceResult::*, Handle, NodeRef, Root};
1414
use super::search::SearchResult::*;
1515

@@ -291,7 +291,7 @@ where
291291
/// [`iter`]: BTreeMap::iter
292292
#[stable(feature = "rust1", since = "1.0.0")]
293293
pub struct Iter<'a, K: 'a, V: 'a> {
294-
range: Range<'a, K, V>,
294+
range: LazyLeafRange<marker::Immut<'a>, K, V>,
295295
length: usize,
296296
}
297297

@@ -309,10 +309,20 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
309309
///
310310
/// [`iter_mut`]: BTreeMap::iter_mut
311311
#[stable(feature = "rust1", since = "1.0.0")]
312-
#[derive(Debug)]
313312
pub struct IterMut<'a, K: 'a, V: 'a> {
314-
range: RangeMut<'a, K, V>,
313+
range: LazyLeafRange<marker::ValMut<'a>, K, V>,
315314
length: usize,
315+
316+
// Be invariant in `K` and `V`
317+
_marker: PhantomData<&'a mut (K, V)>,
318+
}
319+
320+
#[stable(feature = "collection_debug", since = "1.17.0")]
321+
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> {
322+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
323+
let range = Iter { range: self.range.reborrow(), length: self.length };
324+
f.debug_list().entries(range).finish()
325+
}
316326
}
317327

318328
/// An owning iterator over the entries of a `BTreeMap`.
@@ -323,16 +333,15 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
323333
/// [`into_iter`]: IntoIterator::into_iter
324334
#[stable(feature = "rust1", since = "1.0.0")]
325335
pub struct IntoIter<K, V> {
326-
range: LeafRange<marker::Dying, K, V>,
336+
range: LazyLeafRange<marker::Dying, K, V>,
327337
length: usize,
328338
}
329339

330340
impl<K, V> IntoIter<K, V> {
331341
/// Returns an iterator of references over the remaining items.
332342
#[inline]
333343
pub(super) fn iter(&self) -> Iter<'_, K, V> {
334-
let range = Range { inner: self.range.reborrow() };
335-
Iter { range: range, length: self.length }
344+
Iter { range: self.range.reborrow(), length: self.length }
336345
}
337346
}
338347

@@ -1312,7 +1321,7 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
13121321
None
13131322
} else {
13141323
self.length -= 1;
1315-
Some(unsafe { self.range.inner.next_unchecked() })
1324+
Some(unsafe { self.range.next_unchecked() })
13161325
}
13171326
}
13181327

@@ -1343,7 +1352,7 @@ impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, K, V> {
13431352
None
13441353
} else {
13451354
self.length -= 1;
1346-
Some(unsafe { self.range.inner.next_back_unchecked() })
1355+
Some(unsafe { self.range.next_back_unchecked() })
13471356
}
13481357
}
13491358
}
@@ -1381,7 +1390,7 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> {
13811390
None
13821391
} else {
13831392
self.length -= 1;
1384-
Some(unsafe { self.range.inner.next_unchecked() })
1393+
Some(unsafe { self.range.next_unchecked() })
13851394
}
13861395
}
13871396

@@ -1409,7 +1418,7 @@ impl<'a, K: 'a, V: 'a> DoubleEndedIterator for IterMut<'a, K, V> {
14091418
None
14101419
} else {
14111420
self.length -= 1;
1412-
Some(unsafe { self.range.inner.next_back_unchecked() })
1421+
Some(unsafe { self.range.next_back_unchecked() })
14131422
}
14141423
}
14151424
}
@@ -1428,7 +1437,7 @@ impl<'a, K, V> IterMut<'a, K, V> {
14281437
/// Returns an iterator of references over the remaining items.
14291438
#[inline]
14301439
pub(super) fn iter(&self) -> Iter<'_, K, V> {
1431-
Iter { range: self.range.iter(), length: self.length }
1440+
Iter { range: self.range.reborrow(), length: self.length }
14321441
}
14331442
}
14341443

@@ -1444,7 +1453,7 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
14441453

14451454
IntoIter { range: full_range, length: me.length }
14461455
} else {
1447-
IntoIter { range: LeafRange::none(), length: 0 }
1456+
IntoIter { range: LazyLeafRange::none(), length: 0 }
14481457
}
14491458
}
14501459
}
@@ -1902,14 +1911,6 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
19021911
}
19031912
}
19041913

1905-
impl<'a, K, V> RangeMut<'a, K, V> {
1906-
/// Returns an iterator of references over the remaining items.
1907-
#[inline]
1908-
pub(super) fn iter(&self) -> Range<'_, K, V> {
1909-
Range { inner: self.inner.reborrow() }
1910-
}
1911-
}
1912-
19131914
#[stable(feature = "btree_range", since = "1.17.0")]
19141915
impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
19151916
fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
@@ -2066,9 +2067,9 @@ impl<K, V> BTreeMap<K, V> {
20662067
if let Some(root) = &self.root {
20672068
let full_range = root.reborrow().full_range();
20682069

2069-
Iter { range: Range { inner: full_range }, length: self.length }
2070+
Iter { range: full_range, length: self.length }
20702071
} else {
2071-
Iter { range: Range { inner: LeafRange::none() }, length: 0 }
2072+
Iter { range: LazyLeafRange::none(), length: 0 }
20722073
}
20732074
}
20742075

@@ -2098,15 +2099,9 @@ impl<K, V> BTreeMap<K, V> {
20982099
if let Some(root) = &mut self.root {
20992100
let full_range = root.borrow_valmut().full_range();
21002101

2101-
IterMut {
2102-
range: RangeMut { inner: full_range, _marker: PhantomData },
2103-
length: self.length,
2104-
}
2102+
IterMut { range: full_range, length: self.length, _marker: PhantomData }
21052103
} else {
2106-
IterMut {
2107-
range: RangeMut { inner: LeafRange::none(), _marker: PhantomData },
2108-
length: 0,
2109-
}
2104+
IterMut { range: LazyLeafRange::none(), length: 0, _marker: PhantomData }
21102105
}
21112106
}
21122107

0 commit comments

Comments
 (0)