make some things guaranteed to be deterministic (#1065)

This PR replaces a few uses of hash maps/sets with btree maps/sets and
index maps/sets. This has the benefit of guaranteeing a deterministic
order of iteration.

I made these changes as part of looking into a flaky test.
Unfortunately, I'm not optimistic that anything here will actually fix
the flaky test, since I don't believe anything was actually dependent
on the order of iteration.
This commit is contained in:
Andrew Gallant 2024-01-23 20:30:33 -05:00 committed by GitHub
parent 1b3a3f4e80
commit eebc2f340a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 53 additions and 17 deletions

View file

@ -1,9 +1,10 @@
use std::collections::BTreeSet;
use std::convert::Infallible;
use std::fmt::Formatter;
use indexmap::IndexMap;
use pubgrub::range::Range;
use pubgrub::report::{DefaultStringReporter, DerivationTree, Reporter};
use rustc_hash::FxHashMap;
use thiserror::Error;
use url::Url;
@ -112,7 +113,7 @@ impl From<pubgrub::error::PubGrubError<PubGrubPackage, Range<Version>, Infallibl
ResolveError::NoSolution(NoSolutionError {
derivation_tree,
// The following should be populated before display for the best error messages
available_versions: FxHashMap::default(),
available_versions: IndexMap::default(),
selector: None,
python_requirement: None,
})
@ -131,7 +132,7 @@ impl From<pubgrub::error::PubGrubError<PubGrubPackage, Range<Version>, Infallibl
#[derive(Debug)]
pub struct NoSolutionError {
derivation_tree: DerivationTree<PubGrubPackage, Range<Version>>,
available_versions: FxHashMap<PubGrubPackage, Vec<Version>>,
available_versions: IndexMap<PubGrubPackage, BTreeSet<Version>>,
selector: Option<CandidateSelector>,
python_requirement: Option<PythonRequirement>,
}
@ -170,19 +171,21 @@ impl NoSolutionError {
python_requirement: &PythonRequirement,
package_versions: &OnceMap<PackageName, VersionMap>,
) -> Self {
let mut available_versions = FxHashMap::default();
let mut available_versions = IndexMap::default();
for package in self.derivation_tree.packages() {
match package {
PubGrubPackage::Root(_) => {}
PubGrubPackage::Python(PubGrubPython::Installed) => {
available_versions.insert(
package.clone(),
vec![python_requirement.installed().clone()],
BTreeSet::from([python_requirement.installed().clone()]),
);
}
PubGrubPackage::Python(PubGrubPython::Target) => {
available_versions
.insert(package.clone(), vec![python_requirement.target().clone()]);
available_versions.insert(
package.clone(),
BTreeSet::from([python_requirement.target().clone()]),
);
}
PubGrubPackage::Package(name, ..) => {
if let Some(entry) = package_versions.get(name) {