rustywallet_batch/
config.rs1use crate::error::BatchError;
6
7#[derive(Debug, Clone)]
28pub struct BatchConfig {
29 pub batch_size: usize,
31
32 pub thread_count: Option<usize>,
35
36 pub use_simd: bool,
38
39 pub chunk_size: usize,
41
42 pub memory_limit: Option<usize>,
44
45 pub parallel: bool,
47
48 pub deterministic_order: bool,
50}
51
52impl Default for BatchConfig {
53 fn default() -> Self {
54 Self {
55 batch_size: 10_000,
56 thread_count: None,
57 use_simd: true,
58 chunk_size: 1_000,
59 memory_limit: None,
60 parallel: false,
61 deterministic_order: false,
62 }
63 }
64}
65
66impl BatchConfig {
67 pub fn new() -> Self {
69 Self::default()
70 }
71
72 pub fn fast() -> Self {
76 Self {
77 batch_size: 100_000,
78 thread_count: None, use_simd: true,
80 chunk_size: 10_000,
81 memory_limit: None,
82 parallel: true,
83 deterministic_order: false,
84 }
85 }
86
87 pub fn balanced() -> Self {
91 Self {
92 batch_size: 50_000,
93 thread_count: None,
94 use_simd: true,
95 chunk_size: 5_000,
96 memory_limit: Some(100 * 1024 * 1024), parallel: true,
98 deterministic_order: false,
99 }
100 }
101
102 pub fn memory_efficient() -> Self {
106 Self {
107 batch_size: 10_000,
108 thread_count: Some(2),
109 use_simd: true,
110 chunk_size: 100,
111 memory_limit: Some(10 * 1024 * 1024), parallel: true,
113 deterministic_order: false,
114 }
115 }
116
117 pub fn with_batch_size(mut self, size: usize) -> Self {
119 self.batch_size = size;
120 self
121 }
122
123 pub fn with_thread_count(mut self, count: Option<usize>) -> Self {
125 self.thread_count = count;
126 self
127 }
128
129 pub fn with_simd(mut self, enabled: bool) -> Self {
131 self.use_simd = enabled;
132 self
133 }
134
135 pub fn with_chunk_size(mut self, size: usize) -> Self {
137 self.chunk_size = size;
138 self
139 }
140
141 pub fn with_memory_limit(mut self, limit: Option<usize>) -> Self {
143 self.memory_limit = limit;
144 self
145 }
146
147 pub fn with_parallel(mut self, enabled: bool) -> Self {
149 self.parallel = enabled;
150 self
151 }
152
153 pub fn with_deterministic_order(mut self, enabled: bool) -> Self {
155 self.deterministic_order = enabled;
156 self
157 }
158
159 pub fn validate(&self) -> Result<(), BatchError> {
163 if self.batch_size == 0 {
164 return Err(BatchError::invalid_config("batch_size must be greater than 0"));
165 }
166
167 if self.chunk_size == 0 {
168 return Err(BatchError::invalid_config("chunk_size must be greater than 0"));
169 }
170
171 if let Some(count) = self.thread_count {
172 if count == 0 {
173 return Err(BatchError::invalid_config("thread_count must be greater than 0"));
174 }
175 }
176
177 if let Some(limit) = self.memory_limit {
178 if limit == 0 {
179 return Err(BatchError::invalid_config("memory_limit must be greater than 0"));
180 }
181 }
182
183 Ok(())
184 }
185
186 pub fn effective_thread_count(&self) -> usize {
190 self.thread_count.unwrap_or_else(|| {
191 rayon::current_num_threads()
192 })
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use super::*;
199
200 #[test]
201 fn test_default_config() {
202 let config = BatchConfig::default();
203 assert_eq!(config.batch_size, 10_000);
204 assert!(config.thread_count.is_none());
205 assert!(config.use_simd);
206 assert_eq!(config.chunk_size, 1_000);
207 assert!(config.memory_limit.is_none());
208 assert!(!config.parallel);
209 assert!(!config.deterministic_order);
210 }
211
212 #[test]
213 fn test_fast_preset() {
214 let config = BatchConfig::fast();
215 assert_eq!(config.batch_size, 100_000);
216 assert!(config.parallel);
217 assert_eq!(config.chunk_size, 10_000);
218 }
219
220 #[test]
221 fn test_balanced_preset() {
222 let config = BatchConfig::balanced();
223 assert_eq!(config.batch_size, 50_000);
224 assert!(config.parallel);
225 assert!(config.memory_limit.is_some());
226 }
227
228 #[test]
229 fn test_memory_efficient_preset() {
230 let config = BatchConfig::memory_efficient();
231 assert_eq!(config.chunk_size, 100);
232 assert!(config.memory_limit.is_some());
233 }
234
235 #[test]
236 fn test_builder_pattern() {
237 let config = BatchConfig::new()
238 .with_batch_size(50_000)
239 .with_thread_count(Some(4))
240 .with_chunk_size(500)
241 .with_parallel(true);
242
243 assert_eq!(config.batch_size, 50_000);
244 assert_eq!(config.thread_count, Some(4));
245 assert_eq!(config.chunk_size, 500);
246 assert!(config.parallel);
247 }
248
249 #[test]
250 fn test_validation_valid() {
251 let config = BatchConfig::default();
252 assert!(config.validate().is_ok());
253 }
254
255 #[test]
256 fn test_validation_invalid_batch_size() {
257 let config = BatchConfig::default().with_batch_size(0);
258 assert!(config.validate().is_err());
259 }
260
261 #[test]
262 fn test_validation_invalid_chunk_size() {
263 let config = BatchConfig::default().with_chunk_size(0);
264 assert!(config.validate().is_err());
265 }
266
267 #[test]
268 fn test_validation_invalid_thread_count() {
269 let config = BatchConfig::default().with_thread_count(Some(0));
270 assert!(config.validate().is_err());
271 }
272}