benchmarking
This commit is contained in:
		
							
								
								
									
										197
									
								
								benches/common/backends.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								benches/common/backends.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| // benches/common/backends.rs | ||||
| use herodb::storage::Storage; | ||||
| use herodb::storage_sled::SledStorage; | ||||
| use herodb::storage_trait::StorageBackend; | ||||
| use std::sync::Arc; | ||||
| use tempfile::TempDir; | ||||
|  | ||||
| /// Backend type identifier | ||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||||
| pub enum BackendType { | ||||
|     Redb, | ||||
|     Sled, | ||||
| } | ||||
|  | ||||
| impl BackendType { | ||||
|     pub fn name(&self) -> &'static str { | ||||
|         match self { | ||||
|             BackendType::Redb => "redb", | ||||
|             BackendType::Sled => "sled", | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn all() -> Vec<BackendType> { | ||||
|         vec![BackendType::Redb, BackendType::Sled] | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Wrapper for benchmark backends with automatic cleanup | ||||
| pub struct BenchmarkBackend { | ||||
|     pub storage: Arc<dyn StorageBackend>, | ||||
|     pub backend_type: BackendType, | ||||
|     _temp_dir: TempDir, // Kept for automatic cleanup | ||||
| } | ||||
|  | ||||
| impl BenchmarkBackend { | ||||
|     /// Create a new redb backend for benchmarking | ||||
|     pub fn new_redb() -> Result<Self, Box<dyn std::error::Error>> { | ||||
|         let temp_dir = TempDir::new()?; | ||||
|         let db_path = temp_dir.path().join("bench.db"); | ||||
|         let storage = Storage::new(db_path, false, None)?; | ||||
|          | ||||
|         Ok(Self { | ||||
|             storage: Arc::new(storage), | ||||
|             backend_type: BackendType::Redb, | ||||
|             _temp_dir: temp_dir, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /// Create a new sled backend for benchmarking | ||||
|     pub fn new_sled() -> Result<Self, Box<dyn std::error::Error>> { | ||||
|         let temp_dir = TempDir::new()?; | ||||
|         let db_path = temp_dir.path().join("bench.sled"); | ||||
|         let storage = SledStorage::new(db_path, false, None)?; | ||||
|          | ||||
|         Ok(Self { | ||||
|             storage: Arc::new(storage), | ||||
|             backend_type: BackendType::Sled, | ||||
|             _temp_dir: temp_dir, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /// Create a backend of the specified type | ||||
|     pub fn new(backend_type: BackendType) -> Result<Self, Box<dyn std::error::Error>> { | ||||
|         match backend_type { | ||||
|             BackendType::Redb => Self::new_redb(), | ||||
|             BackendType::Sled => Self::new_sled(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Get the backend name for display | ||||
|     pub fn name(&self) -> &'static str { | ||||
|         self.backend_type.name() | ||||
|     } | ||||
|  | ||||
|     /// Pre-populate the backend with test data | ||||
|     pub fn populate_strings(&self, data: &[(String, String)]) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         for (key, value) in data { | ||||
|             self.storage.set(key.clone(), value.clone())?; | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// Pre-populate with hash data | ||||
|     pub fn populate_hashes(&self, data: &[(String, Vec<(String, String)>)]) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         for (key, fields) in data { | ||||
|             self.storage.hset(key, fields.clone())?; | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// Pre-populate with list data | ||||
|     pub fn populate_lists(&self, data: &[(String, Vec<String>)]) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         for (key, elements) in data { | ||||
|             self.storage.rpush(key, elements.clone())?; | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// Clear all data from the backend | ||||
|     pub fn clear(&self) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         self.storage.flushdb()?; | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// Get the number of keys in the database | ||||
|     pub fn dbsize(&self) -> Result<i64, Box<dyn std::error::Error>> { | ||||
|         Ok(self.storage.dbsize()?) | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Helper function to create and populate a backend for read benchmarks | ||||
| pub fn setup_populated_backend( | ||||
|     backend_type: BackendType, | ||||
|     num_keys: usize, | ||||
|     value_size: usize, | ||||
| ) -> Result<BenchmarkBackend, Box<dyn std::error::Error>> { | ||||
|     use super::DataGenerator; | ||||
|      | ||||
|     let backend = BenchmarkBackend::new(backend_type)?; | ||||
|     let mut generator = DataGenerator::new(42); | ||||
|     let data = generator.generate_string_pairs(num_keys, value_size); | ||||
|     backend.populate_strings(&data)?; | ||||
|      | ||||
|     Ok(backend) | ||||
| } | ||||
|  | ||||
| /// Helper function to create and populate a backend with hash data | ||||
| pub fn setup_populated_backend_hashes( | ||||
|     backend_type: BackendType, | ||||
|     num_hashes: usize, | ||||
|     fields_per_hash: usize, | ||||
|     value_size: usize, | ||||
| ) -> Result<BenchmarkBackend, Box<dyn std::error::Error>> { | ||||
|     use super::DataGenerator; | ||||
|      | ||||
|     let backend = BenchmarkBackend::new(backend_type)?; | ||||
|     let mut generator = DataGenerator::new(42); | ||||
|     let data = generator.generate_hash_data(num_hashes, fields_per_hash, value_size); | ||||
|     backend.populate_hashes(&data)?; | ||||
|      | ||||
|     Ok(backend) | ||||
| } | ||||
|  | ||||
| /// Helper function to create and populate a backend with list data | ||||
| pub fn setup_populated_backend_lists( | ||||
|     backend_type: BackendType, | ||||
|     num_lists: usize, | ||||
|     elements_per_list: usize, | ||||
|     element_size: usize, | ||||
| ) -> Result<BenchmarkBackend, Box<dyn std::error::Error>> { | ||||
|     use super::DataGenerator; | ||||
|      | ||||
|     let backend = BenchmarkBackend::new(backend_type)?; | ||||
|     let mut generator = DataGenerator::new(42); | ||||
|     let data = generator.generate_list_data(num_lists, elements_per_list, element_size); | ||||
|     backend.populate_lists(&data)?; | ||||
|      | ||||
|     Ok(backend) | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_backend_creation() { | ||||
|         let redb = BenchmarkBackend::new_redb(); | ||||
|         assert!(redb.is_ok()); | ||||
|  | ||||
|         let sled = BenchmarkBackend::new_sled(); | ||||
|         assert!(sled.is_ok()); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_backend_populate() { | ||||
|         let backend = BenchmarkBackend::new_redb().unwrap(); | ||||
|         let data = vec![ | ||||
|             ("key1".to_string(), "value1".to_string()), | ||||
|             ("key2".to_string(), "value2".to_string()), | ||||
|         ]; | ||||
|          | ||||
|         backend.populate_strings(&data).unwrap(); | ||||
|         assert_eq!(backend.dbsize().unwrap(), 2); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_backend_clear() { | ||||
|         let backend = BenchmarkBackend::new_redb().unwrap(); | ||||
|         let data = vec![("key1".to_string(), "value1".to_string())]; | ||||
|          | ||||
|         backend.populate_strings(&data).unwrap(); | ||||
|         assert_eq!(backend.dbsize().unwrap(), 1); | ||||
|          | ||||
|         backend.clear().unwrap(); | ||||
|         assert_eq!(backend.dbsize().unwrap(), 0); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user