Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 81fd394

Browse files
committed
Pin canonincalized block
1 parent 2f0d59d commit 81fd394

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

client/state-db/src/noncanonical.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub struct NonCanonicalOverlay<BlockHash: Hash, Key: Hash> {
3838
// would be deleted but kept around because block is pinned, ref counted.
3939
pinned: HashMap<BlockHash, u32>,
4040
pinned_insertions: HashMap<BlockHash, (Vec<Key>, u32)>,
41+
last_canon_pinned: Option<BlockHash>,
4142
}
4243

4344
#[cfg_attr(test, derive(PartialEq, Debug))]
@@ -225,6 +226,7 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
225226
pinned: Default::default(),
226227
pinned_insertions: Default::default(),
227228
values,
229+
last_canon_pinned: None,
228230
})
229231
}
230232

@@ -367,12 +369,23 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
367369
.position(|overlay| overlay.hash == *hash)
368370
.ok_or(StateDbError::InvalidBlock)?;
369371

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+
370382
let mut discarded_journals = Vec::new();
371383
let mut discarded_blocks = Vec::new();
372384
for (i, overlay) in level.blocks.into_iter().enumerate() {
373385
let mut pinned_children = 0;
374386
// That's the one we need to canonicalize
375387
if i == index {
388+
376389
commit.data.inserted.extend(overlay.inserted.iter().map(|k| {
377390
(
378391
k.clone(),
@@ -680,6 +693,7 @@ mod tests {
680693
db.commit(&overlay.insert(&h2, 11, &h1, make_changeset(&[5], &[3])).unwrap());
681694
let mut commit = CommitSet::default();
682695
overlay.canonicalize(&h1, &mut commit).unwrap();
696+
overlay.unpin(&h1);
683697
db.commit(&commit);
684698
assert_eq!(overlay.levels.len(), 1);
685699

@@ -707,15 +721,16 @@ mod tests {
707721
let mut commit = CommitSet::default();
708722
overlay.canonicalize(&h1, &mut commit).unwrap();
709723
db.commit(&commit);
710-
assert!(!contains(&overlay, 5));
724+
assert!(contains(&overlay, 5));
711725
assert!(contains(&overlay, 7));
712726
assert_eq!(overlay.levels.len(), 1);
713-
assert_eq!(overlay.parents.len(), 1);
727+
assert_eq!(overlay.parents.len(), 2);
714728
let mut commit = CommitSet::default();
715729
overlay.canonicalize(&h2, &mut commit).unwrap();
730+
assert!(!contains(&overlay, 5));
716731
db.commit(&commit);
717732
assert_eq!(overlay.levels.len(), 0);
718-
assert_eq!(overlay.parents.len(), 0);
733+
assert_eq!(overlay.parents.len(), 1);
719734
assert!(db.data_eq(&make_db(&[1, 4, 6, 7, 8])));
720735
}
721736

@@ -732,6 +747,8 @@ mod tests {
732747
let mut commit = CommitSet::default();
733748
overlay.canonicalize(&h_1, &mut commit).unwrap();
734749
db.commit(&commit);
750+
// explicitly unpin last block
751+
overlay.unpin(&h_1);
735752
assert!(!contains(&overlay, 1));
736753
}
737754

@@ -818,6 +835,8 @@ mod tests {
818835
// canonicalize 1. 2 and all its children should be discarded
819836
let mut commit = CommitSet::default();
820837
overlay.canonicalize(&h_1, &mut commit).unwrap();
838+
// explicitly unpin last block
839+
overlay.unpin(&h_1);
821840
db.commit(&commit);
822841
assert_eq!(overlay.levels.len(), 2);
823842
assert_eq!(overlay.parents.len(), 6);
@@ -838,6 +857,7 @@ mod tests {
838857
// canonicalize 1_2. 1_1 and all its children should be discarded
839858
let mut commit = CommitSet::default();
840859
overlay.canonicalize(&h_1_2, &mut commit).unwrap();
860+
overlay.unpin(&h_1_2);
841861
db.commit(&commit);
842862
assert_eq!(overlay.levels.len(), 1);
843863
assert_eq!(overlay.parents.len(), 3);
@@ -854,6 +874,7 @@ mod tests {
854874
// canonicalize 1_2_2
855875
let mut commit = CommitSet::default();
856876
overlay.canonicalize(&h_1_2_2, &mut commit).unwrap();
877+
overlay.unpin(&h_1_2_2);
857878
db.commit(&commit);
858879
assert_eq!(overlay.levels.len(), 0);
859880
assert_eq!(overlay.parents.len(), 0);
@@ -964,6 +985,7 @@ mod tests {
964985
assert!(contains(&overlay, 1));
965986
overlay.unpin(&h_21);
966987
assert!(!contains(&overlay, 1));
988+
overlay.unpin(&h_12);
967989
assert!(overlay.pinned.is_empty());
968990
}
969991

@@ -998,6 +1020,7 @@ mod tests {
9981020

9991021
let mut commit = CommitSet::default();
10001022
overlay.canonicalize(&h21, &mut commit).unwrap(); // h11 should stay in the DB
1023+
overlay.unpin(&h21);
10011024
db.commit(&commit);
10021025
assert!(!contains(&overlay, 21));
10031026
}

0 commit comments

Comments
 (0)