Skip to content

Commit

Permalink
reworks blockstore ColumnIndexDeprecation trait
Browse files Browse the repository at this point in the history
Similar to
    #4416
in order to add more type-safety and avoid unnecessary heap allocations:
https://github.com/anza-xyz/agave/blob/8a0c9b461/ledger/src/blockstore_db.rs#L932
https://github.com/anza-xyz/agave/blob/8a0c9b461/ledger/src/blockstore_db.rs#L1005
https://github.com/anza-xyz/agave/blob/8a0c9b461/ledger/src/blockstore_db.rs#L1075

the commit removes
    const DEPRECATED_INDEX_LEN: usize;
from ColumnIndexDeprecation trait and instead adds:
    type DeprecatedKey: AsRef<[u8]>;
  • Loading branch information
behzadnouri committed Jan 14, 2025
1 parent 8a0c9b4 commit 6f8b9c9
Showing 1 changed file with 42 additions and 30 deletions.
72 changes: 42 additions & 30 deletions ledger/src/blockstore_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,11 +857,11 @@ pub enum IndexError {

/// Helper trait to transition primary indexes out from the columns that are using them.
pub trait ColumnIndexDeprecation: Column {
const DEPRECATED_INDEX_LEN: usize;
const CURRENT_INDEX_LEN: usize;
type DeprecatedIndex;
type DeprecatedKey: AsRef<[u8]>;

fn deprecated_key(index: Self::DeprecatedIndex) -> Vec<u8>;
fn deprecated_key(index: Self::DeprecatedIndex) -> Self::DeprecatedKey;
fn try_deprecated_index(key: &[u8]) -> std::result::Result<Self::DeprecatedIndex, IndexError>;

fn try_current_index(key: &[u8]) -> std::result::Result<Self::Index, IndexError>;
Expand All @@ -881,15 +881,27 @@ pub trait ColumnIndexDeprecation: Column {
}
}

macro_rules! concat_key_bytes {
($($range:expr => $bytes:expr),* $(,)?) => {{
let mut key = [0u8; std::mem::size_of::<Self::Key>()];
macro_rules! concat_bytes {
($key:ty, $($range:expr => $bytes:expr),* $(,)?) => {{
let mut key = [0u8; std::mem::size_of::<$key>()];
debug_assert_eq!(0 $(+$bytes.len())*, key.len());
$(key[$range].copy_from_slice($bytes);)*
key
}};
}

macro_rules! concat_key_bytes {
($($range:expr => $bytes:expr),* $(,)?) => {
concat_bytes!(Self::Key, $($range => $bytes),*)
};
}

macro_rules! concat_deprecated_key_bytes {
($($range:expr => $bytes:expr),* $(,)?) => {
concat_bytes!(Self::DeprecatedKey, $($range => $bytes),*)
};
}

impl Column for columns::TransactionStatus {
type Index = (Signature, Slot);
type Key = [u8; SIGNATURE_BYTES + std::mem::size_of::<Slot>()];
Expand Down Expand Up @@ -924,20 +936,20 @@ impl ProtobufColumn for columns::TransactionStatus {
}

impl ColumnIndexDeprecation for columns::TransactionStatus {
const DEPRECATED_INDEX_LEN: usize = 80;
const CURRENT_INDEX_LEN: usize = 72;
type DeprecatedIndex = (u64, Signature, Slot);
type DeprecatedKey = [u8; 80];

fn deprecated_key((index, signature, slot): Self::DeprecatedIndex) -> Vec<u8> {
let mut key = vec![0; Self::DEPRECATED_INDEX_LEN];
BigEndian::write_u64(&mut key[0..8], index);
key[8..72].copy_from_slice(&signature.as_ref()[0..64]);
BigEndian::write_u64(&mut key[72..80], slot);
key
fn deprecated_key((index, signature, slot): Self::DeprecatedIndex) -> Self::DeprecatedKey {
concat_deprecated_key_bytes!(
..8 => &index.to_be_bytes(),
8..72 => signature.as_ref(),
72.. => &slot.to_be_bytes(),
)
}

fn try_deprecated_index(key: &[u8]) -> std::result::Result<Self::DeprecatedIndex, IndexError> {
if key.len() != Self::DEPRECATED_INDEX_LEN {
if key.len() != std::mem::size_of::<Self::DeprecatedKey>() {
return Err(IndexError::UnpackError);
}
let primary_index = BigEndian::read_u64(&key[0..8]);
Expand Down Expand Up @@ -997,21 +1009,23 @@ impl ColumnName for columns::AddressSignatures {
}

impl ColumnIndexDeprecation for columns::AddressSignatures {
const DEPRECATED_INDEX_LEN: usize = 112;
const CURRENT_INDEX_LEN: usize = 108;
type DeprecatedIndex = (u64, Pubkey, Slot, Signature);

fn deprecated_key((primary_index, pubkey, slot, signature): Self::DeprecatedIndex) -> Vec<u8> {
let mut key = vec![0; Self::DEPRECATED_INDEX_LEN];
BigEndian::write_u64(&mut key[0..8], primary_index);
key[8..40].clone_from_slice(&pubkey.as_ref()[0..32]);
BigEndian::write_u64(&mut key[40..48], slot);
key[48..112].clone_from_slice(&signature.as_ref()[0..64]);
key
type DeprecatedKey = [u8; 112];

fn deprecated_key(
(primary_index, pubkey, slot, signature): Self::DeprecatedIndex,
) -> Self::DeprecatedKey {
concat_deprecated_key_bytes!(
..8 => &primary_index.to_be_bytes(),
8..40 => pubkey.as_ref(),
40..48 => &slot.to_be_bytes(),
48..112 => signature.as_ref(),
)
}

fn try_deprecated_index(key: &[u8]) -> std::result::Result<Self::DeprecatedIndex, IndexError> {
if key.len() != Self::DEPRECATED_INDEX_LEN {
if key.len() != std::mem::size_of::<Self::DeprecatedKey>() {
return Err(IndexError::UnpackError);
}
let primary_index = BigEndian::read_u64(&key[0..8]);
Expand Down Expand Up @@ -1067,14 +1081,12 @@ impl ColumnName for columns::TransactionMemos {
}

impl ColumnIndexDeprecation for columns::TransactionMemos {
const DEPRECATED_INDEX_LEN: usize = 64;
const CURRENT_INDEX_LEN: usize = 72;
type DeprecatedIndex = Signature;
type DeprecatedKey = [u8; 64];

fn deprecated_key(signature: Self::DeprecatedIndex) -> Vec<u8> {
let mut key = vec![0; Self::DEPRECATED_INDEX_LEN];
key[0..64].copy_from_slice(&signature.as_ref()[0..64]);
key
fn deprecated_key(signature: Self::DeprecatedIndex) -> Self::DeprecatedKey {
<[u8; SIGNATURE_BYTES]>::from(signature)
}

fn try_deprecated_index(key: &[u8]) -> std::result::Result<Self::DeprecatedIndex, IndexError> {
Expand Down Expand Up @@ -1885,13 +1897,13 @@ where
&self,
iterator_mode: IteratorMode<C::DeprecatedIndex>,
) -> Result<impl Iterator<Item = (C::DeprecatedIndex, Box<[u8]>)> + '_> {
let start_key;
let start_key: <C as ColumnIndexDeprecation>::DeprecatedKey;
let iterator_mode = match iterator_mode {
IteratorMode::Start => RocksIteratorMode::Start,
IteratorMode::End => RocksIteratorMode::End,
IteratorMode::From(start_from, direction) => {
start_key = C::deprecated_key(start_from);
RocksIteratorMode::From(&start_key, direction)
RocksIteratorMode::From(start_key.as_ref(), direction)
}
};

Expand Down

0 comments on commit 6f8b9c9

Please sign in to comment.