/// Information about a dependency requested by a Cargo manifest.
/// Cheap to copy.
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug)]
pub struct Dependency {
inner: Rc<Inner>,
}
/// The data underlying a Dependency.
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug)]
struct Inner {
name: String,
source_id: SourceId,
platform: Option<Platform>,
}
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug)]
pub enum Platform {
Name(String),
Cfg(CfgExpr),
}
}
-#[derive(PartialEq, Clone, Debug, Copy)]
+#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug, Copy)]
pub enum Kind {
Normal,
Development,
// Next, transform all dependencies into a list of possible candidates
// which can satisfy that dependency.
let mut deps = deps.into_iter().map(|(dep, features)| {
- let mut candidates = self.query(registry, &dep)?;
- // When we attempt versions for a package, we'll want to start at
- // the maximum version and work our way down.
- candidates.sort_by(|a, b| {
- b.summary.version().cmp(a.summary.version())
- });
- Ok((dep, Rc::new(candidates), Rc::new(features)))
+ let candidates = self.query(registry, &dep)?;
+ Ok((dep, candidates, Rc::new(features)))
}).collect::<CargoResult<Vec<DepInfo>>>()?;
// Attempt to resolve dependencies with fewer candidates before trying
/// return.
fn query(&self,
registry: &mut Registry,
- dep: &Dependency) -> CargoResult<Vec<Candidate>> {
+ dep: &Dependency) -> CargoResult<Rc<Vec<Candidate>>> {
+ use ::std::cell::RefCell;
+ thread_local!(static CACHE: RefCell<BTreeMap<Dependency, Rc<Vec<Candidate>>>> = RefCell::new(BTreeMap::new()));
+ if let Some(out) = CACHE.with(|m| m.borrow().get(dep).cloned()) {
+ return Ok(out);
+ }
+
let mut ret = Vec::new();
registry.query(dep, &mut |s| {
ret.push(Candidate { summary: s, replace: None });
candidate.replace = replace;
}
- Ok(ret)
+
+ // When we attempt versions for a package, we'll want to start at
+ // the maximum version and work our way down.
+ ret.sort_unstable_by(|a, b| {
+ b.summary.version().cmp(a.summary.version())
+ });
+
+ let out = Rc::new(ret);
+
+ CACHE.with(|m| m.borrow_mut().insert(dep.clone(), out.clone()));
+
+ Ok(out)
}
fn prev_active(&self, dep: &Dependency) -> &[Summary] {
use util::{CargoError, CargoResult};
-#[derive(Clone, PartialEq, Debug)]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug)]
pub enum Cfg {
Name(String),
KeyPair(String, String),
}
-#[derive(Clone, PartialEq, Debug)]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug)]
pub enum CfgExpr {
Not(Box<CfgExpr>),
All(Vec<CfgExpr>),