57
57
use indexmap:: IndexMap ;
58
58
use std:: borrow:: Borrow ;
59
59
use std:: cell:: { Ref , RefCell , RefMut } ;
60
- use std:: collections:: { BTreeSet , HashSet } ;
60
+ use std:: collections:: { BTreeMap , HashSet } ;
61
61
use std:: fmt;
62
62
use std:: hash:: Hash ;
63
63
use std:: rc:: Rc ;
@@ -409,13 +409,10 @@ pub struct StackGraph<N: Clone, E: Clone> {
409
409
inner : Rc < RefCell < Graph < N , E > > > ,
410
410
/// The shared list of all extant references to the same `Graph`.
411
411
/// 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 > > > ,
415
414
/// The size of the `Graph` that this `StackGraph` refers to.
416
415
age : GraphAge ,
417
- /// The arbitrary number that is unique to this clone.
418
- this_ref : usize ,
419
416
}
420
417
421
418
#[ test]
@@ -442,40 +439,38 @@ fn demonstrate_stack_graph_can_read_all_clones() {
442
439
443
440
impl < N : Clone , E : Clone > Clone for StackGraph < N , E > {
444
441
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 ;
452
445
StackGraph {
453
446
inner : Rc :: clone ( & self . inner ) ,
454
447
other_refs : Rc :: clone ( & self . other_refs ) ,
455
- this_ref : count,
456
448
age : self . age ,
457
449
}
458
450
}
459
451
}
460
452
461
453
impl < N : Clone , E : Clone > Drop for StackGraph < N , E > {
462
454
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
+ }
466
462
}
467
463
}
468
464
469
465
impl < N : Eq + Hash + Clone , E : Clone + PartialEq > StackGraph < N , E > {
470
466
pub fn new ( ) -> StackGraph < N , E > {
471
467
let inner = Graph :: new ( ) ;
472
468
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 ) ;
475
471
StackGraph {
476
472
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) ) ,
479
474
age,
480
475
}
481
476
}
@@ -497,13 +492,17 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
497
492
fn activate ( & mut self ) -> RefMut < ' _ , Graph < N , E > > {
498
493
let inner = if {
499
494
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
+ }
501
501
borrow
502
- . 0
503
- . iter ( )
502
+ . keys ( )
504
503
. rev ( )
505
504
. next ( )
506
- . map ( |( a , _ ) | a <= & self . age )
505
+ . map ( |a | a <= & self . age )
507
506
. unwrap_or ( true )
508
507
} {
509
508
// 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> {
515
514
inner
516
515
} else {
517
516
// 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 ( ) ) ) ;
520
518
let new = Rc :: make_mut ( & mut self . inner ) ;
521
519
let mut inner = RefCell :: borrow_mut ( new) ;
522
520
inner. reset_to ( self . age ) ;
@@ -531,9 +529,9 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
531
529
g. add ( node) ;
532
530
g. len ( )
533
531
} ;
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 ;
537
535
}
538
536
539
537
/// connect `node`to `child` with out associating any data.
@@ -543,9 +541,9 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
543
541
g. link ( node, child) ;
544
542
g. len ( )
545
543
} ;
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 ;
549
547
}
550
548
551
549
/// connect `node`to `child` associating it with `edge`.
@@ -555,9 +553,9 @@ impl<N: Eq + Hash + Clone, E: Clone + PartialEq> StackGraph<N, E> {
555
553
g. add_edge ( node, child, edge) ;
556
554
g. len ( )
557
555
} ;
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 ;
561
559
}
562
560
}
563
561
0 commit comments