use criterion::{black_box, criterion_group, criterion_main, Criterion}; use ourdb::{OurDB, OurDBConfig, OurDBSetArgs}; use std::path::PathBuf; use tempfile::tempdir; fn criterion_benchmark(c: &mut Criterion) { // Create a temporary directory for benchmarks let temp_dir = tempdir().expect("Failed to create temp directory"); let db_path = temp_dir.path().to_path_buf(); // Benchmark set operation (insertion) c.bench_function("set", |b| { let config = OurDBConfig { path: db_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), // 10MB keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let test_data = vec![b'X'; 100]; // 100 bytes of data let mut i = 0; b.iter(|| { let args = OurDBSetArgs { id: None, // Let the DB assign an ID data: &test_data, }; black_box(db.set(args).unwrap()); i += 1; }); }); // Setup database with data for other benchmarks let setup_config = OurDBConfig { path: db_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), // 10MB keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut setup_db = OurDB::new(setup_config).unwrap(); let test_data = vec![b'X'; 100]; // 100 bytes of data let mut ids = Vec::with_capacity(1000); // Insert 1000 records for _ in 0..1000 { let args = OurDBSetArgs { id: None, data: &test_data, }; let id = setup_db.set(args).unwrap(); ids.push(id); } // Benchmark get operation c.bench_function("get", |b| { let config = OurDBConfig { path: db_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let mut i = 0; b.iter(|| { let id = ids[i % ids.len()]; black_box(db.get(id).unwrap()); i += 1; }); }); // Benchmark update operation c.bench_function("update", |b| { let config = OurDBConfig { path: db_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let updated_data = vec![b'Y'; 100]; // Different data for updates let mut i = 0; b.iter(|| { let id = ids[i % ids.len()]; let args = OurDBSetArgs { id: Some(id), data: &updated_data, }; black_box(db.set(args).unwrap()); i += 1; }); }); // Benchmark get_history operation c.bench_function("get_history", |b| { let config = OurDBConfig { path: db_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let mut i = 0; b.iter(|| { let id = ids[i % ids.len()]; black_box(db.get_history(id, 2).unwrap()); i += 1; }); }); // Benchmark delete operation c.bench_function("delete", |b| { // Create a fresh database for deletion benchmarks let delete_dir = tempdir().expect("Failed to create temp directory"); let delete_path = delete_dir.path().to_path_buf(); let config = OurDBConfig { path: delete_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let test_data = vec![b'X'; 100]; // Setup keys to delete let mut delete_ids = Vec::with_capacity(1000); for _ in 0..1000 { let args = OurDBSetArgs { id: None, data: &test_data, }; let id = db.set(args).unwrap(); delete_ids.push(id); } let mut i = 0; b.iter(|| { let id = delete_ids[i % delete_ids.len()]; // Only try to delete if it exists (not already deleted) if db.get(id).is_ok() { black_box(db.delete(id).unwrap()); } i += 1; }); }); // Benchmark key-value mode vs incremental mode let mut group = c.benchmark_group("mode_comparison"); // Benchmark set in key-value mode group.bench_function("set_keyvalue_mode", |b| { let kv_dir = tempdir().expect("Failed to create temp directory"); let kv_path = kv_dir.path().to_path_buf(); let config = OurDBConfig { path: kv_path.clone(), incremental_mode: false, // Key-value mode file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let test_data = vec![b'X'; 100]; let mut i = 0; b.iter(|| { let id = i + 1; // Explicit ID let args = OurDBSetArgs { id: Some(id as u32), data: &test_data, }; black_box(db.set(args).unwrap()); i += 1; }); }); // Benchmark set in incremental mode group.bench_function("set_incremental_mode", |b| { let inc_dir = tempdir().expect("Failed to create temp directory"); let inc_path = inc_dir.path().to_path_buf(); let config = OurDBConfig { path: inc_path.clone(), incremental_mode: true, // Incremental mode file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let test_data = vec![b'X'; 100]; b.iter(|| { let args = OurDBSetArgs { id: None, // Auto-generated ID data: &test_data, }; black_box(db.set(args).unwrap()); }); }); group.finish(); // Benchmark with different record sizes let mut size_group = c.benchmark_group("record_size"); for &size in &[10, 100, 1000, 10000] { size_group.bench_function(format!("set_size_{}", size), |b| { let size_dir = tempdir().expect("Failed to create temp directory"); let size_path = size_dir.path().to_path_buf(); let config = OurDBConfig { path: size_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let test_data = vec![b'X'; size]; b.iter(|| { let args = OurDBSetArgs { id: None, data: &test_data, }; black_box(db.set(args).unwrap()); }); }); size_group.bench_function(format!("get_size_{}", size), |b| { let size_dir = tempdir().expect("Failed to create temp directory"); let size_path = size_dir.path().to_path_buf(); let config = OurDBConfig { path: size_path.clone(), incremental_mode: true, file_size: Some(10 * 1024 * 1024), keysize: Some(6), // Use keysize=6 to allow non-zero file_nr }; let mut db = OurDB::new(config).unwrap(); let test_data = vec![b'X'; size]; // Insert some records first let mut size_ids = Vec::with_capacity(100); for _ in 0..100 { let args = OurDBSetArgs { id: None, data: &test_data, }; let id = db.set(args).unwrap(); size_ids.push(id); } let mut i = 0; b.iter(|| { let id = size_ids[i % size_ids.len()]; black_box(db.get(id).unwrap()); i += 1; }); }); } size_group.finish(); } criterion_group!(benches, criterion_benchmark); criterion_main!(benches);