introduce trait IndexValue for accounts index (#19859)

This commit is contained in:
Jeff Washington (jwash) 2021-09-14 17:51:07 -05:00 committed by GitHub
parent 21bc7e94f5
commit fc647eed19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 27 deletions

View File

@ -24,8 +24,9 @@ use crate::{
accounts_hash::{AccountsHash, CalculateHashIntermediate, HashStats, PreviousPass}, accounts_hash::{AccountsHash, CalculateHashIntermediate, HashStats, PreviousPass},
accounts_index::{ accounts_index::{
AccountIndexGetResult, AccountSecondaryIndexes, AccountsIndex, AccountsIndexConfig, AccountIndexGetResult, AccountSecondaryIndexes, AccountsIndex, AccountsIndexConfig,
AccountsIndexRootsStats, IndexKey, IsCached, RefCount, ScanResult, SlotList, SlotSlice, AccountsIndexRootsStats, IndexKey, IndexValue, IsCached, RefCount, ScanResult, SlotList,
ZeroLamport, ACCOUNTS_INDEX_CONFIG_FOR_BENCHMARKS, ACCOUNTS_INDEX_CONFIG_FOR_TESTING, SlotSlice, ZeroLamport, ACCOUNTS_INDEX_CONFIG_FOR_BENCHMARKS,
ACCOUNTS_INDEX_CONFIG_FOR_TESTING,
}, },
ancestors::Ancestors, ancestors::Ancestors,
append_vec::{AppendVec, StoredAccountMeta, StoredMeta, StoredMetaWriteVersion}, append_vec::{AppendVec, StoredAccountMeta, StoredMeta, StoredMetaWriteVersion},
@ -278,6 +279,8 @@ impl IsCached for AccountInfo {
} }
} }
impl IndexValue for AccountInfo {}
impl ZeroLamport for AccountInfo { impl ZeroLamport for AccountInfo {
fn is_zero_lamport(&self) -> bool { fn is_zero_lamport(&self) -> bool {
self.lamports == 0 self.lamports == 0

View File

@ -54,6 +54,11 @@ pub trait IsCached:
fn is_cached(&self) -> bool; fn is_cached(&self) -> bool;
} }
pub trait IndexValue:
'static + IsCached + Clone + Debug + PartialEq + ZeroLamport + Copy + Default + Sync + Send
{
}
#[derive(Error, Debug, PartialEq)] #[derive(Error, Debug, PartialEq)]
pub enum ScanError { pub enum ScanError {
#[error("Node detected it replayed bad version of slot {slot:?} with id {bank_id:?}, thus the scan on said slot was aborted")] #[error("Node detected it replayed bad version of slot {slot:?} with id {bank_id:?}, thus the scan on said slot was aborted")]
@ -117,7 +122,7 @@ pub struct AccountMapEntryInner<T> {
pub slot_list: RwLock<SlotList<T>>, pub slot_list: RwLock<SlotList<T>>,
} }
impl<T: IsCached> AccountMapEntryInner<T> { impl<T: IndexValue> AccountMapEntryInner<T> {
pub fn ref_count(&self) -> RefCount { pub fn ref_count(&self) -> RefCount {
self.ref_count.load(Ordering::Relaxed) self.ref_count.load(Ordering::Relaxed)
} }
@ -131,27 +136,27 @@ impl<T: IsCached> AccountMapEntryInner<T> {
} }
} }
pub enum AccountIndexGetResult<'a, T: IsCached> { pub enum AccountIndexGetResult<'a, T: IndexValue> {
Found(ReadAccountMapEntry<T>, usize), Found(ReadAccountMapEntry<T>, usize),
NotFoundOnFork, NotFoundOnFork,
Missing(AccountMapsReadLock<'a, T>), Missing(AccountMapsReadLock<'a, T>),
} }
#[self_referencing] #[self_referencing]
pub struct ReadAccountMapEntry<T: IsCached> { pub struct ReadAccountMapEntry<T: IndexValue> {
owned_entry: AccountMapEntry<T>, owned_entry: AccountMapEntry<T>,
#[borrows(owned_entry)] #[borrows(owned_entry)]
#[covariant] #[covariant]
slot_list_guard: RwLockReadGuard<'this, SlotList<T>>, slot_list_guard: RwLockReadGuard<'this, SlotList<T>>,
} }
impl<T: IsCached> Debug for ReadAccountMapEntry<T> { impl<T: IndexValue> Debug for ReadAccountMapEntry<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self.borrow_owned_entry()) write!(f, "{:?}", self.borrow_owned_entry())
} }
} }
impl<T: IsCached> ReadAccountMapEntry<T> { impl<T: IndexValue> ReadAccountMapEntry<T> {
pub fn from_account_map_entry(account_map_entry: AccountMapEntry<T>) -> Self { pub fn from_account_map_entry(account_map_entry: AccountMapEntry<T>) -> Self {
ReadAccountMapEntryBuilder { ReadAccountMapEntryBuilder {
owned_entry: account_map_entry, owned_entry: account_map_entry,
@ -178,14 +183,14 @@ impl<T: IsCached> ReadAccountMapEntry<T> {
} }
#[self_referencing] #[self_referencing]
pub struct WriteAccountMapEntry<T: IsCached> { pub struct WriteAccountMapEntry<T: IndexValue> {
owned_entry: AccountMapEntry<T>, owned_entry: AccountMapEntry<T>,
#[borrows(owned_entry)] #[borrows(owned_entry)]
#[covariant] #[covariant]
slot_list_guard: RwLockWriteGuard<'this, SlotList<T>>, slot_list_guard: RwLockWriteGuard<'this, SlotList<T>>,
} }
impl<T: IsCached> WriteAccountMapEntry<T> { impl<T: IndexValue> WriteAccountMapEntry<T> {
pub fn from_account_map_entry(account_map_entry: AccountMapEntry<T>) -> Self { pub fn from_account_map_entry(account_map_entry: AccountMapEntry<T>) -> Self {
WriteAccountMapEntryBuilder { WriteAccountMapEntryBuilder {
owned_entry: account_map_entry, owned_entry: account_map_entry,
@ -522,7 +527,7 @@ pub struct AccountsIndexRootsStats {
pub unrooted_cleaned_count: usize, pub unrooted_cleaned_count: usize,
} }
pub struct AccountsIndexIterator<'a, T: IsCached> { pub struct AccountsIndexIterator<'a, T: IndexValue> {
account_maps: &'a LockMapTypeSlice<T>, account_maps: &'a LockMapTypeSlice<T>,
bin_calculator: &'a PubkeyBinCalculator16, bin_calculator: &'a PubkeyBinCalculator16,
start_bound: Bound<Pubkey>, start_bound: Bound<Pubkey>,
@ -531,7 +536,7 @@ pub struct AccountsIndexIterator<'a, T: IsCached> {
collect_all_unsorted: bool, collect_all_unsorted: bool,
} }
impl<'a, T: IsCached> AccountsIndexIterator<'a, T> { impl<'a, T: IndexValue> AccountsIndexIterator<'a, T> {
fn range<R>( fn range<R>(
map: &AccountMapsReadLock<T>, map: &AccountMapsReadLock<T>,
range: R, range: R,
@ -615,7 +620,7 @@ impl<'a, T: IsCached> AccountsIndexIterator<'a, T> {
} }
} }
impl<'a, T: IsCached> Iterator for AccountsIndexIterator<'a, T> { impl<'a, T: IndexValue> Iterator for AccountsIndexIterator<'a, T> {
type Item = Vec<(Pubkey, AccountMapEntry<T>)>; type Item = Vec<(Pubkey, AccountMapEntry<T>)>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.is_finished { if self.is_finished {
@ -676,7 +681,7 @@ impl ScanSlotTracker {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct AccountsIndex<T: IsCached> { pub struct AccountsIndex<T: IndexValue> {
pub account_maps: LockMapType<T>, pub account_maps: LockMapType<T>,
pub bin_calculator: PubkeyBinCalculator16, pub bin_calculator: PubkeyBinCalculator16,
program_id_index: SecondaryIndex<DashMapSecondaryIndexEntry>, program_id_index: SecondaryIndex<DashMapSecondaryIndexEntry>,
@ -699,7 +704,7 @@ pub struct AccountsIndex<T: IsCached> {
storage: AccountsIndexStorage<T>, storage: AccountsIndexStorage<T>,
} }
impl<T: IsCached> AccountsIndex<T> { impl<T: IndexValue> AccountsIndex<T> {
pub fn default_for_tests() -> Self { pub fn default_for_tests() -> Self {
Self::new(Some(ACCOUNTS_INDEX_CONFIG_FOR_TESTING)) Self::new(Some(ACCOUNTS_INDEX_CONFIG_FOR_TESTING))
} }
@ -1824,7 +1829,7 @@ pub mod tests {
} }
} }
impl<'a, T: IsCached> AccountIndexGetResult<'a, T> { impl<'a, T: IndexValue> AccountIndexGetResult<'a, T> {
pub fn unwrap(self) -> (ReadAccountMapEntry<T>, usize) { pub fn unwrap(self) -> (ReadAccountMapEntry<T>, usize) {
match self { match self {
AccountIndexGetResult::Found(lock, size) => (lock, size), AccountIndexGetResult::Found(lock, size) => (lock, size),
@ -2614,6 +2619,7 @@ pub mod tests {
type AccountInfoTest = f64; type AccountInfoTest = f64;
impl IndexValue for AccountInfoTest {}
impl IsCached for AccountInfoTest { impl IsCached for AccountInfoTest {
fn is_cached(&self) -> bool { fn is_cached(&self) -> bool {
true true
@ -2734,7 +2740,7 @@ pub mod tests {
} }
} }
fn test_new_entry_code_paths_helper<T: IsCached>( fn test_new_entry_code_paths_helper<T: IndexValue>(
account_infos: [T; 2], account_infos: [T; 2],
is_cached: bool, is_cached: bool,
upsert: bool, upsert: bool,
@ -3416,7 +3422,7 @@ pub mod tests {
assert!(found_key); assert!(found_key);
} }
fn account_maps_len_expensive<T: IsCached>(index: &AccountsIndex<T>) -> usize { fn account_maps_len_expensive<T: IndexValue>(index: &AccountsIndex<T>) -> usize {
index index
.account_maps .account_maps
.iter() .iter()
@ -3944,6 +3950,8 @@ pub mod tests {
); );
} }
impl IndexValue for bool {}
impl IndexValue for u64 {}
impl IsCached for bool { impl IsCached for bool {
fn is_cached(&self) -> bool { fn is_cached(&self) -> bool {
false false

View File

@ -1,4 +1,4 @@
use crate::accounts_index::IsCached; use crate::accounts_index::IndexValue;
use crate::bucket_map_holder::BucketMapHolder; use crate::bucket_map_holder::BucketMapHolder;
use crate::waitable_condvar::WaitableCondvar; use crate::waitable_condvar::WaitableCondvar;
use std::{ use std::{
@ -15,7 +15,7 @@ use std::{
// and it will stop all the background threads and join them. // and it will stop all the background threads and join them.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct AccountsIndexStorage<T: IsCached> { pub struct AccountsIndexStorage<T: IndexValue> {
// for managing the bg threads // for managing the bg threads
exit: Arc<AtomicBool>, exit: Arc<AtomicBool>,
wait: Arc<WaitableCondvar>, wait: Arc<WaitableCondvar>,
@ -25,7 +25,7 @@ pub struct AccountsIndexStorage<T: IsCached> {
storage: Arc<BucketMapHolder<T>>, storage: Arc<BucketMapHolder<T>>,
} }
impl<T: IsCached> Drop for AccountsIndexStorage<T> { impl<T: IndexValue> Drop for AccountsIndexStorage<T> {
fn drop(&mut self) { fn drop(&mut self) {
self.exit.store(true, Ordering::Relaxed); self.exit.store(true, Ordering::Relaxed);
self.wait.notify_all(); self.wait.notify_all();
@ -35,7 +35,7 @@ impl<T: IsCached> Drop for AccountsIndexStorage<T> {
} }
} }
impl<T: IsCached> AccountsIndexStorage<T> { impl<T: IndexValue> AccountsIndexStorage<T> {
pub fn new() -> AccountsIndexStorage<T> { pub fn new() -> AccountsIndexStorage<T> {
let storage = Arc::new(BucketMapHolder::new()); let storage = Arc::new(BucketMapHolder::new());
let storage_ = storage.clone(); let storage_ = storage.clone();

View File

@ -1,4 +1,4 @@
use crate::accounts_index::IsCached; use crate::accounts_index::IndexValue;
use crate::bucket_map_holder_stats::BucketMapHolderStats; use crate::bucket_map_holder_stats::BucketMapHolderStats;
use crate::waitable_condvar::WaitableCondvar; use crate::waitable_condvar::WaitableCondvar;
use std::fmt::Debug; use std::fmt::Debug;
@ -8,12 +8,12 @@ use std::time::Duration;
// will eventually hold the bucket map // will eventually hold the bucket map
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct BucketMapHolder<T: IsCached> { pub struct BucketMapHolder<T: IndexValue> {
pub stats: BucketMapHolderStats, pub stats: BucketMapHolderStats,
_phantom: std::marker::PhantomData<T>, _phantom: std::marker::PhantomData<T>,
} }
impl<T: IsCached> BucketMapHolder<T> { impl<T: IndexValue> BucketMapHolder<T> {
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
} }

View File

@ -1,5 +1,5 @@
use crate::accounts_index::{ use crate::accounts_index::{
AccountMapEntry, AccountMapEntryInner, IsCached, SlotList, WriteAccountMapEntry, AccountMapEntry, AccountMapEntryInner, IndexValue, SlotList, WriteAccountMapEntry,
}; };
use crate::accounts_index_storage::AccountsIndexStorage; use crate::accounts_index_storage::AccountsIndexStorage;
use crate::bucket_map_holder::BucketMapHolder; use crate::bucket_map_holder::BucketMapHolder;
@ -16,14 +16,14 @@ type K = Pubkey;
// one instance of this represents one bin of the accounts index. // one instance of this represents one bin of the accounts index.
#[derive(Debug)] #[derive(Debug)]
pub struct InMemAccountsIndex<T: IsCached> { pub struct InMemAccountsIndex<T: IndexValue> {
// backing store // backing store
map: HashMap<Pubkey, AccountMapEntry<T>>, map: HashMap<Pubkey, AccountMapEntry<T>>,
storage: Arc<BucketMapHolder<T>>, storage: Arc<BucketMapHolder<T>>,
bin: usize, bin: usize,
} }
impl<T: IsCached> InMemAccountsIndex<T> { impl<T: IndexValue> InMemAccountsIndex<T> {
pub fn new(storage: &AccountsIndexStorage<T>, bin: usize) -> Self { pub fn new(storage: &AccountsIndexStorage<T>, bin: usize) -> Self {
Self { Self {
map: HashMap::new(), map: HashMap::new(),