feat: generic static file masks (#12785)

This commit is contained in:
Arsenii Kulikov
2024-11-22 19:52:51 +04:00
committed by GitHub
parent 362e2ed0af
commit 7f95f1bf07
9 changed files with 94 additions and 78 deletions

View File

@ -48,7 +48,6 @@ page_size = { version = "0.6.0", optional = true }
thiserror.workspace = true
tempfile = { workspace = true, optional = true }
derive_more.workspace = true
paste.workspace = true
rustc-hash = { workspace = true, optional = true }
sysinfo = { version = "0.31", default-features = false, features = ["system"] }
parking_lot = { workspace = true, optional = true }

View File

@ -1,38 +1,5 @@
use reth_db_api::table::Decompress;
/// Generic Mask helper struct for selecting specific column values to read and decompress.
///
/// #### Explanation:
///
/// A `NippyJar` static file row can contain multiple column values. To specify the column values
/// to be read, a mask is utilized.
///
/// For example, a static file with three columns, if the first and last columns are queried, the
/// mask `0b101` would be passed. To select only the second column, the mask `0b010` would be used.
///
/// Since each static file has its own column distribution, different wrapper types are necessary.
/// For instance, `B256` might be the third column in the `Header` segment, while being the second
/// column in another segment. Hence, `Mask<B256>` would only be applicable to one of these
/// scenarios.
///
/// Alongside, the column selector traits (eg. [`ColumnSelectorOne`]) this provides a structured way
/// to tie the types to be decoded to the mask necessary to query them.
#[derive(Debug)]
pub struct Mask<FIRST, SECOND = (), THIRD = ()>(std::marker::PhantomData<(FIRST, SECOND, THIRD)>);
macro_rules! add_segments {
($($segment:tt),+) => {
paste::paste! {
$(
#[doc = concat!("Mask for ", stringify!($segment), " static file segment. See [`Mask`] for more.")]
#[derive(Debug)]
pub struct [<$segment Mask>]<FIRST, SECOND = (), THIRD = ()>(Mask<FIRST, SECOND, THIRD>);
)+
}
};
}
add_segments!(Header, Receipt, Transaction);
/// Trait for specifying a mask to select one column value.
pub trait ColumnSelectorOne {
/// First desired column value
@ -66,21 +33,45 @@ pub trait ColumnSelectorThree {
#[macro_export]
/// Add mask to select `N` column values from a specific static file segment row.
macro_rules! add_static_file_mask {
($mask_struct:tt, $type1:ty, $mask:expr) => {
impl ColumnSelectorOne for $mask_struct<$type1> {
($(#[$attr:meta])* $mask_struct:ident $(<$generic:ident>)?, $type1:ty, $mask:expr) => {
$(#[$attr])*
#[derive(Debug)]
pub struct $mask_struct$(<$generic>)?$((std::marker::PhantomData<$generic>))?;
impl$(<$generic>)? ColumnSelectorOne for $mask_struct$(<$generic>)?
where
$type1: Send + Sync + std::fmt::Debug + reth_db_api::table::Decompress,
{
type FIRST = $type1;
const MASK: usize = $mask;
}
};
($mask_struct:tt, $type1:ty, $type2:ty, $mask:expr) => {
impl ColumnSelectorTwo for $mask_struct<$type1, $type2> {
($(#[$attr:meta])* $mask_struct:ident $(<$generic:ident>)?, $type1:ty, $type2:ty, $mask:expr) => {
$(#[$attr])*
#[derive(Debug)]
pub struct $mask_struct$(<$generic>)?$((std::marker::PhantomData<$generic>))?;
impl$(<$generic>)? ColumnSelectorTwo for $mask_struct$(<$generic>)?
where
$type1: Send + Sync + std::fmt::Debug + reth_db_api::table::Decompress,
$type2: Send + Sync + std::fmt::Debug + reth_db_api::table::Decompress,
{
type FIRST = $type1;
type SECOND = $type2;
const MASK: usize = $mask;
}
};
($mask_struct:tt, $type1:ty, $type2:ty, $type3:ty, $mask:expr) => {
impl ColumnSelectorThree for $mask_struct<$type1, $type2, $type3> {
($(#[$attr:meta])* $mask_struct:ident $(<$generic:ident>)?, $type1:ty, $type2:ty, $type3:ty, $mask:expr) => {
$(#[$attr])*
#[derive(Debug)]
pub struct $mask_struct$(<$generic>)?$((std::marker::PhantomData<$generic>))?;
impl$(<$generic>)? ColumnSelectorThree for $mask_struct$(<$generic>)?
where
$type1: Send + Sync + std::fmt::Debug + reth_db_api::table::Decompress,
$type2: Send + Sync + std::fmt::Debug + reth_db_api::table::Decompress,
$type3: Send + Sync + std::fmt::Debug + reth_db_api::table::Decompress,
{
type FIRST = $type1;
type SECOND = $type2;
type THIRD = $type3;

View File

@ -1,23 +1,44 @@
use super::{ReceiptMask, TransactionMask};
use crate::{
add_static_file_mask,
static_file::mask::{ColumnSelectorOne, ColumnSelectorTwo, HeaderMask},
HeaderTerminalDifficulties, RawValue, Receipts, Transactions,
static_file::mask::{ColumnSelectorOne, ColumnSelectorTwo},
HeaderTerminalDifficulties,
};
use alloy_consensus::Header;
use alloy_primitives::BlockHash;
use reth_db_api::table::Table;
// HEADER MASKS
add_static_file_mask!(HeaderMask, Header, 0b001);
add_static_file_mask!(HeaderMask, <HeaderTerminalDifficulties as Table>::Value, 0b010);
add_static_file_mask!(HeaderMask, BlockHash, 0b100);
add_static_file_mask!(HeaderMask, Header, BlockHash, 0b101);
add_static_file_mask!(HeaderMask, <HeaderTerminalDifficulties as Table>::Value, BlockHash, 0b110);
add_static_file_mask! {
#[doc = "Mask for selecting a single header from Headers static file segment"]
HeaderMask<H>, H, 0b001
}
add_static_file_mask! {
#[doc = "Mask for selecting a total difficulty value from Headers static file segment"]
TotalDifficultyMask, <HeaderTerminalDifficulties as Table>::Value, 0b010
}
add_static_file_mask! {
#[doc = "Mask for selecting a block hash value from Headers static file segment"]
BlockHashMask, BlockHash, 0b100
}
add_static_file_mask! {
#[doc = "Mask for selecting a header along with block hash from Headers static file segment"]
HeaderWithHashMask<H>, H, BlockHash, 0b101
}
add_static_file_mask! {
#[doc = "Mask for selecting a total difficulty along with block hash from Headers static file segment"]
TDWithHashMask,
<HeaderTerminalDifficulties as Table>::Value,
BlockHash,
0b110
}
// RECEIPT MASKS
add_static_file_mask!(ReceiptMask, <Receipts as Table>::Value, 0b1);
add_static_file_mask! {
#[doc = "Mask for selecting a single receipt from Receipts static file segment"]
ReceiptMask<R>, R, 0b1
}
// TRANSACTION MASKS
add_static_file_mask!(TransactionMask, <Transactions as Table>::Value, 0b1);
add_static_file_mask!(TransactionMask, RawValue<<Transactions as Table>::Value>, 0b1);
add_static_file_mask! {
#[doc = "Mask for selecting a single transaction from Transactions static file segment"]
TransactionMask<T>, T, 0b1
}

View File

@ -17,6 +17,7 @@ use reth_primitives::{
};
mod masks;
pub use masks::*;
/// Alias type for a map of [`StaticFileSegment`] and sorted lists of existing static file ranges.
type SortedStaticFiles =