reth_trie_parallel/
targets_v2.rs1use alloy_primitives::{map::B256Map, B256};
4use reth_trie::proof_v2;
5
6#[derive(Debug, Default)]
9pub struct MultiProofTargetsV2 {
10 pub account_targets: Vec<proof_v2::Target>,
12 pub storage_targets: B256Map<Vec<proof_v2::Target>>,
14}
15
16impl MultiProofTargetsV2 {
17 pub fn is_empty(&self) -> bool {
19 self.account_targets.is_empty() && self.storage_targets.is_empty()
20 }
21
22 pub fn chunking_length(&self) -> usize {
24 self.account_targets.len() +
25 self.storage_targets.values().map(|slots| slots.len()).sum::<usize>()
26 }
27
28 pub fn chunks(self, chunk_size: usize) -> impl Iterator<Item = Self> {
30 ChunkedMultiProofTargetsV2::new(self, chunk_size)
31 }
32}
33
34#[derive(Debug)]
42pub struct ChunkedMultiProofTargetsV2 {
43 account_targets: std::vec::IntoIter<proof_v2::Target>,
45 storage_targets: B256Map<Vec<proof_v2::Target>>,
47 current_account_storage: Option<(B256, std::vec::IntoIter<proof_v2::Target>)>,
49 size: usize,
51}
52
53impl ChunkedMultiProofTargetsV2 {
54 pub fn new(targets: MultiProofTargetsV2, size: usize) -> Self {
56 Self {
57 account_targets: targets.account_targets.into_iter(),
58 storage_targets: targets.storage_targets,
59 current_account_storage: None,
60 size,
61 }
62 }
63}
64
65impl Iterator for ChunkedMultiProofTargetsV2 {
66 type Item = MultiProofTargetsV2;
67
68 fn next(&mut self) -> Option<Self::Item> {
69 let mut chunk = MultiProofTargetsV2::default();
70 let mut count = 0;
71
72 if let Some((account_addr, ref mut storage_iter)) = self.current_account_storage {
74 let remaining_capacity = self.size - count;
75 let slots: Vec<_> = storage_iter.by_ref().take(remaining_capacity).collect();
76
77 count += slots.len();
78 chunk.storage_targets.insert(account_addr, slots);
79
80 if storage_iter.len() == 0 {
82 self.current_account_storage = None;
83 }
84 }
85
86 while count < self.size {
88 let Some(account_target) = self.account_targets.next() else {
89 break;
90 };
91
92 chunk.account_targets.push(account_target);
94 count += 1;
95
96 let account_addr = account_target.key();
98 if let Some(storage_slots) = self.storage_targets.remove(&account_addr) {
99 let remaining_capacity = self.size - count;
100
101 if storage_slots.len() <= remaining_capacity {
102 count += storage_slots.len();
104 chunk.storage_targets.insert(account_addr, storage_slots);
105 } else {
106 let mut storage_iter = storage_slots.into_iter();
108 let slots_in_chunk: Vec<_> =
109 storage_iter.by_ref().take(remaining_capacity).collect();
110 count += slots_in_chunk.len();
111
112 chunk.storage_targets.insert(account_addr, slots_in_chunk);
113
114 self.current_account_storage = Some((account_addr, storage_iter));
116 break;
117 }
118 }
119 }
120
121 while let Some((account_addr, storage_slots)) = self.storage_targets.iter_mut().next() &&
123 count < self.size
124 {
125 let account_addr = *account_addr;
126 let storage_slots = std::mem::take(storage_slots);
127 let remaining_capacity = self.size - count;
128
129 self.storage_targets.remove(&account_addr);
132
133 if storage_slots.len() <= remaining_capacity {
134 count += storage_slots.len();
136 chunk.storage_targets.insert(account_addr, storage_slots);
137 } else {
138 let mut storage_iter = storage_slots.into_iter();
140 let slots_in_chunk: Vec<_> =
141 storage_iter.by_ref().take(remaining_capacity).collect();
142
143 chunk.storage_targets.insert(account_addr, slots_in_chunk);
144
145 if storage_iter.len() > 0 {
147 self.current_account_storage = Some((account_addr, storage_iter));
148 }
149 break;
150 }
151 }
152
153 if chunk.account_targets.is_empty() && chunk.storage_targets.is_empty() {
154 None
155 } else {
156 Some(chunk)
157 }
158 }
159}