@@ -91,8 +91,8 @@ pub(crate) fn marker_reachability<T>(
91
91
pub ( crate ) fn simplify_conflict_markers ( graph : & mut Graph < ResolutionGraphNode , UniversalMarker > ) {
92
92
// The set of activated extras (and TODO, in the future, groups)
93
93
// for each node. The ROOT nodes don't have any extras activated.
94
- let mut activated: FxHashMap < NodeIndex , FxHashSet < ( PackageName , ExtraName ) > > =
95
- FxHashMap :: with_capacity_and_hasher ( graph . node_count ( ) , FxBuildHasher ) ;
94
+ let mut activated: FxHashMap < NodeIndex , Vec < FxHashSet < ( PackageName , ExtraName ) > > > =
95
+ FxHashMap :: default ( ) ;
96
96
97
97
// Collect the root nodes.
98
98
//
@@ -108,35 +108,217 @@ pub(crate) fn simplify_conflict_markers(graph: &mut Graph<ResolutionGraphNode, U
108
108
} )
109
109
. collect ( ) ;
110
110
111
- let mut assume_by_edge: FxHashMap < EdgeIndex , FxHashSet < ( PackageName , ExtraName ) > > =
112
- FxHashMap :: default ( ) ;
111
+ // let mut assume_by_edge: FxHashMap<EdgeIndex, FxHashSet<(PackageName, ExtraName)>> =
112
+ // FxHashMap::default();
113
113
let mut seen: FxHashSet < NodeIndex > = FxHashSet :: default ( ) ;
114
114
while let Some ( parent_index) = queue. pop ( ) {
115
- for child_edge in graph. edges_directed ( parent_index, Direction :: Outgoing ) {
116
- // TODO: The below seems excessively clone-y.
117
- // Consider tightening this up a bit.
118
- let target = child_edge. target ( ) ;
119
- let mut extras: FxHashSet < ( PackageName , ExtraName ) > =
120
- activated. get ( & parent_index) . cloned ( ) . unwrap_or_default ( ) ;
121
- if let Some ( ( package, extra) ) = graph[ parent_index] . package_extra_names ( ) {
122
- extras. insert ( ( package. clone ( ) , extra. clone ( ) ) ) ;
115
+ if let Some ( ( package, extra) ) = graph[ parent_index] . package_extra_names ( ) {
116
+ for set in activated
117
+ . entry ( parent_index)
118
+ . or_insert_with ( || vec ! [ FxHashSet :: default ( ) ] )
119
+ {
120
+ set. insert ( ( package. clone ( ) , extra. clone ( ) ) ) ;
123
121
}
124
- if let Some ( ( package, extra) ) = graph[ target] . package_extra_names ( ) {
125
- extras. insert ( ( package. clone ( ) , extra. clone ( ) ) ) ;
122
+ }
123
+ let sets = activated. get ( & parent_index) . cloned ( ) . unwrap_or_default ( ) ;
124
+ for child_edge in graph. edges_directed ( parent_index, Direction :: Outgoing ) {
125
+ for set in sets. clone ( ) {
126
+ activated. entry ( child_edge. target ( ) ) . or_default ( ) . push ( set) ;
126
127
}
127
- activated. entry ( target) . or_default ( ) . extend ( extras. clone ( ) ) ;
128
- assume_by_edge
129
- . entry ( child_edge. id ( ) )
130
- . or_default ( )
131
- . extend ( extras) ;
128
+ // activated
129
+ // .entry(child_edge.target())
130
+ // .or_default()
131
+ // .extend(sets.clone());
132
132
if seen. insert ( child_edge. target ( ) ) {
133
133
queue. push ( child_edge. target ( ) ) ;
134
134
}
135
135
}
136
136
}
137
+ /*
138
+ eprintln!("EXTRA ASSUMPTIONS");
139
+ for (&node_id, extras) in &activated {
140
+ let node = &graph[node_id];
141
+ eprintln!(
142
+ " {} -> assuming ({})",
143
+ node.debug(),
144
+ extras
145
+ .iter()
146
+ .map(|set| {
147
+ format!(
148
+ "{{{}}}",
149
+ set.iter()
150
+ .map(|&(ref p, ref e)| format!("{p}[{e}]"))
151
+ .collect::<Vec<String>>()
152
+ .join(", "),
153
+ )
154
+ })
155
+ .collect::<Vec<String>>()
156
+ .join(", ")
157
+ );
158
+ }
159
+ */
160
+ for edge_index in ( 0 ..graph. edge_count ( ) ) . map ( EdgeIndex :: new) {
161
+ let ( from_index, _) = graph. edge_endpoints ( edge_index) . unwrap ( ) ;
162
+ let Some ( activated) = activated. get ( & from_index) else {
163
+ continue ;
164
+ } ;
165
+ let all_paths_satisfied = activated. iter ( ) . all ( |set| {
166
+ let extras = set
167
+ . iter ( )
168
+ . cloned ( )
169
+ . collect :: < Vec < ( PackageName , ExtraName ) > > ( ) ;
170
+ graph[ edge_index] . conflict ( ) . evaluate ( & extras)
171
+ } ) ;
172
+ if all_paths_satisfied {
173
+ for set in activated {
174
+ for ( package, extra) in set {
175
+ graph[ edge_index] . assume_extra ( package, extra) ;
176
+ }
177
+ }
178
+ }
179
+ /*
180
+ let activated = activated
181
+ .iter()
182
+ .cloned()
183
+ .collect::<Vec<(PackageName, ExtraName)>>();
184
+ if activated.iter().all(|&(ref package, ref extra)| {
185
+ graph[edge_index]
186
+ .conflict()
187
+ .evaluate(&[(package.clone(), extra.clone())])
188
+ }) {
189
+ for &(ref package, ref extra) in &activated {
190
+ graph[edge_index].assume_extra(package, extra);
191
+ }
192
+ }
193
+ */
194
+ }
195
+ }
196
+
197
+ /*
198
+ /// Traverse the given dependency graph and propagate activated markers.
199
+ ///
200
+ /// For example, given an edge like `foo[x1] -> bar`, then it is known that
201
+ /// `x1` is activated. This in turn can be used to simplify any downstream
202
+ /// conflict markers with `extra == "x1"` in them.
203
+ pub(crate) fn simplify_conflict_markers(graph: &mut Graph<ResolutionGraphNode, UniversalMarker>) {
204
+ // Collect the root nodes.
205
+ //
206
+ // Besides the actual virtual root node, virtual dev dependencies packages are also root
207
+ // nodes since the edges don't cover dev dependencies.
208
+ let mut queue: Vec<EdgeIndex> = graph
209
+ .node_indices()
210
+ .filter(|node_index| {
211
+ graph
212
+ .edges_directed(*node_index, Direction::Incoming)
213
+ .next()
214
+ .is_none()
215
+ })
216
+ .flat_map(|node_index| graph.edges_directed(node_index, Direction::Outgoing))
217
+ .map(|edge| edge.id())
218
+ .collect();
219
+ // let mut seen: FxHashSet<EdgeIndex> = FxHashSet::default();
220
+ let mut assume_by_edge: FxHashMap<EdgeIndex, FxHashSet<(PackageName, ExtraName)>> =
221
+ FxHashMap::default();
222
+ while let Some(edge_id) = queue.pop() {
223
+ // OK because we know `edge_id` is valid.
224
+ let (_from_id, to_id) = graph.edge_endpoints(edge_id).unwrap();
225
+ let parent_assumptions = assume_by_edge.get(&edge_id).cloned().unwrap_or_default();
226
+ for child_edge in graph.edges_directed(to_id, Direction::Outgoing) {
227
+ let mut assumptions = assume_by_edge
228
+ .get(&child_edge.id())
229
+ .cloned()
230
+ .unwrap_or_default();
231
+ assumptions.extend(parent_assumptions.iter().cloned());
232
+ if let Some((package, extra)) = graph[to_id].package_extra_names() {
233
+ assume_by_edge
234
+ .entry(child_edge.id())
235
+ .or_default()
236
+ .insert((package.clone(), extra.clone()));
237
+ assumptions.insert((package.clone(), extra.clone()));
238
+ }
239
+ if !child_edge
240
+ .weight()
241
+ .conflict()
242
+ .evaluate(&assumptions.iter().cloned().collect::<Vec<_>>())
243
+ {
244
+ assume_by_edge.insert(child_edge.id(), assumptions);
245
+ }
246
+ queue.push(child_edge.id());
247
+ // if seen.insert(child_item) {
248
+ // queue.push(child_item);
249
+ // }
250
+ }
251
+ }
252
+ eprintln!("EXTRA ASSUMPTIONS");
137
253
for (edge_id, extras) in assume_by_edge {
254
+ let (ni1, ni2) = graph.edge_endpoints(edge_id).unwrap();
255
+ let (n1, n2) = (&graph[ni1], &graph[ni2]);
256
+ eprintln!(
257
+ " ({}, {}) -> assuming {{{}}}",
258
+ n1.debug(),
259
+ n2.debug(),
260
+ extras
261
+ .iter()
262
+ .map(|&(ref p, ref e)| format!("{p}[{e}]"))
263
+ .collect::<Vec<String>>()
264
+ .join(", ")
265
+ );
138
266
for &(ref package, ref extra) in &extras {
139
267
graph[edge_id].assume_extra(package, extra);
140
268
}
141
269
}
142
270
}
271
+ */
272
+
273
+ /*
274
+ pub(crate) fn simplify_conflict_markers3(graph: &mut Graph<ResolutionGraphNode, UniversalMarker>) {
275
+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
276
+ struct Item<'a> {
277
+ node_index: NodeIndex,
278
+ extra: Option<(&'a PackageName, &'a ExtraName)>,
279
+ }
280
+
281
+ // Collect the root nodes.
282
+ //
283
+ // Besides the actual virtual root node, virtual dev dependencies packages are also root
284
+ // nodes since the edges don't cover dev dependencies.
285
+ let mut queue: Vec<Item<'_>> = graph
286
+ .node_indices()
287
+ .filter(|node_index| {
288
+ graph
289
+ .edges_directed(*node_index, Direction::Incoming)
290
+ .next()
291
+ .is_none()
292
+ })
293
+ .map(|node_index| Item {
294
+ node_index,
295
+ extra: None,
296
+ })
297
+ .collect();
298
+ let mut seen: FxHashSet<Item<'_>> = FxHashSet::default();
299
+ let mut assume_by_edge: FxHashMap<EdgeIndex, FxHashSet<(PackageName, ExtraName)>> =
300
+ FxHashMap::default();
301
+ while let Some(item) = queue.pop() {
302
+ let parent = &graph[item.node_index];
303
+ for edge in graph.edges_directed(item.node_index, Direction::Outgoing) {
304
+ // BREADCRUMBS: OK, so maybe we do need to traverse by edge?
305
+ // Or just add it to `Item`? I think the issue here is that
306
+ // we need to union the `assume_by_edge` sets as we traverse
307
+ // the graph.
308
+ if let Some((package, extra)) = parent.package_extra_names() {
309
+ assume_by_edge
310
+ .entry(edge.id())
311
+ .or_default()
312
+ .insert((package.clone(), extra.clone()));
313
+ }
314
+ let child_item = Item {
315
+ node_index: edge.target(),
316
+ extra: parent.package_extra_names(),
317
+ };
318
+ if seen.insert(child_item) {
319
+ queue.push(child_item);
320
+ }
321
+ }
322
+ }
323
+ }
324
+ */
0 commit comments