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] Add TieredStorage::write_accounts_to_hot_storage() API #382

Closed
Closed
Show file tree
Hide file tree
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
71 changes: 68 additions & 3 deletions accounts-db/src/accounts_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use {
accounts_hash::AccountHash,
append_vec::{AppendVec, AppendVecError},
storable_accounts::StorableAccounts,
tiered_storage::error::TieredStorageError,
tiered_storage::{error::TieredStorageError, index::IndexOffset, TieredStorage},
},
solana_sdk::{account::ReadableAccount, clock::Slot, pubkey::Pubkey},
std::{
Expand Down Expand Up @@ -56,6 +56,7 @@ pub type Result<T> = std::result::Result<T, AccountsFileError>;
/// under different formats.
pub enum AccountsFile {
AppendVec(AppendVec),
TieredStorage(TieredStorage),
}

impl AccountsFile {
Expand All @@ -64,43 +65,80 @@ impl AccountsFile {
/// The second element of the returned tuple is the number of accounts in the
/// accounts file.
pub fn new_from_file(path: impl AsRef<Path>, current_len: usize) -> Result<(Self, usize)> {
let (av, num_accounts) = AppendVec::new_from_file(path, current_len)?;
Ok((Self::AppendVec(av), num_accounts))
match TieredStorage::new_readonly(path.as_ref()) {
Ok(tiered_storage) => {
// unwrap() note: TieredStorage::new_readonly() is guaranteed to have a valid
// reader instance when opening with new_readonly.
let num_accounts = tiered_storage.reader().unwrap().num_accounts();
Ok((Self::TieredStorage(tiered_storage), num_accounts))
}
Err(TieredStorageError::MagicNumberMismatch(_, _)) => {
// In case of MagicNumberMismatch, we can assume that this is not
// a tiered-storage file.
let (av, num_accounts) = AppendVec::new_from_file(path, current_len)?;
Ok((Self::AppendVec(av), num_accounts))
}
Err(e) => Err(AccountsFileError::TieredStorageError(e)),
}
}

pub fn flush(&self) -> Result<()> {
match self {
Self::AppendVec(av) => av.flush(),
Self::TieredStorage(_) => Ok(()),
}
}

pub fn reset(&self) {
match self {
Self::AppendVec(av) => av.reset(),
Self::TieredStorage(_) => {}
}
}

pub fn remaining_bytes(&self) -> u64 {
match self {
Self::AppendVec(av) => av.remaining_bytes(),
Self::TieredStorage(ts) => {
if ts.is_read_only() {
0
} else {
u64::MAX
}
}
}
}

pub fn len(&self) -> usize {
match self {
Self::AppendVec(av) => av.len(),
Self::TieredStorage(ts) => ts.file_size().unwrap_or(0) as usize,
}
}

pub fn is_empty(&self) -> bool {
match self {
Self::AppendVec(av) => av.is_empty(),
Self::TieredStorage(ts) => ts.file_size().unwrap_or(0) == 0,
}
}

pub fn capacity(&self) -> u64 {
match self {
Self::AppendVec(av) => av.capacity(),
Self::TieredStorage(ts) => {
// As TieredStorage doesn't have the concept about capacity,
// here we return the file size when the file was written.
if ts.is_read_only() {
return ts.file_size().unwrap_or(0);
}
// Or u64::MAX, indicating it can accept as many data as
// possible.
// TODO: while TieredStorage isn't directly capped by size, it
// has maximum numbers of accounts and owners. A proper API
// is needed to capture this.
u64::MAX
}
}
}

Expand All @@ -114,6 +152,16 @@ impl AccountsFile {
pub fn get_account(&self, index: usize) -> Option<(StoredAccountMeta<'_>, usize)> {
match self {
Self::AppendVec(av) => av.get_account(index),
Self::TieredStorage(ts) => {
if let Some(reader) = ts.reader() {
if let Ok(Some((metas, index_offset))) =
reader.get_account(IndexOffset(index as u32))
{
return Some((metas, index_offset.0 as usize));
}
}
None
}
}
}

Expand All @@ -124,13 +172,20 @@ impl AccountsFile {
) -> std::result::Result<usize, MatchAccountOwnerError> {
match self {
Self::AppendVec(av) => av.account_matches_owners(offset, owners),
Self::TieredStorage(ts) => {
let Some(reader) = ts.reader() else {
return Err(MatchAccountOwnerError::UnableToLoad);
};
reader.account_matches_owners(IndexOffset(offset as u32), owners)
}
}
}

/// Return the path of the underlying account file.
pub fn get_path(&self) -> PathBuf {
match self {
Self::AppendVec(av) => av.get_path(),
Self::TieredStorage(ts) => ts.path().to_path_buf(),
}
}

Expand All @@ -143,6 +198,14 @@ impl AccountsFile {
pub fn accounts(&self, offset: usize) -> Vec<StoredAccountMeta> {
match self {
Self::AppendVec(av) => av.accounts(offset),
Self::TieredStorage(ts) => {
let Some(reader) = ts.reader() else {
return vec![];
};
reader
.accounts(IndexOffset(offset as u32))
.unwrap_or_default()
}
}
}

Expand All @@ -166,6 +229,7 @@ impl AccountsFile {
) -> Option<Vec<StoredAccountInfo>> {
match self {
Self::AppendVec(av) => av.append_accounts(accounts, skip),
Self::TieredStorage(ts) => ts.write_accounts_to_hot_storage(accounts, skip).ok(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this is effectively the same as using the HOT_FORMAT constant. So API details are still leaking out.

}
}
}
Expand Down Expand Up @@ -204,6 +268,7 @@ pub mod tests {
pub(crate) fn set_current_len_for_tests(&self, len: usize) {
match self {
Self::AppendVec(av) => av.set_current_len_for_tests(len),
Self::TieredStorage(_) => {}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions accounts-db/src/ancient_append_vecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,9 @@ pub const fn get_ancient_append_vec_capacity() -> u64 {
pub fn is_ancient(storage: &AccountsFile) -> bool {
match storage {
AccountsFile::AppendVec(storage) => storage.capacity() >= get_ancient_append_vec_capacity(),
AccountsFile::TieredStorage(ts) => {
ts.file_size().unwrap_or(0) >= get_ancient_append_vec_capacity()
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions accounts-db/src/tiered_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ impl TieredStorage {
}
}

pub fn write_accounts_to_hot_storage<
'a,
'b,
T: ReadableAccount + Sync,
U: StorableAccounts<'a, T>,
V: Borrow<AccountHash>,
>(
&self,
accounts: &StorableAccountsWithHashesAndWriteVersions<'a, 'b, T, U, V>,
skip: usize,
) -> TieredStorageResult<Vec<StoredAccountInfo>> {
self.write_accounts(accounts, skip, &HOT_FORMAT)
}

/// Returns the underlying reader of the TieredStorage. None will be
/// returned if it's is_read_only() returns false.
pub fn reader(&self) -> Option<&TieredStorageReader> {
Expand Down
Loading