perf(trie): add clone_into_sorted for TrieUpdates and StorageTrieUpdates (#20784)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Matthias Seitz
2026-01-06 16:11:27 +01:00
committed by GitHub
parent 63842264f3
commit 485eb2e8d5
2 changed files with 48 additions and 1 deletions

View File

@@ -156,7 +156,7 @@ impl DeferredTrieData {
) -> ComputedTrieData {
// Sort the current block's hashed state and trie updates
let sorted_hashed_state = Arc::new(hashed_state.clone_into_sorted());
let sorted_trie_updates = Arc::new(trie_updates.clone().into_sorted());
let sorted_trie_updates = Arc::new(trie_updates.clone_into_sorted());
// Merge trie data from ancestors (oldest -> newest so later state takes precedence)
let mut overlay = TrieInputSorted::default();

View File

@@ -167,6 +167,32 @@ impl TrieUpdates {
TrieUpdatesSorted { account_nodes, storage_tries }
}
/// Creates a sorted copy without consuming self.
/// More efficient than `.clone().into_sorted()` as it avoids cloning `HashMap` metadata.
pub fn clone_into_sorted(&self) -> TrieUpdatesSorted {
let mut account_nodes = self
.account_nodes
.iter()
.map(|(path, node)| (*path, Some(node.clone())))
.collect::<Vec<_>>();
// Add removed nodes that aren't already updated (updated nodes take precedence)
account_nodes.extend(
self.removed_nodes
.iter()
.filter(|path| !self.account_nodes.contains_key(*path))
.map(|path| (*path, None)),
);
account_nodes.sort_unstable_by(|a, b| a.0.cmp(&b.0));
let storage_tries = self
.storage_tries
.iter()
.map(|(&hashed_address, updates)| (hashed_address, updates.clone_into_sorted()))
.collect();
TrieUpdatesSorted { account_nodes, storage_tries }
}
/// Converts trie updates into [`TrieUpdatesSortedRef`].
pub fn into_sorted_ref<'a>(&'a self) -> TrieUpdatesSortedRef<'a> {
let mut account_nodes = self.account_nodes.iter().collect::<Vec<_>>();
@@ -340,6 +366,27 @@ impl StorageTrieUpdates {
StorageTrieUpdatesSorted { is_deleted: self.is_deleted, storage_nodes }
}
/// Creates a sorted copy without consuming self.
/// More efficient than `.clone().into_sorted()` as it avoids cloning `HashMap` metadata.
pub fn clone_into_sorted(&self) -> StorageTrieUpdatesSorted {
let mut storage_nodes = self
.storage_nodes
.iter()
.map(|(path, node)| (*path, Some(node.clone())))
.collect::<Vec<_>>();
// Add removed nodes that aren't already updated (updated nodes take precedence)
storage_nodes.extend(
self.removed_nodes
.iter()
.filter(|path| !self.storage_nodes.contains_key(*path))
.map(|path| (*path, None)),
);
storage_nodes.sort_unstable_by(|a, b| a.0.cmp(&b.0));
StorageTrieUpdatesSorted { is_deleted: self.is_deleted, storage_nodes }
}
/// Convert storage trie updates into [`StorageTrieUpdatesSortedRef`].
pub fn into_sorted_ref(&self) -> StorageTrieUpdatesSortedRef<'_> {
StorageTrieUpdatesSortedRef {