From 79714ba97418dbdd8cce54ecda1463e5411c7bc8 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Thu, 25 Apr 2019 16:09:26 -0400 Subject: [PATCH] combine the caching structs --- src/cargo/core/resolver/dep_cache.rs | 51 ++++++++++++---------------- src/cargo/core/resolver/mod.rs | 16 ++++----- 2 files changed, 28 insertions(+), 39 deletions(-) diff --git a/src/cargo/core/resolver/dep_cache.rs b/src/cargo/core/resolver/dep_cache.rs index 50020b42a26..75f96b7e3d9 100644 --- a/src/cargo/core/resolver/dep_cache.rs +++ b/src/cargo/core/resolver/dep_cache.rs @@ -1,13 +1,13 @@ //! There are 2 sources of facts for the resolver: //! -//! - The Registry tells us for a Dependency what versions are available to fulfil it. -//! - The Summary tells us for a version (and features) what dependencies need to be fulfilled for it to be activated. +//! - The `Registry` tells us for a `Dependency` what versions are available to fulfil it. +//! - The `Summary` tells us for a version (and features) what dependencies need to be fulfilled for it to be activated. //! //! These constitute immutable facts, the soled ground truth that all other inference depends on. //! Theoretically this could all be enumerated ahead of time, but we want to be lazy and only //! look up things we need to. The compromise is to cache the results as they are computed. //! -//! The structs in this module impl that cache in all the gory details +//! This module impl that cache in all the gory details use std::cmp::Ordering; use std::collections::{BTreeSet, HashMap, HashSet}; @@ -26,11 +26,18 @@ pub struct RegistryQueryer<'a> { pub registry: &'a mut (dyn Registry + 'a), replacements: &'a [(PackageIdSpec, Dependency)], try_to_use: &'a HashSet, - // If set the list of dependency candidates will be sorted by minimal - // versions first. That allows `cargo update -Z minimal-versions` which will - // specify minimum dependency versions to be used. + /// If set the list of dependency candidates will be sorted by minimal + /// versions first. That allows `cargo update -Z minimal-versions` which will + /// specify minimum dependency versions to be used. minimal_versions: bool, - cache: HashMap>>, + /// a cache of `Candidate`s that fulfil a `Dependency` + registry_cache: HashMap>>, + /// a cache of `Dependency`s that are required for a `Summary` + summary_cache: HashMap< + (Option, Summary, Method), + Rc<(HashSet, Rc>)>, + >, + /// all the cases we ended up using a supplied replacement used_replacements: HashMap, } @@ -46,7 +53,8 @@ impl<'a> RegistryQueryer<'a> { replacements, try_to_use, minimal_versions, - cache: HashMap::new(), + registry_cache: HashMap::new(), + summary_cache: HashMap::new(), used_replacements: HashMap::new(), } } @@ -62,7 +70,7 @@ impl<'a> RegistryQueryer<'a> { /// applied by performing a second query for what the override should /// return. pub fn query(&mut self, dep: &Dependency) -> CargoResult>> { - if let Some(out) = self.cache.get(dep).cloned() { + if let Some(out) = self.registry_cache.get(dep).cloned() { return Ok(out); } @@ -182,27 +190,10 @@ impl<'a> RegistryQueryer<'a> { let out = Rc::new(ret); - self.cache.insert(dep.clone(), out.clone()); + self.registry_cache.insert(dep.clone(), out.clone()); Ok(out) } -} - -pub struct DepsCache<'a> { - pub registry: RegistryQueryer<'a>, - cache: HashMap< - (Option, Summary, Method), - Rc<(HashSet, Rc>)>, - >, -} - -impl<'a> DepsCache<'a> { - pub fn new(registry: RegistryQueryer<'a>) -> Self { - DepsCache { - registry, - cache: HashMap::new(), - } - } /// Find out what dependencies will be added by activating `candidate`, /// with features described in `method`. Then look up in the `registry` @@ -217,7 +208,7 @@ impl<'a> DepsCache<'a> { // if we have calculated a result before, then we can just return it, // as it is a "pure" query of its arguments. if let Some(out) = self - .cache + .summary_cache .get(&(parent, candidate.clone(), method.clone())) .cloned() { @@ -233,7 +224,7 @@ impl<'a> DepsCache<'a> { let mut deps = deps .into_iter() .map(|(dep, features)| { - let candidates = self.registry.query(&dep)?; + let candidates = self.query(&dep)?; Ok((dep, candidates, features)) }) .collect::>>()?; @@ -248,7 +239,7 @@ impl<'a> DepsCache<'a> { // If we succeed we add the result to the cache so we can use it again next time. // We dont cache the failure cases as they dont impl Clone. - self.cache + self.summary_cache .insert((parent, candidate.clone(), method.clone()), out.clone()); Ok(out) diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index 93c7d2c6f80..a6a589da8be 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -61,7 +61,7 @@ use crate::util::errors::CargoResult; use crate::util::profile; use self::context::{Activations, Context}; -use self::dep_cache::{DepsCache, RegistryQueryer}; +use self::dep_cache::RegistryQueryer; use self::types::{Candidate, ConflictMap, ConflictReason, DepsFrame}; use self::types::{FeaturesSet, RcVecIter, RemainingDeps, ResolverProgress}; @@ -133,8 +133,7 @@ pub fn resolve( Some(config) => config.cli_unstable().minimal_versions, None => false, }; - let registry = RegistryQueryer::new(registry, replacements, try_to_use, minimal_versions); - let mut registry = DepsCache::new(registry); + let mut registry = RegistryQueryer::new(registry, replacements, try_to_use, minimal_versions); let cx = activate_deps_loop(cx, &mut registry, summaries, config)?; let mut cksums = HashMap::new(); @@ -144,7 +143,7 @@ pub fn resolve( } let resolve = Resolve::new( cx.graph(), - cx.resolve_replacements(®istry.registry), + cx.resolve_replacements(®istry), cx.resolve_features .iter() .map(|(k, v)| (*k, v.iter().map(|x| x.to_string()).collect())) @@ -168,7 +167,7 @@ pub fn resolve( /// dependency graph, cx.resolve is returned. fn activate_deps_loop( mut cx: Context, - registry: &mut DepsCache<'_>, + registry: &mut RegistryQueryer<'_>, summaries: &[(Summary, Method)], config: Option<&Config>, ) -> CargoResult { @@ -328,7 +327,7 @@ fn activate_deps_loop( debug!("no candidates found"); Err(errors::activation_error( &cx, - registry.registry.registry, + registry.registry, &parent, &dep, &conflicting_activations, @@ -594,7 +593,7 @@ fn activate_deps_loop( /// iterate through next. fn activate( cx: &mut Context, - registry: &mut DepsCache<'_>, + registry: &mut RegistryQueryer<'_>, parent: Option<(&Summary, &Dependency)>, candidate: Candidate, method: Method, @@ -858,7 +857,7 @@ impl RemainingCandidates { /// Panics if the input conflict is not all active in `cx`. fn generalize_conflicting( cx: &Context, - registry: &mut DepsCache<'_>, + registry: &mut RegistryQueryer<'_>, past_conflicting_activations: &mut conflict_cache::ConflictCache, parent: &Summary, dep: &Dependency, @@ -897,7 +896,6 @@ fn generalize_conflicting( // Thus, if all the things it can resolve to have already ben determined // to be conflicting, then we can just say that we conflict with the parent. if registry - .registry .query(critical_parents_dep) .expect("an already used dep now error!?") .iter()