AcctInfo: store offset in AccountInfo as u32 (#21895)
This commit is contained in:
parent
e5be96d8bf
commit
46e5350d8c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue