Avoid overcounting versions in batch prefetcher (#10350)

This commit is contained in:
konsti
2025-01-07 15:12:18 +01:00
committed by GitHub
parent 3cbf8ab7b1
commit 14a9008e54
2 changed files with 16 additions and 12 deletions
@@ -3,7 +3,7 @@ use std::sync::Arc;
use itertools::Itertools;
use pubgrub::{Range, Ranges, Term};
use rustc_hash::FxHashMap;
use rustc_hash::{FxHashMap, FxHashSet};
use tokio::sync::mpsc::Sender;
use tracing::{debug, trace};
@@ -43,7 +43,7 @@ enum BatchPrefetchStrategy {
#[derive(Clone)]
pub(crate) struct BatchPrefetcher {
// Types to determine whether we need to prefetch.
tried_versions: FxHashMap<PackageName, usize>,
tried_versions: FxHashMap<PackageName, FxHashSet<Version>>,
last_prefetch: FxHashMap<PackageName, usize>,
// Types to execute the prefetch.
prefetch_runner: BatchPrefetcherRunner,
@@ -142,7 +142,7 @@ impl BatchPrefetcher {
}
/// Each time we tried a version for a package, we register that here.
pub(crate) fn version_tried(&mut self, package: &PubGrubPackage) {
pub(crate) fn version_tried(&mut self, package: &PubGrubPackage, version: &Version) {
// Only track base packages, no virtual packages from extras.
let PubGrubPackageInner::Package {
name,
@@ -153,7 +153,10 @@ impl BatchPrefetcher {
else {
return;
};
*self.tried_versions.entry(name.clone()).or_default() += 1;
self.tried_versions
.entry(name.clone())
.or_default()
.insert(version.clone());
}
/// After 5, 10, 20, 40 tried versions, prefetch that many versions to start early but not
@@ -170,7 +173,7 @@ impl BatchPrefetcher {
return (0, false);
};
let num_tried = self.tried_versions.get(name).copied().unwrap_or_default();
let num_tried = self.tried_versions.get(name).map_or(0, FxHashSet::len);
let previous_prefetch = self.last_prefetch.get(name).copied().unwrap_or_default();
let do_prefetch = (num_tried >= 5 && previous_prefetch < 5)
|| (num_tried >= 10 && previous_prefetch < 10)
@@ -180,12 +183,13 @@ impl BatchPrefetcher {
}
/// Log stats about how many versions we tried.
///
/// Note that they may be inflated when we count the same version repeatedly during
/// backtracking.
pub(crate) fn log_tried_versions(&self) {
let total_versions: usize = self.tried_versions.values().sum();
let mut tried_versions: Vec<_> = self.tried_versions.iter().collect();
let total_versions: usize = self.tried_versions.values().map(FxHashSet::len).sum();
let mut tried_versions: Vec<_> = self
.tried_versions
.iter()
.map(|(name, versions)| (name, versions.len()))
.collect();
tried_versions.sort_by(|(p1, c1), (p2, c2)| {
c1.cmp(c2)
.reverse()
+2 -2
View File
@@ -476,8 +476,6 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
// (idempotent due to caching).
self.request_package(next_package, url, index, &request_sink)?;
state.prefetcher.version_tried(next_package);
let version = if let Some(version) = state.initial_version.take() {
// If we just forked based on platform support, we can skip version selection,
// since the fork operation itself already selected the appropriate version for
@@ -571,6 +569,8 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
version
};
state.prefetcher.version_tried(next_package, &version);
self.on_progress(next_package, &version);
if !state