mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-19 03:04:27 -05:00
This commit is contained in:
committed by
GitHub
parent
c137ed836f
commit
dd0c6d279f
@@ -243,53 +243,8 @@ impl DeferredTrieData {
|
||||
/// In normal operation, the parent always has a cached overlay and this
|
||||
/// function is never called.
|
||||
///
|
||||
/// When the `rayon` feature is enabled, uses parallel collection and merge:
|
||||
/// 1. Collects ancestor data in parallel (each `wait_cloned()` may compute)
|
||||
/// 2. Merges hashed state and trie updates in parallel with each other
|
||||
/// 3. Uses tree reduction within each merge for O(log n) depth
|
||||
#[cfg(feature = "rayon")]
|
||||
fn merge_ancestors_into_overlay(
|
||||
ancestors: &[Self],
|
||||
sorted_hashed_state: &HashedPostStateSorted,
|
||||
sorted_trie_updates: &TrieUpdatesSorted,
|
||||
) -> TrieInputSorted {
|
||||
// Early exit: no ancestors means just wrap current block's data
|
||||
if ancestors.is_empty() {
|
||||
return TrieInputSorted::new(
|
||||
Arc::new(sorted_trie_updates.clone()),
|
||||
Arc::new(sorted_hashed_state.clone()),
|
||||
Default::default(),
|
||||
);
|
||||
}
|
||||
|
||||
// Collect ancestor data, unzipping states and updates into Arc slices
|
||||
let (states, updates): (Vec<_>, Vec<_>) = ancestors
|
||||
.iter()
|
||||
.map(|a| {
|
||||
let data = a.wait_cloned();
|
||||
(data.hashed_state, data.trie_updates)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
// Merge state and nodes in parallel with each other using tree reduction
|
||||
let (state, nodes) = rayon::join(
|
||||
|| {
|
||||
let mut merged = HashedPostStateSorted::merge_parallel(&states);
|
||||
merged.extend_ref_and_sort(sorted_hashed_state);
|
||||
merged
|
||||
},
|
||||
|| {
|
||||
let mut merged = TrieUpdatesSorted::merge_parallel(&updates);
|
||||
merged.extend_ref_and_sort(sorted_trie_updates);
|
||||
merged
|
||||
},
|
||||
);
|
||||
|
||||
TrieInputSorted::new(Arc::new(nodes), Arc::new(state), Default::default())
|
||||
}
|
||||
|
||||
/// Merge all ancestors and current block's data into a single overlay (sequential fallback).
|
||||
#[cfg(not(feature = "rayon"))]
|
||||
/// Iterates ancestors oldest -> newest, then extends with current block's data,
|
||||
/// so later state takes precedence.
|
||||
fn merge_ancestors_into_overlay(
|
||||
ancestors: &[Self],
|
||||
sorted_hashed_state: &HashedPostStateSorted,
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
utils::{extend_sorted_vec, kway_merge_sorted},
|
||||
KeyHasher, MultiProofTargets, Nibbles,
|
||||
};
|
||||
use alloc::{borrow::Cow, sync::Arc, vec::Vec};
|
||||
use alloc::{borrow::Cow, vec::Vec};
|
||||
use alloy_primitives::{
|
||||
keccak256,
|
||||
map::{hash_map, B256Map, HashMap, HashSet},
|
||||
@@ -710,36 +710,6 @@ impl HashedPostStateSorted {
|
||||
self.accounts.clear();
|
||||
self.storages.clear();
|
||||
}
|
||||
|
||||
/// Parallel batch-merge sorted hashed post states. Slice is **oldest to newest**.
|
||||
///
|
||||
/// This is more efficient than sequential `extend_ref` calls when merging many states,
|
||||
/// as it processes all states in parallel with tree reduction using divide-and-conquer.
|
||||
#[cfg(feature = "rayon")]
|
||||
pub fn merge_parallel(states: &[Arc<Self>]) -> Self {
|
||||
fn parallel_merge_tree(states: &[Arc<HashedPostStateSorted>]) -> HashedPostStateSorted {
|
||||
match states.len() {
|
||||
0 => HashedPostStateSorted::default(),
|
||||
1 => states[0].as_ref().clone(),
|
||||
2 => {
|
||||
let mut acc = states[0].as_ref().clone();
|
||||
acc.extend_ref_and_sort(&states[1]);
|
||||
acc
|
||||
}
|
||||
n => {
|
||||
let mid = n / 2;
|
||||
let (mut left, right) = rayon::join(
|
||||
|| parallel_merge_tree(&states[..mid]),
|
||||
|| parallel_merge_tree(&states[mid..]),
|
||||
);
|
||||
left.extend_ref_and_sort(&right);
|
||||
left
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parallel_merge_tree(states)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Self> for HashedPostStateSorted {
|
||||
|
||||
@@ -4,7 +4,6 @@ use crate::{
|
||||
};
|
||||
use alloc::{
|
||||
collections::{btree_map::BTreeMap, btree_set::BTreeSet},
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use alloy_primitives::{
|
||||
@@ -698,36 +697,6 @@ impl TrieUpdatesSorted {
|
||||
|
||||
Self { account_nodes, storage_tries }.into()
|
||||
}
|
||||
|
||||
/// Parallel batch-merge sorted trie updates. Slice is **oldest to newest**.
|
||||
///
|
||||
/// This is more efficient than sequential `extend_ref` calls when merging many updates,
|
||||
/// as it processes all updates in parallel with tree reduction using divide-and-conquer.
|
||||
#[cfg(feature = "rayon")]
|
||||
pub fn merge_parallel(updates: &[Arc<Self>]) -> Self {
|
||||
fn parallel_merge_tree(updates: &[Arc<TrieUpdatesSorted>]) -> TrieUpdatesSorted {
|
||||
match updates.len() {
|
||||
0 => TrieUpdatesSorted::default(),
|
||||
1 => updates[0].as_ref().clone(),
|
||||
2 => {
|
||||
let mut acc = updates[0].as_ref().clone();
|
||||
acc.extend_ref_and_sort(&updates[1]);
|
||||
acc
|
||||
}
|
||||
n => {
|
||||
let mid = n / 2;
|
||||
let (mut left, right) = rayon::join(
|
||||
|| parallel_merge_tree(&updates[..mid]),
|
||||
|| parallel_merge_tree(&updates[mid..]),
|
||||
);
|
||||
left.extend_ref_and_sort(&right);
|
||||
left
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parallel_merge_tree(updates)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Self> for TrieUpdatesSorted {
|
||||
|
||||
Reference in New Issue
Block a user