@@ -38,6 +38,7 @@ pub struct NonCanonicalOverlay<BlockHash: Hash, Key: Hash> {
38
38
// would be deleted but kept around because block is pinned, ref counted.
39
39
pinned : HashMap < BlockHash , u32 > ,
40
40
pinned_insertions : HashMap < BlockHash , ( Vec < Key > , u32 ) > ,
41
+ last_canon_pinned : Option < BlockHash > ,
41
42
}
42
43
43
44
#[ cfg_attr( test, derive( PartialEq , Debug ) ) ]
@@ -225,6 +226,7 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
225
226
pinned : Default :: default ( ) ,
226
227
pinned_insertions : Default :: default ( ) ,
227
228
values,
229
+ last_canon_pinned : None ,
228
230
} )
229
231
}
230
232
@@ -367,12 +369,23 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
367
369
. position ( |overlay| overlay. hash == * hash)
368
370
. ok_or ( StateDbError :: InvalidBlock ) ?;
369
371
372
+ // No failures are possible beyond this point.
373
+
374
+ // Unpin previously canonicalized block
375
+ if let Some ( prev_hash) = self . last_canon_pinned . take ( ) {
376
+ self . unpin ( & prev_hash) ;
377
+ }
378
+ // Force pin canonicalized block so that it is no discarded immediately
379
+ self . pin ( hash) ;
380
+ self . last_canon_pinned = Some ( hash. clone ( ) ) ;
381
+
370
382
let mut discarded_journals = Vec :: new ( ) ;
371
383
let mut discarded_blocks = Vec :: new ( ) ;
372
384
for ( i, overlay) in level. blocks . into_iter ( ) . enumerate ( ) {
373
385
let mut pinned_children = 0 ;
374
386
// That's the one we need to canonicalize
375
387
if i == index {
388
+
376
389
commit. data . inserted . extend ( overlay. inserted . iter ( ) . map ( |k| {
377
390
(
378
391
k. clone ( ) ,
@@ -680,6 +693,7 @@ mod tests {
680
693
db. commit ( & overlay. insert ( & h2, 11 , & h1, make_changeset ( & [ 5 ] , & [ 3 ] ) ) . unwrap ( ) ) ;
681
694
let mut commit = CommitSet :: default ( ) ;
682
695
overlay. canonicalize ( & h1, & mut commit) . unwrap ( ) ;
696
+ overlay. unpin ( & h1) ;
683
697
db. commit ( & commit) ;
684
698
assert_eq ! ( overlay. levels. len( ) , 1 ) ;
685
699
@@ -707,15 +721,16 @@ mod tests {
707
721
let mut commit = CommitSet :: default ( ) ;
708
722
overlay. canonicalize ( & h1, & mut commit) . unwrap ( ) ;
709
723
db. commit ( & commit) ;
710
- assert ! ( ! contains( & overlay, 5 ) ) ;
724
+ assert ! ( contains( & overlay, 5 ) ) ;
711
725
assert ! ( contains( & overlay, 7 ) ) ;
712
726
assert_eq ! ( overlay. levels. len( ) , 1 ) ;
713
- assert_eq ! ( overlay. parents. len( ) , 1 ) ;
727
+ assert_eq ! ( overlay. parents. len( ) , 2 ) ;
714
728
let mut commit = CommitSet :: default ( ) ;
715
729
overlay. canonicalize ( & h2, & mut commit) . unwrap ( ) ;
730
+ assert ! ( !contains( & overlay, 5 ) ) ;
716
731
db. commit ( & commit) ;
717
732
assert_eq ! ( overlay. levels. len( ) , 0 ) ;
718
- assert_eq ! ( overlay. parents. len( ) , 0 ) ;
733
+ assert_eq ! ( overlay. parents. len( ) , 1 ) ;
719
734
assert ! ( db. data_eq( & make_db( & [ 1 , 4 , 6 , 7 , 8 ] ) ) ) ;
720
735
}
721
736
@@ -732,6 +747,8 @@ mod tests {
732
747
let mut commit = CommitSet :: default ( ) ;
733
748
overlay. canonicalize ( & h_1, & mut commit) . unwrap ( ) ;
734
749
db. commit ( & commit) ;
750
+ // explicitly unpin last block
751
+ overlay. unpin ( & h_1) ;
735
752
assert ! ( !contains( & overlay, 1 ) ) ;
736
753
}
737
754
@@ -818,6 +835,8 @@ mod tests {
818
835
// canonicalize 1. 2 and all its children should be discarded
819
836
let mut commit = CommitSet :: default ( ) ;
820
837
overlay. canonicalize ( & h_1, & mut commit) . unwrap ( ) ;
838
+ // explicitly unpin last block
839
+ overlay. unpin ( & h_1) ;
821
840
db. commit ( & commit) ;
822
841
assert_eq ! ( overlay. levels. len( ) , 2 ) ;
823
842
assert_eq ! ( overlay. parents. len( ) , 6 ) ;
@@ -838,6 +857,7 @@ mod tests {
838
857
// canonicalize 1_2. 1_1 and all its children should be discarded
839
858
let mut commit = CommitSet :: default ( ) ;
840
859
overlay. canonicalize ( & h_1_2, & mut commit) . unwrap ( ) ;
860
+ overlay. unpin ( & h_1_2) ;
841
861
db. commit ( & commit) ;
842
862
assert_eq ! ( overlay. levels. len( ) , 1 ) ;
843
863
assert_eq ! ( overlay. parents. len( ) , 3 ) ;
@@ -854,6 +874,7 @@ mod tests {
854
874
// canonicalize 1_2_2
855
875
let mut commit = CommitSet :: default ( ) ;
856
876
overlay. canonicalize ( & h_1_2_2, & mut commit) . unwrap ( ) ;
877
+ overlay. unpin ( & h_1_2_2) ;
857
878
db. commit ( & commit) ;
858
879
assert_eq ! ( overlay. levels. len( ) , 0 ) ;
859
880
assert_eq ! ( overlay. parents. len( ) , 0 ) ;
@@ -964,6 +985,7 @@ mod tests {
964
985
assert ! ( contains( & overlay, 1 ) ) ;
965
986
overlay. unpin ( & h_21) ;
966
987
assert ! ( !contains( & overlay, 1 ) ) ;
988
+ overlay. unpin ( & h_12) ;
967
989
assert ! ( overlay. pinned. is_empty( ) ) ;
968
990
}
969
991
@@ -998,6 +1020,7 @@ mod tests {
998
1020
999
1021
let mut commit = CommitSet :: default ( ) ;
1000
1022
overlay. canonicalize ( & h21, & mut commit) . unwrap ( ) ; // h11 should stay in the DB
1023
+ overlay. unpin ( & h21) ;
1001
1024
db. commit ( & commit) ;
1002
1025
assert ! ( !contains( & overlay, 21 ) ) ;
1003
1026
}
0 commit comments