Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TieredStorage] HotStorageReader::get_account_offset #33824

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion accounts-db/src/tiered_storage/hot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,17 @@ impl HotStorageReader {
let (meta, _) = get_type::<HotAccountMeta>(&self.mmap, offset)?;
Ok(meta)
}

/// Returns the offset to the account stored in the underlying TieredStorage
/// file associated with the specified index.
fn get_account_offset(&self, index: usize) -> TieredStorageResult<u64> {
// As Hot storage currently don't support compression, each account has
// its own account block. As a result, the account block offset is the
// account offset.
self.footer
.account_index_format
.get_account_block_offset(&self.mmap, &self.footer, index)
}
}

#[cfg(test)]
Expand All @@ -241,7 +252,7 @@ pub mod tests {
FOOTER_SIZE,
},
hot::{HotAccountMeta, HotStorageReader},
index::AccountIndexFormat,
index::{AccountIndexFormat, AccountIndexWriterEntry},
meta::{AccountMetaFlags, AccountMetaOptionalFields, TieredAccountMeta},
},
memoffset::offset_of,
Expand Down Expand Up @@ -460,4 +471,56 @@ pub mod tests {
}
assert_eq!(&footer, hot_storage.footer());
}

#[test]
fn test_hot_storage_index_block() {
const NUM_ACCOUNTS: u32 = 10;
let mut rng = rand::thread_rng();

// Generate the index entry of each account
let addresses: Vec<_> = std::iter::repeat_with(Pubkey::new_unique)
.take(NUM_ACCOUNTS as usize)
.collect();
let index_entries: Vec<_> = addresses
.iter()
.map(|address| AccountIndexWriterEntry {
address,
block_offset: rng.gen_range(128..2048),
intra_block_offset: 0,
})
.collect();

// Generate a new temp path that is guaranteed to NOT already have a file.
let temp_dir = TempDir::new().unwrap();
let path = temp_dir.path().join("test_hot_storage_footer");

let footer = TieredStorageFooter {
account_meta_format: AccountMetaFormat::Hot,
account_index_format: AccountIndexFormat::AddressAndOffset,
// Set account_index_offset to 0 as we don't write any account meta &
// data in this test, while this field is usually non-zero in prod.
account_index_offset: 0,
account_entry_count: NUM_ACCOUNTS,
..TieredStorageFooter::default()
};

{
let file = TieredStorageFile::new_writable(&path).unwrap();
footer
.account_index_format
.write_index_block(&file, &index_entries)
.unwrap();

footer.write_footer_block(&file).unwrap();
}

let hot_storage = HotStorageReader::new_from_path(&path).unwrap();
for (i, index_entry) in index_entries.iter().enumerate() {
assert_eq!(
index_entry.block_offset,
hot_storage.get_account_offset(i).unwrap(),
);
}
assert_eq!(&footer, hot_storage.footer());
}
}