Skip to content

Commit 4afbd85

Browse files
committed
make RemainingCandidates::next peekable.
`candidates.next` always came with a `candidates.clone().next(prev_active).is_ok` so lets just make that part of `next`. no `clone` needed.
1 parent 847f1f7 commit 4afbd85

File tree

1 file changed

+38
-42
lines changed

1 file changed

+38
-42
lines changed

src/cargo/core/resolver/mod.rs

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ impl Ord for DepsFrame {
528528
}
529529
}
530530

531+
#[derive(Clone)]
531532
struct BacktrackFrame<'a> {
532533
cur: usize,
533534
context_backup: Context<'a>,
@@ -543,10 +544,20 @@ struct RemainingCandidates {
543544
remaining: RcVecIter<Candidate>,
544545
// note: change to RcList or something if clone is to expensive
545546
conflicting_prev_active: HashSet<PackageId>,
547+
// This is a inlined peekable generator
548+
has_another: Option<Candidate>,
546549
}
547550

548551
impl RemainingCandidates {
549-
fn next(&mut self, prev_active: &[Summary]) -> Result<Candidate, HashSet<PackageId>> {
552+
fn new(candidates: &Rc<Vec<Candidate>>) -> RemainingCandidates {
553+
RemainingCandidates {
554+
remaining: RcVecIter::new(Rc::clone(candidates)),
555+
conflicting_prev_active: HashSet::new(),
556+
has_another: None,
557+
}
558+
}
559+
560+
fn next(&mut self, prev_active: &[Summary]) -> Result<(Candidate, bool), HashSet<PackageId>> {
550561
// Filter the set of candidates based on the previously activated
551562
// versions for this dependency. We can actually use a version if it
552563
// precisely matches an activated version or if it is otherwise
@@ -559,15 +570,22 @@ impl RemainingCandidates {
559570
// that conflicted with the ones we tried. If any of these change
560571
// then we would have considered different candidates.
561572
for (_, b) in self.remaining.by_ref() {
562-
if let Some(a) = prev_active.iter().find(|a| compatible(a.version(), b.summary.version())) {
573+
if let Some(a) = prev_active
574+
.iter()
575+
.find(|a| compatible(a.version(), b.summary.version()))
576+
{
563577
if *a != b.summary {
564578
self.conflicting_prev_active.insert(a.package_id().clone());
565-
continue
579+
continue;
566580
}
567581
}
568-
return Ok(b);
582+
if let Some(r) = ::std::mem::replace(&mut self.has_another, Some(b)) {
583+
return Ok((r, true));
584+
}
569585
}
570-
Err(self.conflicting_prev_active.clone())
586+
::std::mem::replace(&mut self.has_another, None)
587+
.map(|r| (r, false))
588+
.ok_or_else(|| self.conflicting_prev_active.clone())
571589
}
572590
}
573591

@@ -652,20 +670,10 @@ fn activate_deps_loop<'a>(mut cx: Context<'a>,
652670
let (mut parent, (mut cur, (mut dep, candidates, mut features))) = frame;
653671
assert!(!remaining_deps.is_empty());
654672

655-
let (next, has_another, remaining_candidates) = {
656-
let prev_active = cx.prev_active(&dep);
657-
trace!("{}[{}]>{} {} candidates", parent.name(), cur, dep.name(),
658-
candidates.len());
659-
trace!("{}[{}]>{} {} prev activations", parent.name(), cur,
660-
dep.name(), prev_active.len());
661-
let mut candidates = RemainingCandidates {
662-
remaining: RcVecIter::new(Rc::clone(&candidates)),
663-
conflicting_prev_active: HashSet::new(),
664-
};
665-
(candidates.next(prev_active),
666-
candidates.clone().next(prev_active).is_ok(),
667-
candidates)
668-
};
673+
trace!("{}[{}]>{} {} candidates", parent.name(), cur, dep.name(), candidates.len());
674+
trace!("{}[{}]>{} {} prev activations", parent.name(), cur, dep.name(), cx.prev_active(&dep).len());
675+
let mut remaining_candidates = RemainingCandidates::new(&candidates);
676+
let next = remaining_candidates.next(cx.prev_active(&dep));
669677

670678
// Alright, for each candidate that's gotten this far, it meets the
671679
// following requirements:
@@ -680,15 +688,15 @@ fn activate_deps_loop<'a>(mut cx: Context<'a>,
680688
// turn. We could possibly fail to activate each candidate, so we try
681689
// each one in turn.
682690
let candidate = match next {
683-
Ok(candidate) => {
691+
Ok((candidate, has_another)) => {
684692
// We have a candidate. Add an entry to the `backtrack_stack` so
685693
// we can try the next one if this one fails.
686694
if has_another {
687695
backtrack_stack.push(BacktrackFrame {
688696
cur,
689697
context_backup: Context::clone(&cx),
690698
deps_backup: <BinaryHeap<DepsFrame>>::clone(&remaining_deps),
691-
remaining_candidates: remaining_candidates,
699+
remaining_candidates,
692700
parent: Summary::clone(&parent),
693701
dep: Dependency::clone(&dep),
694702
features: Rc::clone(&features),
@@ -759,13 +767,7 @@ fn find_candidate<'a>(
759767
conflicting_activations: &mut HashSet<PackageId>,
760768
) -> Option<Candidate> {
761769
while let Some(mut frame) = backtrack_stack.pop() {
762-
let (next, has_another) = {
763-
let prev_active = frame.context_backup.prev_active(&frame.dep);
764-
(
765-
frame.remaining_candidates.next(prev_active),
766-
frame.remaining_candidates.clone().next(prev_active).is_ok(),
767-
)
768-
};
770+
let next= frame.remaining_candidates.next(frame.context_backup.prev_active(&frame.dep));
769771
if frame.context_backup.is_active(parent.package_id())
770772
&& conflicting_activations
771773
.iter()
@@ -774,22 +776,16 @@ fn find_candidate<'a>(
774776
{
775777
continue;
776778
}
777-
if let Ok(candidate) = next {
778-
*cur = frame.cur;
779+
if let Ok((candidate, has_another)) = next {
779780
if has_another {
780-
*cx = frame.context_backup.clone();
781-
*remaining_deps = frame.deps_backup.clone();
782-
*parent = frame.parent.clone();
783-
*dep = frame.dep.clone();
784-
*features = Rc::clone(&frame.features);
785-
backtrack_stack.push(frame);
786-
} else {
787-
*cx = frame.context_backup;
788-
*remaining_deps = frame.deps_backup;
789-
*parent = frame.parent;
790-
*dep = frame.dep;
791-
*features = frame.features;
781+
backtrack_stack.push(frame.clone());
792782
}
783+
*cur = frame.cur;
784+
*cx = frame.context_backup;
785+
*remaining_deps = frame.deps_backup;
786+
*parent = frame.parent;
787+
*dep = frame.dep;
788+
*features = frame.features;
793789
return Some(candidate);
794790
}
795791
}

0 commit comments

Comments
 (0)