Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
wip: disk idx: disk_unknown
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffwashington committed May 5, 2022
1 parent b4c3b66 commit 3b1dcb5
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
20 changes: 20 additions & 0 deletions runtime/src/accounts_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,30 @@ pub struct AccountMapEntryMeta {
pub dirty: AtomicBool,
/// 'age' at which this entry should be purged from the cache (implements lru)
pub age: AtomicU8,
/// true if we don't know whether this item exists on disk or not
pub disk_unknown: AtomicBool,
}

impl AccountMapEntryMeta {
pub fn new_dirty<T: IndexValue>(storage: &Arc<BucketMapHolder<T>>) -> Self {
AccountMapEntryMeta {
dirty: AtomicBool::new(true),
age: AtomicU8::new(storage.future_age_to_flush()),
disk_unknown: AtomicBool::new(false),
}
}
pub fn new_dirty_disk_unknown<T: IndexValue>(storage: &Arc<BucketMapHolder<T>>) -> Self {
AccountMapEntryMeta {
dirty: AtomicBool::new(true),
age: AtomicU8::new(storage.future_age_to_flush()),
disk_unknown: AtomicBool::new(true),
}
}
pub fn new_clean<T: IndexValue>(storage: &Arc<BucketMapHolder<T>>) -> Self {
AccountMapEntryMeta {
dirty: AtomicBool::new(false),
age: AtomicU8::new(storage.future_age_to_flush()),
disk_unknown: AtomicBool::new(false),
}
}
}
Expand Down Expand Up @@ -301,6 +312,14 @@ impl<T: IndexValue> AccountMapEntryInner<T> {
Ordering::Relaxed,
);
}

pub fn set_disk_unknown(&self) {
self.meta.disk_unknown.store(true, Ordering::Release);
}

pub fn disk_unknown(&self) -> bool {
self.meta.disk_unknown.load(Ordering::Acquire)
}
}

pub enum AccountIndexGetResult<T: IndexValue> {
Expand Down Expand Up @@ -2017,6 +2036,7 @@ pub mod tests {
let meta = AccountMapEntryMeta {
dirty: AtomicBool::new(entry.dirty()),
age: AtomicU8::new(entry.age()),
disk_unknown: AtomicBool::new(false),
};
PreAllocatedAccountMapEntry::Entry(Arc::new(AccountMapEntryInner::new(
vec![(slot, account_info)],
Expand Down
38 changes: 33 additions & 5 deletions runtime/src/in_mem_accounts_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
) -> RT {
self.get_only_in_mem(pubkey, |entry| {
if let Some(entry) = entry {
if entry.disk_unknown() {
// we found the pubkey
// but, we haven't checked to see if there is more on disk
// so, we have to load from disk first, then merge with in-mem
// right now we have a read lock on the in-mem idx, fwiw
}
entry.set_age(self.storage.future_age_to_flush());
callback(Some(entry)).1
} else {
Expand All @@ -242,7 +248,17 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
let mut map = self.map().write().unwrap();
let entry = map.entry(*pubkey);
match entry {
Entry::Occupied(occupied) => callback(Some(occupied.get())).1,
Entry::Occupied(occupied) => {
let entry = occupied.get();
if entry.disk_unknown() {
// we found the pubkey
// but, we haven't checked to see if there is more on disk
// so, we have to load from disk first, then merge with in-mem
// right now we have a write lock on the in-mem idx, fwiw
// todo: somewhere we remove a slot from the slot list
}
callback(Some(entry)).1
}
Entry::Vacant(vacant) => {
let (add_to_cache, rt) = callback(Some(&disk_entry));

Expand Down Expand Up @@ -319,6 +335,7 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
let entry = map.entry(pubkey);
m.stop();
let found = matches!(entry, Entry::Occupied(_));
// if entry.disk_unknown(), we don't know if the slot list is empty because we haven't checked on disk.
let result = self.remove_if_slot_list_empty_entry(entry);
drop(map);

Expand Down Expand Up @@ -364,6 +381,8 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
// try to get it just from memory first using only a read lock
self.get_only_in_mem(pubkey, |entry| {
if let Some(entry) = entry {
// if entry.disk_unknown(), that is ok.
// updating the slot list here will either update the same slot we already updated or insert a new slot that we also don't know if it is on disk or not
Self::lock_and_update_slot_list(
entry,
new_value.into(),
Expand All @@ -381,6 +400,8 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
match entry {
Entry::Occupied(mut occupied) => {
let current = occupied.get_mut();
// if current.disk_unknown(), that is ok.
// updating the slot list here will either update the same slot we already updated or insert a new slot that we also don't know if it is on disk or not
Self::lock_and_update_slot_list(
current,
new_value.into(),
Expand All @@ -397,6 +418,7 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
// desired to be this for filler accounts: self.storage.get_startup();
// but, this has proven to be far too slow at high account counts
let directly_to_disk = false;
let enable_disk_unknown = true;
if directly_to_disk {
// We may like this to always run, but it is unclear.
// If disk bucket needs to resize, then this call can stall for a long time.
Expand All @@ -412,9 +434,11 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
self.stats().insert_or_delete(true, self.bin);
}
} else {
// go to in-mem cache first
let disk_entry = self.load_account_entry_from_disk(vacant.key());
let new_value = if let Some(disk_entry) = disk_entry {
// put new_value in in-mem cache. First we have to see if it already exists on disk and if so, merge.
let new_value = if let Some(disk_entry) = (!enable_disk_unknown)
.then(|| self.load_account_entry_from_disk(vacant.key()))
.flatten()
{
// on disk, so merge new_value with what was on disk
Self::lock_and_update_slot_list(
&disk_entry,
Expand All @@ -427,7 +451,11 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
} else {
// not on disk, so insert new thing
self.stats().insert_or_delete(true, self.bin);
new_value.into_account_map_entry(&self.storage)
let entry = new_value.into_account_map_entry(&self.storage);
if enable_disk_unknown {
entry.set_disk_unknown();
}
entry
};
assert!(new_value.dirty());
vacant.insert(new_value);
Expand Down

0 comments on commit 3b1dcb5

Please sign in to comment.