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);
|
|
}
|
|
}
|
|
}
|
|
} |