Skip to content

Commit 9043918

Browse files
committed
Use BTreeMap::range to avoid iterating over unnecessary versions
1 parent 7bbec6b commit 9043918

File tree

1 file changed

+48
-15
lines changed

1 file changed

+48
-15
lines changed

crates/uv-resolver/src/version_map.rs

+48-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use pubgrub::Range;
21
use std::collections::btree_map::{BTreeMap, Entry};
2+
use std::collections::Bound;
3+
use std::ops::RangeBounds;
34
use std::sync::OnceLock;
5+
6+
use pubgrub::Ranges;
47
use tracing::instrument;
58

69
use uv_client::{OwnedArchive, SimpleMetadata, VersionFiles};
@@ -156,8 +159,8 @@ impl VersionMap {
156159
/// for each version.
157160
pub(crate) fn iter(
158161
&self,
159-
range: &Range<Version>,
160-
) -> impl DoubleEndedIterator<Item = (&Version, VersionMapDistHandle)> + ExactSizeIterator {
162+
range: &Ranges<Version>,
163+
) -> impl DoubleEndedIterator<Item = (&Version, VersionMapDistHandle)> {
161164
// Performance optimization: If we only have a single version, return that version directly.
162165
if let Some(version) = range.as_singleton() {
163166
either::Either::Left(match self.inner {
@@ -185,20 +188,24 @@ impl VersionMap {
185188
} else {
186189
either::Either::Right(match self.inner {
187190
VersionMapInner::Eager(ref eager) => {
188-
either::Either::Left(eager.map.iter().map(|(version, dist)| {
189-
let version_map_dist = VersionMapDistHandle {
190-
inner: VersionMapDistHandleInner::Eager(dist),
191-
};
192-
(version, version_map_dist)
193-
}))
191+
either::Either::Left(eager.map.range(BoundingRange::from(range)).map(
192+
|(version, dist)| {
193+
let version_map_dist = VersionMapDistHandle {
194+
inner: VersionMapDistHandleInner::Eager(dist),
195+
};
196+
(version, version_map_dist)
197+
},
198+
))
194199
}
195200
VersionMapInner::Lazy(ref lazy) => {
196-
either::Either::Right(lazy.map.iter().map(|(version, dist)| {
197-
let version_map_dist = VersionMapDistHandle {
198-
inner: VersionMapDistHandleInner::Lazy { lazy, dist },
199-
};
200-
(version, version_map_dist)
201-
}))
201+
either::Either::Right(lazy.map.range(BoundingRange::from(range)).map(
202+
|(version, dist)| {
203+
let version_map_dist = VersionMapDistHandle {
204+
inner: VersionMapDistHandleInner::Lazy { lazy, dist },
205+
};
206+
(version, version_map_dist)
207+
},
208+
))
202209
}
203210
})
204211
}
@@ -609,3 +616,29 @@ struct SimplePrioritizedDist {
609616
/// of writing, is to use `--exclude-newer 1900-01-01`.)
610617
dist: OnceLock<Option<PrioritizedDist>>,
611618
}
619+
620+
/// A range that can be used to iterate over a subset of a [`BTreeMap`].
621+
#[derive(Debug)]
622+
struct BoundingRange<'a> {
623+
min: Bound<&'a Version>,
624+
max: Bound<&'a Version>,
625+
}
626+
627+
impl<'a> From<&'a Ranges<Version>> for BoundingRange<'a> {
628+
fn from(value: &'a Ranges<Version>) -> Self {
629+
let (min, max) = value
630+
.bounding_range()
631+
.unwrap_or((Bound::Unbounded, Bound::Unbounded));
632+
Self { min, max }
633+
}
634+
}
635+
636+
impl<'a> RangeBounds<Version> for BoundingRange<'a> {
637+
fn start_bound(&self) -> Bound<&'a Version> {
638+
self.min
639+
}
640+
641+
fn end_bound(&self) -> Bound<&'a Version> {
642+
self.max
643+
}
644+
}

0 commit comments

Comments
 (0)