131 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // benches/common/data_generator.rs
 | |
| use rand::{Rng, SeedableRng};
 | |
| use rand::rngs::StdRng;
 | |
| 
 | |
| /// Deterministic data generator for benchmarks
 | |
| pub struct DataGenerator {
 | |
|     rng: StdRng,
 | |
| }
 | |
| 
 | |
| impl DataGenerator {
 | |
|     /// Create a new data generator with a fixed seed for reproducibility
 | |
|     pub fn new(seed: u64) -> Self {
 | |
|         Self {
 | |
|             rng: StdRng::seed_from_u64(seed),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Generate a single key with the given prefix and ID
 | |
|     pub fn generate_key(&self, prefix: &str, id: usize) -> String {
 | |
|         format!("{}:{:08}", prefix, id)
 | |
|     }
 | |
| 
 | |
|     /// Generate a random string value of the specified size
 | |
|     pub fn generate_value(&mut self, size: usize) -> String {
 | |
|         const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 | |
|         (0..size)
 | |
|             .map(|_| {
 | |
|                 let idx = self.rng.gen_range(0..CHARSET.len());
 | |
|                 CHARSET[idx] as char
 | |
|             })
 | |
|             .collect()
 | |
|     }
 | |
| 
 | |
|     /// Generate a batch of key-value pairs
 | |
|     pub fn generate_string_pairs(&mut self, count: usize, value_size: usize) -> Vec<(String, String)> {
 | |
|         (0..count)
 | |
|             .map(|i| {
 | |
|                 let key = self.generate_key("bench:key", i);
 | |
|                 let value = self.generate_value(value_size);
 | |
|                 (key, value)
 | |
|             })
 | |
|             .collect()
 | |
|     }
 | |
| 
 | |
|     /// Generate hash data (key -> field-value pairs)
 | |
|     pub fn generate_hash_data(&mut self, num_hashes: usize, fields_per_hash: usize, value_size: usize) 
 | |
|         -> Vec<(String, Vec<(String, String)>)> {
 | |
|         (0..num_hashes)
 | |
|             .map(|i| {
 | |
|                 let hash_key = self.generate_key("bench:hash", i);
 | |
|                 let fields: Vec<(String, String)> = (0..fields_per_hash)
 | |
|                     .map(|j| {
 | |
|                         let field = format!("field{}", j);
 | |
|                         let value = self.generate_value(value_size);
 | |
|                         (field, value)
 | |
|                     })
 | |
|                     .collect();
 | |
|                 (hash_key, fields)
 | |
|             })
 | |
|             .collect()
 | |
|     }
 | |
| 
 | |
|     /// Generate list data (key -> list of elements)
 | |
|     pub fn generate_list_data(&mut self, num_lists: usize, elements_per_list: usize, element_size: usize) 
 | |
|         -> Vec<(String, Vec<String>)> {
 | |
|         (0..num_lists)
 | |
|             .map(|i| {
 | |
|                 let list_key = self.generate_key("bench:list", i);
 | |
|                 let elements: Vec<String> = (0..elements_per_list)
 | |
|                     .map(|_| self.generate_value(element_size))
 | |
|                     .collect();
 | |
|                 (list_key, elements)
 | |
|             })
 | |
|             .collect()
 | |
|     }
 | |
| 
 | |
|     /// Generate keys for pattern matching tests
 | |
|     pub fn generate_pattern_keys(&mut self, count: usize) -> Vec<String> {
 | |
|         let mut keys = Vec::new();
 | |
|         
 | |
|         // Generate keys with different patterns
 | |
|         for i in 0..count / 3 {
 | |
|             keys.push(format!("user:{}:profile", i));
 | |
|         }
 | |
|         for i in 0..count / 3 {
 | |
|             keys.push(format!("session:{}:data", i));
 | |
|         }
 | |
|         for i in 0..count / 3 {
 | |
|             keys.push(format!("cache:{}:value", i));
 | |
|         }
 | |
|         
 | |
|         keys
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[cfg(test)]
 | |
| mod tests {
 | |
|     use super::*;
 | |
| 
 | |
|     #[test]
 | |
|     fn test_deterministic_generation() {
 | |
|         let mut generator1 = DataGenerator::new(42);
 | |
|         let mut generator2 = DataGenerator::new(42);
 | |
| 
 | |
|         let pairs1 = generator1.generate_string_pairs(10, 50);
 | |
|         let pairs2 = generator2.generate_string_pairs(10, 50);
 | |
| 
 | |
|         assert_eq!(pairs1, pairs2, "Same seed should produce same data");
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn test_value_size() {
 | |
|         let mut generator = DataGenerator::new(42);
 | |
|         let value = generator.generate_value(100);
 | |
|         assert_eq!(value.len(), 100);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn test_hash_generation() {
 | |
|         let mut generator = DataGenerator::new(42);
 | |
|         let hashes = generator.generate_hash_data(5, 10, 50);
 | |
|         
 | |
|         assert_eq!(hashes.len(), 5);
 | |
|         for (_, fields) in hashes {
 | |
|             assert_eq!(fields.len(), 10);
 | |
|             for (_, value) in fields {
 | |
|                 assert_eq!(value.len(), 50);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } |