AcctInfo: store offset in AccountInfo as u32 (#21895)

This commit is contained in:
Jeff Washington (jwash) 2021-12-15 15:41:11 -06:00 committed by GitHub
parent e5be96d8bf
commit 46e5350d8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 13 deletions

View File

@ -5,6 +5,7 @@
use crate::{
accounts_db::{AppendVecId, CACHE_VIRTUAL_OFFSET},
accounts_index::{IsCached, ZeroLamport},
append_vec::ALIGN_BOUNDARY_OFFSET,
};
/// offset within an append vec to account data
@ -54,13 +55,19 @@ impl StorageLocation {
}
}
/// how large the offset we store in AccountInfo is
/// Note this is a smaller datatype than 'Offset'
/// AppendVecs store accounts aligned to u64, so offset is always a multiple of 8 (sizeof(u64))
pub type OffsetReduced = u32;
#[derive(Default, Debug, PartialEq, Clone, Copy)]
pub struct AccountInfo {
/// index identifying the append storage
store_id: AppendVecId,
/// offset into the storage
offset: Offset,
/// offset = 'reduced_offset' / ALIGN_BOUNDARY_OFFSET into the storage
/// Note this is a smaller type than 'Offset'
reduced_offset: OffsetReduced,
/// needed to track shrink candidacy in bytes. Used to update the number
/// of alive bytes in an AppendVec as newer slots purge outdated entries
@ -99,7 +106,7 @@ impl AccountInfo {
pub fn new(storage_location: StorageLocation, stored_size: StoredSize, lamports: u64) -> Self {
assert_eq!(stored_size & ALL_FLAGS, 0);
let mut stored_size_mask = stored_size;
let (store_id, offset) = match storage_location {
let (store_id, raw_offset) = match storage_location {
StorageLocation::AppendVec(store_id, offset) => (store_id, offset),
StorageLocation::Cached => {
stored_size_mask |= IS_CACHED_STORE_ID_FLAG;
@ -111,11 +118,14 @@ impl AccountInfo {
if lamports == 0 {
stored_size_mask |= IS_ZERO_LAMPORT_FLAG;
}
Self {
let reduced_offset: OffsetReduced = (raw_offset / ALIGN_BOUNDARY_OFFSET) as OffsetReduced;
let result = Self {
store_id,
offset,
reduced_offset,
stored_size_mask,
}
};
assert_eq!(result.offset(), raw_offset, "illegal offset");
result
}
pub fn store_id(&self) -> AppendVecId {
@ -124,7 +134,7 @@ impl AccountInfo {
}
pub fn offset(&self) -> Offset {
self.offset
(self.reduced_offset as Offset) * ALIGN_BOUNDARY_OFFSET
}
pub fn stored_size(&self) -> StoredSize {
@ -136,7 +146,31 @@ impl AccountInfo {
if self.is_cached() {
StorageLocation::Cached
} else {
StorageLocation::AppendVec(self.store_id, self.offset)
StorageLocation::AppendVec(self.store_id, self.offset())
}
}
}
#[cfg(test)]
mod test {
use {super::*, crate::append_vec::MAXIMUM_APPEND_VEC_FILE_SIZE};
#[test]
fn test_limits() {
for offset in [
MAXIMUM_APPEND_VEC_FILE_SIZE as Offset,
0,
ALIGN_BOUNDARY_OFFSET,
4 * ALIGN_BOUNDARY_OFFSET,
] {
let info = AccountInfo::new(StorageLocation::AppendVec(0, offset), 0, 0);
assert!(info.offset() == offset);
}
}
#[test]
#[should_panic(expected = "illegal offset")]
fn test_alignment() {
let offset = 1; // not aligned
AccountInfo::new(StorageLocation::AppendVec(0, offset), 0, 0);
}
}

View File

@ -22,7 +22,7 @@
use std::{thread::sleep, time::Duration};
use {
crate::{
account_info::{AccountInfo, StorageLocation, StoredSize},
account_info::{AccountInfo, Offset, StorageLocation, StoredSize},
accounts_background_service::{DroppedSlotsSender, SendDroppedBankCallback},
accounts_cache::{AccountsCache, CachedAccount, SlotCache},
accounts_hash::{AccountsHash, CalculateHashIntermediate, HashStats, PreviousPass},
@ -120,7 +120,7 @@ const CACHE_VIRTUAL_WRITE_VERSION: StoredMetaWriteVersion = 0;
// for entries in the cache, so that operations that take a storage entry can maintain
// a common interface when interacting with cached accounts. This version is "virtual" in
// that it doesn't actually map to an entry in an AppendVec.
pub(crate) const CACHE_VIRTUAL_OFFSET: usize = 0;
pub(crate) const CACHE_VIRTUAL_OFFSET: Offset = 0;
const CACHE_VIRTUAL_STORED_SIZE: StoredSize = 0;
pub const ACCOUNTS_DB_CONFIG_FOR_TESTING: AccountsDbConfig = AccountsDbConfig {
@ -13306,7 +13306,7 @@ pub mod tests {
}
let do_test = |test_params: TestParameters| {
let account_info = AccountInfo::new(StorageLocation::AppendVec(42, 123), 234, 0);
let account_info = AccountInfo::new(StorageLocation::AppendVec(42, 128), 234, 0);
let pubkey = solana_sdk::pubkey::new_rand();
let mut key_set = HashSet::default();
key_set.insert(pubkey);

View File

@ -30,14 +30,14 @@ use {
// Data placement should be aligned at the next boundary. Without alignment accessing the memory may
// crash on some architectures.
const ALIGN_BOUNDARY_OFFSET: usize = mem::size_of::<u64>();
pub const ALIGN_BOUNDARY_OFFSET: usize = mem::size_of::<u64>();
macro_rules! u64_align {
($addr: expr) => {
($addr + (ALIGN_BOUNDARY_OFFSET - 1)) & !(ALIGN_BOUNDARY_OFFSET - 1)
};
}
const MAXIMUM_APPEND_VEC_FILE_SIZE: u64 = 16 * 1024 * 1024 * 1024; // 16 GiB
pub const MAXIMUM_APPEND_VEC_FILE_SIZE: u64 = 16 * 1024 * 1024 * 1024; // 16 GiB
pub type StoredMetaWriteVersion = u64;