Skip to content

Commit 2340384

Browse files
committed
Better way to do a multi set
1 parent a358966 commit 2340384

File tree

1 file changed

+34
-36
lines changed

1 file changed

+34
-36
lines changed

src/cargo/util/graph.rs

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
use indexmap::IndexMap;
5858
use std::borrow::Borrow;
5959
use std::cell::{Ref, RefCell, RefMut};
60-
use std::collections::{BTreeSet, HashSet};
60+
use std::collections::{BTreeMap, HashSet};
6161
use std::fmt;
6262
use std::hash::Hash;
6363
use std::rc::Rc;
@@ -409,13 +409,10 @@ pub struct StackGraph<N: Clone, E: Clone> {
409409
inner: Rc<RefCell<Graph<N, E>>>,
410410
/// The shared list of all extant references to the same `Graph`.
411411
/// The largest one is allowed to reset and expend the `Graph` without doing a deep clone.
412-
/// There can be more then one clone at the same age, so each one is associated with a unique arbitrary number.
413-
/// This all so stores the largest arbitrary number so far used.
414-
other_refs: Rc<RefCell<(BTreeSet<(GraphAge, usize)>, usize)>>,
412+
/// There can be more then one clone at the same age, so each age is associated with a count.
413+
other_refs: Rc<RefCell<BTreeMap<GraphAge, usize>>>,
415414
/// The size of the `Graph` that this `StackGraph` refers to.
416415
age: GraphAge,
417-
/// The arbitrary number that is unique to this clone.
418-
this_ref: usize,
419416
}
420417

421418
#[test]
@@ -442,40 +439,38 @@ fn demonstrate_stack_graph_can_read_all_clones() {
442439

443440
impl<N: Clone, E: Clone> Clone for StackGraph<N, E> {
444441
fn clone(&self) -> Self {
445-
let count;
446-
{
447-
let mut other_refs = RefCell::borrow_mut(&self.other_refs);
448-
other_refs.1 += 1;
449-
count = other_refs.1;
450-
other_refs.0.insert((self.age, count));
451-
}
442+
*RefCell::borrow_mut(&self.other_refs)
443+
.entry(self.age)
444+
.or_insert(0) += 1;
452445
StackGraph {
453446
inner: Rc::clone(&self.inner),
454447
other_refs: Rc::clone(&self.other_refs),
455-
this_ref: count,
456448
age: self.age,
457449
}
458450
}
459451
}
460452

461453
impl<N: Clone, E: Clone> Drop for StackGraph<N, E> {
462454
fn drop(&mut self) {
463-
RefCell::borrow_mut(&self.other_refs)
464-
.0
465-
.remove(&(self.age, self.this_ref));
455+
let mut borrow = RefCell::borrow_mut(&self.other_refs);
456+
if let std::collections::btree_map::Entry::Occupied(mut val) = borrow.entry(self.age) {
457+
*val.get_mut() -= 1;
458+
if val.get() == &0 {
459+
val.remove();
460+
}
461+
}
466462
}
467463
}
468464

469465
impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
470466
pub fn new() -> StackGraph<N, E> {
471467
let inner = Graph::new();
472468
let age = inner.len();
473-
let mut other_refs = BTreeSet::new();
474-
other_refs.insert((age, 0));
469+
let mut other_refs = BTreeMap::new();
470+
other_refs.insert(age, 1);
475471
StackGraph {
476472
inner: Rc::new(RefCell::new(inner)),
477-
other_refs: Rc::new(RefCell::new((other_refs, 0))),
478-
this_ref: 0,
473+
other_refs: Rc::new(RefCell::new(other_refs)),
479474
age,
480475
}
481476
}
@@ -497,13 +492,17 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
497492
fn activate(&mut self) -> RefMut<'_, Graph<N, E>> {
498493
let inner = if {
499494
let mut borrow = RefCell::borrow_mut(&self.other_refs);
500-
borrow.0.remove(&(self.age, self.this_ref));
495+
if let std::collections::btree_map::Entry::Occupied(mut val) = borrow.entry(self.age) {
496+
*val.get_mut() -= 1;
497+
if val.get() == &0 {
498+
val.remove();
499+
}
500+
}
501501
borrow
502-
.0
503-
.iter()
502+
.keys()
504503
.rev()
505504
.next()
506-
.map(|(a, _)| a <= &self.age)
505+
.map(|a| a <= &self.age)
507506
.unwrap_or(true)
508507
} {
509508
// we are the biggest clone, so we can add to inner directly.
@@ -515,8 +514,7 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
515514
inner
516515
} else {
517516
// a bigger clone still exists so do a deep clone.
518-
self.other_refs = Rc::new(RefCell::new((BTreeSet::new(), 0)));
519-
self.this_ref = 0;
517+
self.other_refs = Rc::new(RefCell::new(BTreeMap::new()));
520518
let new = Rc::make_mut(&mut self.inner);
521519
let mut inner = RefCell::borrow_mut(new);
522520
inner.reset_to(self.age);
@@ -531,9 +529,9 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
531529
g.add(node);
532530
g.len()
533531
};
534-
RefCell::borrow_mut(&self.other_refs)
535-
.0
536-
.insert((self.age, self.this_ref));
532+
*RefCell::borrow_mut(&self.other_refs)
533+
.entry(self.age)
534+
.or_insert(0) += 1;
537535
}
538536

539537
/// connect `node`to `child` with out associating any data.
@@ -543,9 +541,9 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
543541
g.link(node, child);
544542
g.len()
545543
};
546-
RefCell::borrow_mut(&self.other_refs)
547-
.0
548-
.insert((self.age, self.this_ref));
544+
*RefCell::borrow_mut(&self.other_refs)
545+
.entry(self.age)
546+
.or_insert(0) += 1;
549547
}
550548

551549
/// connect `node`to `child` associating it with `edge`.
@@ -555,9 +553,9 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
555553
g.add_edge(node, child, edge);
556554
g.len()
557555
};
558-
RefCell::borrow_mut(&self.other_refs)
559-
.0
560-
.insert((self.age, self.this_ref));
556+
*RefCell::borrow_mut(&self.other_refs)
557+
.entry(self.age)
558+
.or_insert(0) += 1;
561559
}
562560
}
563561

0 commit comments

Comments
 (0)