@@ -38,7 +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
+ pinned_canonincalized : Vec < BlockHash > ,
42
42
}
43
43
44
44
#[ cfg_attr( test, derive( PartialEq , Debug ) ) ]
@@ -226,7 +226,7 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
226
226
pinned : Default :: default ( ) ,
227
227
pinned_insertions : Default :: default ( ) ,
228
228
values,
229
- last_canon_pinned : None ,
229
+ pinned_canonincalized : Default :: default ( ) ,
230
230
} )
231
231
}
232
232
@@ -350,6 +350,18 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
350
350
self . last_canonicalized . as_ref ( ) . map ( |& ( _, n) | n)
351
351
}
352
352
353
+ /// Confirm that all changes made to commit sets are on disk. Allows for temporarily pinned
354
+ /// blocks to be released.
355
+ pub fn sync ( & mut self ) {
356
+ let mut pinned = std:: mem:: take ( & mut self . pinned_canonincalized ) ;
357
+ for hash in pinned. iter ( ) {
358
+ self . unpin ( hash)
359
+ }
360
+ pinned. clear ( ) ;
361
+ // Reuse the same memory buffer
362
+ self . pinned_canonincalized = pinned;
363
+ }
364
+
353
365
/// Select a top-level root and canonicalized it. Discards all sibling subtrees and the root.
354
366
/// Add a set of changes of the canonicalized block to `CommitSet`
355
367
/// Return the block number of the canonicalized block
@@ -371,13 +383,9 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
371
383
372
384
// No failures are possible beyond this point.
373
385
374
- // Unpin previously canonicalized block
375
- if let Some ( prev_hash) = self . last_canon_pinned . take ( ) {
376
- self . unpin ( & prev_hash) ;
377
- }
378
386
// Force pin canonicalized block so that it is no discarded immediately
379
387
self . pin ( hash) ;
380
- self . last_canon_pinned = Some ( hash. clone ( ) ) ;
388
+ self . pinned_canonincalized . push ( hash. clone ( ) ) ;
381
389
382
390
let mut discarded_journals = Vec :: new ( ) ;
383
391
let mut discarded_blocks = Vec :: new ( ) ;
@@ -720,16 +728,17 @@ mod tests {
720
728
let mut commit = CommitSet :: default ( ) ;
721
729
overlay. canonicalize ( & h1, & mut commit) . unwrap ( ) ;
722
730
db. commit ( & commit) ;
723
- assert ! ( contains( & overlay, 5 ) ) ;
731
+ overlay. sync ( ) ;
732
+ assert ! ( !contains( & overlay, 5 ) ) ;
724
733
assert ! ( contains( & overlay, 7 ) ) ;
725
734
assert_eq ! ( overlay. levels. len( ) , 1 ) ;
726
- assert_eq ! ( overlay. parents. len( ) , 2 ) ;
735
+ assert_eq ! ( overlay. parents. len( ) , 1 ) ;
727
736
let mut commit = CommitSet :: default ( ) ;
728
737
overlay. canonicalize ( & h2, & mut commit) . unwrap ( ) ;
729
- assert ! ( !contains( & overlay, 5 ) ) ;
730
738
db. commit ( & commit) ;
739
+ overlay. sync ( ) ;
731
740
assert_eq ! ( overlay. levels. len( ) , 0 ) ;
732
- assert_eq ! ( overlay. parents. len( ) , 1 ) ;
741
+ assert_eq ! ( overlay. parents. len( ) , 0 ) ;
733
742
assert ! ( db. data_eq( & make_db( & [ 1 , 4 , 6 , 7 , 8 ] ) ) ) ;
734
743
}
735
744
@@ -746,8 +755,7 @@ mod tests {
746
755
let mut commit = CommitSet :: default ( ) ;
747
756
overlay. canonicalize ( & h_1, & mut commit) . unwrap ( ) ;
748
757
db. commit ( & commit) ;
749
- // explicitly unpin last block
750
- overlay. unpin ( & h_1) ;
758
+ overlay. sync ( ) ;
751
759
assert ! ( !contains( & overlay, 1 ) ) ;
752
760
}
753
761
@@ -834,9 +842,8 @@ mod tests {
834
842
// canonicalize 1. 2 and all its children should be discarded
835
843
let mut commit = CommitSet :: default ( ) ;
836
844
overlay. canonicalize ( & h_1, & mut commit) . unwrap ( ) ;
837
- // explicitly unpin last block
838
- overlay. unpin ( & h_1) ;
839
845
db. commit ( & commit) ;
846
+ overlay. sync ( ) ;
840
847
assert_eq ! ( overlay. levels. len( ) , 2 ) ;
841
848
assert_eq ! ( overlay. parents. len( ) , 6 ) ;
842
849
assert ! ( !contains( & overlay, 1 ) ) ;
@@ -856,8 +863,8 @@ mod tests {
856
863
// canonicalize 1_2. 1_1 and all its children should be discarded
857
864
let mut commit = CommitSet :: default ( ) ;
858
865
overlay. canonicalize ( & h_1_2, & mut commit) . unwrap ( ) ;
859
- overlay. unpin ( & h_1_2) ;
860
866
db. commit ( & commit) ;
867
+ overlay. sync ( ) ;
861
868
assert_eq ! ( overlay. levels. len( ) , 1 ) ;
862
869
assert_eq ! ( overlay. parents. len( ) , 3 ) ;
863
870
assert ! ( !contains( & overlay, 11 ) ) ;
@@ -873,8 +880,8 @@ mod tests {
873
880
// canonicalize 1_2_2
874
881
let mut commit = CommitSet :: default ( ) ;
875
882
overlay. canonicalize ( & h_1_2_2, & mut commit) . unwrap ( ) ;
876
- overlay. unpin ( & h_1_2_2) ;
877
883
db. commit ( & commit) ;
884
+ overlay. sync ( ) ;
878
885
assert_eq ! ( overlay. levels. len( ) , 0 ) ;
879
886
assert_eq ! ( overlay. parents. len( ) , 0 ) ;
880
887
assert ! ( db. data_eq( & make_db( & [ 1 , 12 , 122 ] ) ) ) ;
@@ -958,6 +965,28 @@ mod tests {
958
965
assert ! ( !contains( & overlay, 1 ) ) ;
959
966
}
960
967
968
+ #[ test]
969
+ fn pins_canonicalized ( ) {
970
+ let mut db = make_db ( & [ ] ) ;
971
+
972
+ let ( h_1, c_1) = ( H256 :: random ( ) , make_changeset ( & [ 1 ] , & [ ] ) ) ;
973
+ let ( h_2, c_2) = ( H256 :: random ( ) , make_changeset ( & [ 2 ] , & [ ] ) ) ;
974
+
975
+ let mut overlay = NonCanonicalOverlay :: < H256 , H256 > :: new ( & db) . unwrap ( ) ;
976
+ db. commit ( & overlay. insert ( & h_1, 1 , & H256 :: default ( ) , c_1) . unwrap ( ) ) ;
977
+ db. commit ( & overlay. insert ( & h_2, 2 , & h_1, c_2) . unwrap ( ) ) ;
978
+
979
+ let mut commit = CommitSet :: default ( ) ;
980
+ overlay. canonicalize ( & h_1, & mut commit) . unwrap ( ) ;
981
+ overlay. canonicalize ( & h_2, & mut commit) . unwrap ( ) ;
982
+ assert ! ( contains( & overlay, 1 ) ) ;
983
+ assert ! ( contains( & overlay, 2 ) ) ;
984
+ db. commit ( & commit) ;
985
+ overlay. sync ( ) ;
986
+ assert ! ( !contains( & overlay, 1 ) ) ;
987
+ assert ! ( !contains( & overlay, 2 ) ) ;
988
+ }
989
+
961
990
#[ test]
962
991
fn pin_keeps_parent ( ) {
963
992
let mut db = make_db ( & [ ] ) ;
@@ -1019,8 +1048,8 @@ mod tests {
1019
1048
1020
1049
let mut commit = CommitSet :: default ( ) ;
1021
1050
overlay. canonicalize ( & h21, & mut commit) . unwrap ( ) ; // h11 should stay in the DB
1022
- overlay. unpin ( & h21) ;
1023
1051
db. commit ( & commit) ;
1052
+ overlay. sync ( ) ;
1024
1053
assert ! ( !contains( & overlay, 21 ) ) ;
1025
1054
}
1026
1055
0 commit comments