Skip to content

Commit 0e6edcf

Browse files
committed
Auto merge of #5428 - matklad:graph-with-edges, r=alexcrichton
Store dependencies as edges of the graph r? @alexcrichton
2 parents 19962e2 + 8164be2 commit 0e6edcf

File tree

5 files changed

+45
-63
lines changed

5 files changed

+45
-63
lines changed

src/cargo/core/resolver/context.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -269,25 +269,19 @@ impl Context {
269269
replacements
270270
}
271271

272-
pub fn graph(&self)
273-
-> (Graph<PackageId>, HashMap<(PackageId, PackageId), Vec<Dependency>>)
274-
{
275-
let mut graph = Graph::new();
276-
let mut deps = HashMap::new();
272+
pub fn graph(&self) -> Graph<PackageId, Vec<Dependency>> {
273+
let mut graph: Graph<PackageId, Vec<Dependency>> = Graph::new();
277274
let mut cur = &self.resolve_graph;
278275
while let Some(ref node) = cur.head {
279276
match node.0 {
280277
GraphNode::Add(ref p) => graph.add(p.clone()),
281278
GraphNode::Link(ref a, ref b, ref dep) => {
282-
graph.link(a.clone(), b.clone());
283-
deps.entry((a.clone(), b.clone()))
284-
.or_insert(Vec::new())
285-
.push(dep.clone());
279+
graph.link(a.clone(), b.clone()).push(dep.clone());
286280
}
287281
}
288282
cur = &node.1;
289283
}
290-
(graph, deps)
284+
graph
291285
}
292286
}
293287

src/cargo/core/resolver/encode.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ impl EncodableResolve {
179179

180180
Ok(Resolve::new(
181181
g,
182-
HashMap::new(),
183182
replacements,
184183
HashMap::new(),
185184
checksums,

src/cargo/core/resolver/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,13 @@ pub fn resolve(
122122
let mut registry = RegistryQueryer::new(registry, replacements, try_to_use, minimal_versions);
123123
let cx = activate_deps_loop(cx, &mut registry, summaries, config)?;
124124

125-
let (graph, deps) = cx.graph();
126-
127125
let mut cksums = HashMap::new();
128126
for summary in cx.activations.values().flat_map(|v| v.iter()) {
129127
let cksum = summary.checksum().map(|s| s.to_string());
130128
cksums.insert(summary.package_id().clone(), cksum);
131129
}
132130
let resolve = Resolve::new(
133-
graph,
134-
deps,
131+
cx.graph(),
135132
cx.resolve_replacements(),
136133
cx.resolve_features
137134
.iter()
@@ -867,7 +864,7 @@ fn activation_error(
867864
candidates: &[Candidate],
868865
config: Option<&Config>,
869866
) -> CargoError {
870-
let (graph, _) = cx.graph();
867+
let graph = cx.graph();
871868
if !candidates.is_empty() {
872869
let mut msg = format!("failed to select a version for `{}`.", dep.name());
873870
msg.push_str("\n ... required by ");

src/cargo/core/resolver/resolve.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ use super::encode::Metadata;
1818
/// for each package.
1919
#[derive(PartialEq)]
2020
pub struct Resolve {
21-
graph: Graph<PackageId>,
22-
dependencies: HashMap<(PackageId, PackageId), Vec<Dependency>>,
21+
graph: Graph<PackageId, Vec<Dependency>>,
2322
replacements: HashMap<PackageId, PackageId>,
2423
reverse_replacements: HashMap<PackageId, PackageId>,
2524
empty_features: HashSet<String>,
@@ -31,8 +30,7 @@ pub struct Resolve {
3130

3231
impl Resolve {
3332
pub fn new(
34-
graph: Graph<PackageId>,
35-
dependencies: HashMap<(PackageId, PackageId), Vec<Dependency>>,
33+
graph: Graph<PackageId, Vec<Dependency>>,
3634
replacements: HashMap<PackageId, PackageId>,
3735
features: HashMap<PackageId, HashSet<String>>,
3836
checksums: HashMap<PackageId, Option<String>>,
@@ -45,7 +43,6 @@ impl Resolve {
4543
.collect();
4644
Resolve {
4745
graph,
48-
dependencies,
4946
replacements,
5047
features,
5148
checksums,
@@ -162,14 +159,13 @@ unable to verify that `{0}` is the same as when the lockfile was generated
162159
Ok(())
163160
}
164161

165-
pub fn iter(&self) -> Nodes<PackageId> {
162+
pub fn iter(&self) -> Nodes<PackageId, Vec<Dependency>> {
166163
self.graph.iter()
167164
}
168165

169166
pub fn deps(&self, pkg: &PackageId) -> Deps {
170167
Deps {
171168
edges: self.graph.edges(pkg),
172-
id: pkg.clone(),
173169
resolve: self,
174170
}
175171
}
@@ -225,11 +221,11 @@ unable to verify that `{0}` is the same as when the lockfile was generated
225221
// that's where the dependency originates from, and we only replace
226222
// targets of dependencies not the originator.
227223
if let Some(replace) = self.reverse_replacements.get(to) {
228-
if let Some(deps) = self.dependencies.get(&(from.clone(), replace.clone())) {
224+
if let Some(deps) = self.graph.edge(from, replace) {
229225
return deps;
230226
}
231227
}
232-
match self.dependencies.get(&(from.clone(), to.clone())) {
228+
match self.graph.edge(from, to) {
233229
Some(ret) => ret,
234230
None => panic!("no Dependency listed for `{}` => `{}`", from, to),
235231
}
@@ -248,18 +244,16 @@ impl fmt::Debug for Resolve {
248244
}
249245

250246
pub struct Deps<'a> {
251-
edges: Option<Edges<'a, PackageId>>,
252-
id: PackageId,
247+
edges: Option<Edges<'a, PackageId, Vec<Dependency>>>,
253248
resolve: &'a Resolve,
254249
}
255250

256251
impl<'a> Iterator for Deps<'a> {
257252
type Item = (&'a PackageId, &'a [Dependency]);
258253

259254
fn next(&mut self) -> Option<(&'a PackageId, &'a [Dependency])> {
260-
let id = self.edges.as_mut()?.next()?;
255+
let (id, deps) = self.edges.as_mut()?.next()?;
261256
let id_ret = self.resolve.replacement(id).unwrap_or(id);
262-
let deps = &self.resolve.dependencies[&(self.id.clone(), id.clone())];
263257
Some((id_ret, deps))
264258
}
265259

@@ -274,14 +268,14 @@ impl<'a> Iterator for Deps<'a> {
274268
impl<'a> ExactSizeIterator for Deps<'a> {}
275269

276270
pub struct DepsNotReplaced<'a> {
277-
edges: Option<Edges<'a, PackageId>>,
271+
edges: Option<Edges<'a, PackageId, Vec<Dependency>>>,
278272
}
279273

280274
impl<'a> Iterator for DepsNotReplaced<'a> {
281275
type Item = &'a PackageId;
282276

283277
fn next(&mut self) -> Option<&'a PackageId> {
284-
self.edges.as_mut().and_then(|e| e.next())
278+
Some(self.edges.as_mut()?.next()?.0)
285279
}
286280

287281
fn size_hint(&self) -> (usize, Option<usize>) {

src/cargo/util/graph.rs

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,44 @@
11
use std::fmt;
22
use std::hash::Hash;
3-
use std::collections::hash_set::{HashSet, Iter};
4-
use std::collections::hash_map::{HashMap, Keys};
3+
use std::collections::hash_map::{HashMap, Iter, Keys};
54

6-
pub struct Graph<N> {
7-
nodes: HashMap<N, HashSet<N>>,
5+
pub struct Graph<N, E> {
6+
nodes: HashMap<N, HashMap<N, E>>,
87
}
98

109
enum Mark {
1110
InProgress,
1211
Done,
1312
}
1413

15-
pub type Nodes<'a, N> = Keys<'a, N, HashSet<N>>;
16-
pub type Edges<'a, N> = Iter<'a, N>;
14+
pub type Nodes<'a, N, E> = Keys<'a, N, HashMap<N, E>>;
15+
pub type Edges<'a, N, E> = Iter<'a, N, E>;
1716

18-
impl<N: Eq + Hash + Clone> Graph<N> {
19-
pub fn new() -> Graph<N> {
17+
impl<N: Eq + Hash + Clone, E: Default> Graph<N, E> {
18+
pub fn new() -> Graph<N, E> {
2019
Graph {
2120
nodes: HashMap::new(),
2221
}
2322
}
2423

2524
pub fn add(&mut self, node: N) {
26-
self.nodes
27-
.entry(node)
28-
.or_insert_with(HashSet::new);
25+
self.nodes.entry(node).or_insert_with(HashMap::new);
2926
}
3027

31-
pub fn link(&mut self, node: N, child: N) {
28+
pub fn link(&mut self, node: N, child: N) -> &mut E {
3229
self.nodes
3330
.entry(node)
34-
.or_insert_with(HashSet::new)
35-
.insert(child);
31+
.or_insert_with(HashMap::new)
32+
.entry(child)
33+
.or_insert_with(Default::default)
3634
}
3735

38-
pub fn get_nodes(&self) -> &HashMap<N, HashSet<N>> {
39-
&self.nodes
36+
pub fn edge(&self, from: &N, to: &N) -> Option<&E> {
37+
self.nodes.get(from)?.get(to)
4038
}
4139

42-
pub fn edges(&self, node: &N) -> Option<Edges<N>> {
43-
self.nodes.get(node).map(|set| set.iter())
40+
pub fn edges(&self, from: &N) -> Option<Edges<N, E>> {
41+
self.nodes.get(from).map(|set| set.iter())
4442
}
4543

4644
pub fn sort(&self) -> Option<Vec<N>> {
@@ -61,15 +59,15 @@ impl<N: Eq + Hash + Clone> Graph<N> {
6159

6260
marks.insert(node.clone(), Mark::InProgress);
6361

64-
for child in &self.nodes[node] {
62+
for child in self.nodes[node].keys() {
6563
self.visit(child, dst, marks);
6664
}
6765

6866
dst.push(node.clone());
6967
marks.insert(node.clone(), Mark::Done);
7068
}
7169

72-
pub fn iter(&self) -> Nodes<N> {
70+
pub fn iter(&self) -> Nodes<N, E> {
7371
self.nodes.keys()
7472
}
7573

@@ -81,12 +79,12 @@ impl<N: Eq + Hash + Clone> Graph<N> {
8179
// it's used for!
8280
let mut result = vec![pkg];
8381
let first_pkg_depending_on = |pkg: &N, res: &[&N]| {
84-
self.get_nodes()
82+
self.nodes
8583
.iter()
86-
.filter(|&(_node, adjacent)| adjacent.contains(pkg))
84+
.filter(|&(_node, adjacent)| adjacent.contains_key(pkg))
8785
// Note that we can have "cycles" introduced through dev-dependency
8886
// edges, so make sure we don't loop infinitely.
89-
.filter(|&(_node, _)| !res.contains(&_node))
87+
.filter(|&(node, _)| !res.contains(&node))
9088
.next()
9189
.map(|p| p.0)
9290
};
@@ -98,20 +96,20 @@ impl<N: Eq + Hash + Clone> Graph<N> {
9896
}
9997
}
10098

101-
impl<N: Eq + Hash + Clone> Default for Graph<N> {
102-
fn default() -> Graph<N> {
99+
impl<N: Eq + Hash + Clone, E: Default> Default for Graph<N, E> {
100+
fn default() -> Graph<N, E> {
103101
Graph::new()
104102
}
105103
}
106104

107-
impl<N: fmt::Display + Eq + Hash> fmt::Debug for Graph<N> {
105+
impl<N: fmt::Display + Eq + Hash, E> fmt::Debug for Graph<N, E> {
108106
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
109107
writeln!(fmt, "Graph {{")?;
110108

111109
for (n, e) in &self.nodes {
112110
writeln!(fmt, " - {}", n)?;
113111

114-
for n in e.iter() {
112+
for n in e.keys() {
115113
writeln!(fmt, " - {}", n)?;
116114
}
117115
}
@@ -122,15 +120,15 @@ impl<N: fmt::Display + Eq + Hash> fmt::Debug for Graph<N> {
122120
}
123121
}
124122

125-
impl<N: Eq + Hash> PartialEq for Graph<N> {
126-
fn eq(&self, other: &Graph<N>) -> bool {
123+
impl<N: Eq + Hash, E: Eq> PartialEq for Graph<N, E> {
124+
fn eq(&self, other: &Graph<N, E>) -> bool {
127125
self.nodes.eq(&other.nodes)
128126
}
129127
}
130-
impl<N: Eq + Hash> Eq for Graph<N> {}
128+
impl<N: Eq + Hash, E: Eq> Eq for Graph<N, E> {}
131129

132-
impl<N: Eq + Hash + Clone> Clone for Graph<N> {
133-
fn clone(&self) -> Graph<N> {
130+
impl<N: Eq + Hash + Clone, E: Clone> Clone for Graph<N, E> {
131+
fn clone(&self) -> Graph<N, E> {
134132
Graph {
135133
nodes: self.nodes.clone(),
136134
}

0 commit comments

Comments
 (0)