Introduce eager rent collection (#9527)

* Switch AccountsIndex.account_maps from HashMap to BTreeMap

* Introduce eager rent collection

* Start to add tests

* Avoid too short eager rent collection cycles

* Add more tests

* Add more tests...

* Refacotr!!!!!!

* Refactoring follow up

* More tiny cleanups

* Don't rewrite 0-lamport accounts to be deterministic

* Refactor a bit

* Do hard fork, restore tests, and perf. mitigation

* Fix build...

* Refactor and add switch over for testnet (TdS)

* Use to_be_bytes

* cleanup

* More tiny cleanup

* Rebase cleanup

* Set Bank::genesis_hash when resuming from snapshot

* Reorder fns and clean ups

* Better naming and commenting

* Yet more naming clarifications

* Make prefix width strictly uniform for 2-base partition_count

* Fix typo...

* Revert cluster-dependent gate

* kick ci?

* kick ci?

* kick ci?
This commit is contained in:
Ryo Onodera
2020-05-13 16:22:14 +09:00
committed by GitHub
parent ee7f15eff1
commit 1eb40c3fe0
9 changed files with 1003 additions and 35 deletions

View File

@@ -1,7 +1,8 @@
use solana_sdk::{clock::Slot, pubkey::Pubkey};
use std::sync::atomic::{AtomicU64, Ordering};
use std::{
collections::{HashMap, HashSet},
collections::{BTreeMap, HashMap, HashSet},
ops::RangeBounds,
sync::{RwLock, RwLockReadGuard},
};
@@ -14,19 +15,19 @@ type AccountMapEntry<T> = (AtomicU64, RwLock<SlotList<T>>);
#[derive(Debug, Default)]
pub struct AccountsIndex<T> {
pub account_maps: HashMap<Pubkey, AccountMapEntry<T>>,
pub account_maps: BTreeMap<Pubkey, AccountMapEntry<T>>,
pub roots: HashSet<Slot>,
pub uncleaned_roots: HashSet<Slot>,
}
impl<T: Clone> AccountsIndex<T> {
/// call func with every pubkey and index visible from a given set of ancestors
pub fn scan_accounts<F>(&self, ancestors: &Ancestors, mut func: F)
impl<'a, T: 'a + Clone> AccountsIndex<T> {
fn do_scan_accounts<F, I>(&self, ancestors: &Ancestors, mut func: F, iter: I)
where
F: FnMut(&Pubkey, (&T, Slot)) -> (),
I: Iterator<Item = (&'a Pubkey, &'a AccountMapEntry<T>)>,
{
for (pubkey, list) in self.account_maps.iter() {
for (pubkey, list) in iter {
let list_r = &list.1.read().unwrap();
if let Some(index) = self.latest_slot(ancestors, &list_r) {
func(pubkey, (&list_r[index].1, list_r[index].0));
@@ -34,6 +35,23 @@ impl<T: Clone> AccountsIndex<T> {
}
}
/// call func with every pubkey and index visible from a given set of ancestors
pub fn scan_accounts<F>(&self, ancestors: &Ancestors, func: F)
where
F: FnMut(&Pubkey, (&T, Slot)) -> (),
{
self.do_scan_accounts(ancestors, func, self.account_maps.iter());
}
/// call func with every pubkey and index visible from a given set of ancestors with range
pub fn range_scan_accounts<F, R>(&self, ancestors: &Ancestors, range: R, func: F)
where
F: FnMut(&Pubkey, (&T, Slot)) -> (),
R: RangeBounds<Pubkey>,
{
self.do_scan_accounts(ancestors, func, self.account_maps.range(range));
}
fn get_rooted_entries(&self, slice: SlotSlice<T>) -> SlotList<T> {
slice
.iter()