1use crate::{
6 BenchmarkResult, IntelligentCacheManager, PerformanceMonitor, UnifiedCache, UnifiedCacheConfig,
7};
8use rand::Rng;
9use std::{sync::Arc, time::Duration};
10use tokio::time::sleep;
11
12#[derive(Debug, Clone)]
14pub struct BenchmarkConfig {
15 pub operations_count: usize,
17 pub worker_count: usize,
19 pub key_space_size: usize,
21 pub value_size: usize,
23 pub read_write_ratio: f64,
25 pub max_duration: Duration,
27}
28
29impl Default for BenchmarkConfig {
30 fn default() -> Self {
31 Self {
32 operations_count: 100_000,
33 worker_count: 4,
34 key_space_size: 10_000,
35 value_size: 1024,
36 read_write_ratio: 0.8, max_duration: Duration::from_secs(60),
38 }
39 }
40}
41
42pub struct CacheBenchmarkSuite {
44 cache: Arc<IntelligentCacheManager<String, Vec<u8>>>,
46 monitor: Arc<PerformanceMonitor>,
48 config: BenchmarkConfig,
50}
51
52impl CacheBenchmarkSuite {
53 pub fn new(cache_config: UnifiedCacheConfig, bench_config: BenchmarkConfig) -> Self {
55 let cache = Arc::new(IntelligentCacheManager::new(cache_config));
56 let monitor = cache.monitor();
57
58 Self {
59 cache,
60 monitor,
61 config: bench_config,
62 }
63 }
64
65 pub async fn run_all_benchmarks(&self) -> Vec<BenchmarkResult> {
67 let mut results = Vec::new();
68
69 results.push(self.benchmark_sequential_operations().await);
71 results.push(self.benchmark_concurrent_operations().await);
72 results.push(self.benchmark_mixed_workload().await);
73
74 results.push(self.benchmark_hit_rate_optimization().await);
76 results.push(self.benchmark_memory_efficiency().await);
77 results.push(self.benchmark_predictive_preheating().await);
78 results.push(self.benchmark_adaptive_tuning().await);
79
80 results.push(self.benchmark_high_contention().await);
82 results.push(self.benchmark_large_dataset().await);
83
84 results
85 }
86
87 pub async fn benchmark_sequential_operations(&self) -> BenchmarkResult {
89 self.monitor
90 .run_benchmark("sequential_operations", || async {
91 let test_data = self.generate_test_data();
92
93 for (key, value) in &test_data {
95 let _ = self.cache.put(key.clone(), value.clone()).await;
96 }
97
98 for (key, _) in &test_data {
100 let _ = self.cache.get(key).await;
101 }
102 })
103 .await
104 }
105
106 pub async fn benchmark_concurrent_operations(&self) -> BenchmarkResult {
108 self.monitor
109 .run_benchmark("concurrent_operations", || async {
110 let test_data = Arc::new(self.generate_test_data());
111 let cache = Arc::clone(&self.cache);
112
113 let mut handles = Vec::new();
114
115 for worker_id in 0..self.config.worker_count {
116 let cache = Arc::clone(&cache);
117 let test_data = Arc::clone(&test_data);
118 let ops_per_worker = self.config.operations_count / self.config.worker_count;
119
120 let handle = tokio::spawn(async move {
121 for i in 0..ops_per_worker {
122 let key_index = (worker_id * ops_per_worker + i) % test_data.len();
123 let (key, value) = &test_data[key_index];
124
125 if i % 5 == 0 {
126 let _ = cache.put(key.clone(), value.clone()).await;
128 } else {
129 let _ = cache.get(key).await;
131 }
132 }
133 });
134
135 handles.push(handle);
136 }
137
138 for handle in handles {
140 let _ = handle.await;
141 }
142 })
143 .await
144 }
145
146 pub async fn benchmark_mixed_workload(&self) -> BenchmarkResult {
148 self.monitor
149 .run_benchmark("mixed_workload", || async {
150 let test_data = self.generate_test_data();
151
152 for (i, (key, value)) in test_data.iter().enumerate() {
153 let operation_ratio = i as f64 / test_data.len() as f64;
154
155 if operation_ratio < self.config.read_write_ratio {
156 let _ = self.cache.get(key).await;
158 } else {
159 let _ = self.cache.put(key.clone(), value.clone()).await;
161 }
162 }
163 })
164 .await
165 }
166
167 pub async fn benchmark_hit_rate_optimization(&self) -> BenchmarkResult {
169 self.monitor
170 .run_benchmark("hit_rate_optimization", || async {
171 let test_data = self.generate_test_data();
172
173 let hot_data_size = test_data.len() / 4; for (key, value) in test_data.iter().take(hot_data_size) {
176 let _ = self.cache.put(key.clone(), value.clone()).await;
177 }
178
179 for _ in 0..self.config.operations_count {
181 let mut rng = rand::rng();
182 let key_index = if rng.random::<f64>() < 0.8 {
183 rng.random_range(0..hot_data_size)
185 } else {
186 hot_data_size + rng.random_range(0..(test_data.len() - hot_data_size))
188 };
189
190 let (key, value) = &test_data[key_index];
191
192 if self.cache.get(key).await.is_none() {
193 let _ = self.cache.put(key.clone(), value.clone()).await;
195 }
196 }
197 })
198 .await
199 }
200
201 pub async fn benchmark_memory_efficiency(&self) -> BenchmarkResult {
203 self.monitor
204 .run_benchmark("memory_efficiency", || async {
205 let large_value = vec![0u8; self.config.value_size * 10]; for i in 0..self.config.key_space_size {
209 let key = format!("large_key_{}", i);
210 let _ = self.cache.put(key, large_value.clone()).await;
211 }
212
213 for i in 0..self.config.key_space_size / 2 {
215 let key = format!("new_key_{}", i);
216 let _ = self.cache.put(key, large_value.clone()).await;
217 }
218 })
219 .await
220 }
221
222 pub async fn benchmark_predictive_preheating(&self) -> BenchmarkResult {
224 self.monitor
225 .run_benchmark("predictive_preheating", || async {
226 let test_data = self.generate_test_data();
227
228 for cycle in 0..10 {
230 for (i, (key, value)) in test_data.iter().enumerate() {
231 if i % 10 == cycle % 10 {
232 if self.cache.get(key).await.is_none() {
234 let _ = self.cache.put(key.clone(), value.clone()).await;
235 }
236 }
237 }
238
239 sleep(Duration::from_millis(100)).await;
241 }
242
243 for (i, (key, _)) in test_data.iter().enumerate() {
245 if i % 10 == 0 {
246 let _ = self.cache.get(key).await;
248 }
249 }
250 })
251 .await
252 }
253
254 pub async fn benchmark_adaptive_tuning(&self) -> BenchmarkResult {
256 self.monitor
257 .run_benchmark("adaptive_tuning", || async {
258 let test_data = self.generate_test_data();
259
260 for _ in 0..1000 {
262 let mut rng = rand::rng();
263 let key_index = rng.random_range(0..test_data.len());
264 let (key, value) = &test_data[key_index];
265
266 if self.cache.get(key).await.is_none() {
267 let _ = self.cache.put(key.clone(), value.clone()).await;
268 }
269 }
270
271 sleep(Duration::from_secs(1)).await;
273
274 let hot_keys: Vec<_> = test_data.iter().take(100).collect();
276 for _ in 0..1000 {
277 let mut rng = rand::rng();
278 let (key, value) = hot_keys[rng.random_range(0..hot_keys.len())];
279
280 if self.cache.get(key).await.is_none() {
281 let _ = self.cache.put(key.clone(), value.clone()).await;
282 }
283 }
284 })
285 .await
286 }
287
288 pub async fn benchmark_high_contention(&self) -> BenchmarkResult {
290 self.monitor
291 .run_benchmark("high_contention", || async {
292 let hot_keys = vec!["hot_key_1", "hot_key_2", "hot_key_3"];
293 let test_value = vec![0u8; self.config.value_size];
294
295 let cache = Arc::clone(&self.cache);
296 let mut handles = Vec::new();
297
298 for _ in 0..self.config.worker_count * 2 {
300 let cache = Arc::clone(&cache);
301 let hot_keys = hot_keys.clone();
302 let test_value = test_value.clone();
303
304 let handle = tokio::spawn(async move {
305 for _ in 0..1000 {
306 let key_index = {
307 let mut rng = rand::rng();
308 rng.random_range(0..hot_keys.len())
309 };
310 let key = &hot_keys[key_index];
311
312 let is_read = {
313 let mut rng = rand::rng();
314 rng.random::<bool>()
315 };
316
317 if is_read {
318 let _ = cache.get(&key.to_string()).await;
319 } else {
320 let _ = cache.put(key.to_string(), test_value.clone()).await;
321 }
322 }
323 });
324
325 handles.push(handle);
326 }
327
328 for handle in handles {
329 let _ = handle.await;
330 }
331 })
332 .await
333 }
334
335 pub async fn benchmark_large_dataset(&self) -> BenchmarkResult {
337 self.monitor
338 .run_benchmark("large_dataset", || async {
339 let large_dataset_size = self.config.key_space_size * 10;
340 let test_value = vec![0u8; self.config.value_size];
341
342 for i in 0..large_dataset_size {
344 let key = format!("large_dataset_key_{}", i);
345 let _ = self.cache.put(key, test_value.clone()).await;
346
347 if i % 1000 == 0 {
349 for j in 0..100 {
350 let read_key = format!("large_dataset_key_{}", j);
351 let _ = self.cache.get(&read_key).await;
352 }
353 }
354 }
355 })
356 .await
357 }
358
359 fn generate_test_data(&self) -> Vec<(String, Vec<u8>)> {
361 (0..self.config.key_space_size)
362 .map(|i| {
363 let key = format!("test_key_{}", i);
364 let value = vec![i as u8; self.config.value_size];
365 (key, value)
366 })
367 .collect()
368 }
369
370 pub async fn get_cache_stats(&self) -> crate::UnifiedCacheStats {
372 self.cache.get_stats().await
373 }
374
375 pub async fn get_performance_metrics(&self) -> crate::PerformanceMetrics {
377 self.monitor.get_performance_metrics().await
378 }
379}
380
381pub async fn run_comprehensive_benchmarks() -> Vec<BenchmarkResult> {
383 println!("š Starting Intelligent Cache Comprehensive Benchmarks");
384
385 let configs = vec![
387 ("High Performance", UnifiedCacheConfig::high_performance()),
388 ("Low Memory", UnifiedCacheConfig::low_memory()),
389 ("Default", UnifiedCacheConfig::default()),
390 ];
391
392 let mut all_results = Vec::new();
393
394 for (config_name, cache_config) in configs {
395 println!("\nš Testing configuration: {}", config_name);
396
397 let bench_config = BenchmarkConfig::default();
398 let suite = CacheBenchmarkSuite::new(cache_config, bench_config);
399
400 let results = suite.run_all_benchmarks().await;
401
402 println!(
403 "ā
Completed {} benchmarks for {}",
404 results.len(),
405 config_name
406 );
407 for result in &results {
408 println!(
409 " {} - {:.2} ops/sec, {:.2}μs avg latency",
410 result.name, result.ops_per_second, result.avg_latency_us
411 );
412 }
413
414 all_results.extend(results);
415 }
416
417 println!("\nšÆ Benchmark Summary:");
418 println!("Total benchmarks completed: {}", all_results.len());
419
420 all_results
421}