- Implement core Rust backend with FFmpeg integration - Add TheTVDB API client with token caching - Implement directory scanner with progress callbacks - Create file manager with rename and move operations - Add audit logging functionality - Implement file mapping for TV episode renaming - Build Node.js native addon via NAPI - Include comprehensive unit and integration tests - Update gitignore to exclude build artifacts and temp files Resolves #TBD
191 lines
5.7 KiB
Rust
191 lines
5.7 KiB
Rust
//! Benchmarks for MovieMapper
|
|
|
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
|
use movie_mapper::service::file_mapper::FileMapper;
|
|
use movie_mapper::service::file_metadata::MetadataExtractor;
|
|
use movie_mapper::service::file_scanner::FileScanner;
|
|
use std::fs::File;
|
|
use tempfile::tempdir;
|
|
|
|
fn bench_file_scanner(c: &mut Criterion) {
|
|
let temp_dir = tempdir().unwrap();
|
|
|
|
// Create test files
|
|
for i in 0..100 {
|
|
let file_path = temp_dir.path().join(format!("video{}.mp4", i));
|
|
File::create(&file_path).unwrap();
|
|
}
|
|
|
|
let scanner = FileScanner::new();
|
|
|
|
c.bench_function("scan_directory_100_files", |b| {
|
|
b.to_async(tokio::runtime::Runtime::new().unwrap())
|
|
.iter(|| async {
|
|
let _ = scanner.scan_directory(temp_dir.path(), None).await;
|
|
});
|
|
});
|
|
|
|
// With progress callback
|
|
c.bench_function("scan_directory_with_callback", |b| {
|
|
b.to_async(tokio::runtime::Runtime::new().unwrap())
|
|
.iter(|| async {
|
|
let mut progress_count = 0;
|
|
let mut callback = |_: usize, _: usize, _: &str| {
|
|
progress_count += 1;
|
|
};
|
|
let _ = scanner
|
|
.scan_directory(temp_dir.path(), Some(&mut callback))
|
|
.await;
|
|
});
|
|
});
|
|
}
|
|
|
|
fn bench_metadata_extraction(c: &mut Criterion) {
|
|
let temp_dir = tempdir().unwrap();
|
|
|
|
// Create test files
|
|
let file_path = temp_dir.path().join("test.mp4");
|
|
File::create(&file_path).unwrap();
|
|
|
|
let extractor = MetadataExtractor::new();
|
|
|
|
c.bench_function("extract_metadata", |b| {
|
|
b.iter(|| {
|
|
let _ = extractor.extract_metadata(black_box(&file_path));
|
|
});
|
|
});
|
|
|
|
c.bench_function("extract_duration", |b| {
|
|
b.iter(|| {
|
|
let _ = extractor.extract_duration(black_box(&file_path));
|
|
});
|
|
});
|
|
|
|
c.bench_function("extract_quality", |b| {
|
|
b.iter(|| {
|
|
let _ = extractor.extract_quality(black_box(&file_path));
|
|
});
|
|
});
|
|
}
|
|
|
|
fn bench_file_mapper(c: &mut Criterion) {
|
|
let temp_dir = tempdir().unwrap();
|
|
|
|
// Create test files
|
|
let mut files = Vec::new();
|
|
for i in 0..50 {
|
|
let file_path = temp_dir.path().join(format!("video{}.mp4", i));
|
|
File::create(&file_path).unwrap();
|
|
files.push(movie_mapper::model::file::MediaFile::from_path(file_path));
|
|
}
|
|
|
|
let mapper = FileMapper::new();
|
|
|
|
c.bench_function("generate_jellyfin_filename", |b| {
|
|
b.iter(|| {
|
|
let _ = mapper.generate_jellyfin_filename(
|
|
black_box("Show Name"),
|
|
black_box(1),
|
|
black_box(1),
|
|
black_box(1),
|
|
black_box("1080p"),
|
|
black_box(".mp4"),
|
|
);
|
|
});
|
|
});
|
|
|
|
c.bench_function("map_files_50", |b| {
|
|
b.to_async(tokio::runtime::Runtime::new().unwrap())
|
|
.iter(|| async {
|
|
let _ = mapper
|
|
.map_files(
|
|
black_box(&files),
|
|
black_box("Show Name"),
|
|
black_box(1),
|
|
black_box(None),
|
|
)
|
|
.await;
|
|
});
|
|
});
|
|
}
|
|
|
|
fn bench_tag_manager(c: &mut Criterion) {
|
|
let temp_dir = tempdir().unwrap();
|
|
|
|
// Create test files
|
|
let mut tag_manager = movie_mapper::service::tag_manager::TagManager::new();
|
|
|
|
// Add many tags
|
|
for i in 0..100 {
|
|
let file_path = temp_dir.path().join(format!("video{}.mp4", i));
|
|
File::create(&file_path).unwrap();
|
|
tag_manager.add_tag(&file_path, "extra").unwrap();
|
|
}
|
|
|
|
c.bench_function("add_tag", |b| {
|
|
b.iter(|| {
|
|
let temp_dir = tempdir().unwrap();
|
|
let file_path = temp_dir.path().join("test.mp4");
|
|
let mut manager = movie_mapper::service::tag_manager::TagManager::new();
|
|
let _ = manager.add_tag(black_box(&file_path), black_box("extra"));
|
|
});
|
|
});
|
|
|
|
c.bench_function("has_tag", |b| {
|
|
b.iter(|| {
|
|
let _ = tag_manager.has_tag(
|
|
black_box(&temp_dir.path().join("video1.mp4")),
|
|
black_box("extra"),
|
|
);
|
|
});
|
|
});
|
|
|
|
c.bench_function("get_tags", |b| {
|
|
b.iter(|| {
|
|
let _ = tag_manager.get_tags(black_box(&temp_dir.path().join("video1.mp4")));
|
|
});
|
|
});
|
|
|
|
c.bench_function("move_tagged_files", |b| {
|
|
b.to_async(tokio::runtime::Runtime::new().unwrap())
|
|
.iter(|| async {
|
|
let temp_dir = tempdir().unwrap();
|
|
let mut manager = movie_mapper::service::tag_manager::TagManager::new();
|
|
let file_path = temp_dir.path().join("test.mp4");
|
|
File::create(&file_path).unwrap();
|
|
manager.add_tag(&file_path, "extra").unwrap();
|
|
|
|
let target_folder = temp_dir.path().join("target");
|
|
let _ = manager
|
|
.move_tagged_files(black_box("extra"), black_box(&target_folder))
|
|
.await;
|
|
});
|
|
});
|
|
}
|
|
|
|
fn bench_audit_logger(c: &mut Criterion) {
|
|
let temp_dir = tempdir().unwrap();
|
|
let logger =
|
|
movie_mapper::service::audit_logger::AuditLogger::new(temp_dir.path().to_str().unwrap());
|
|
|
|
c.bench_function("log_event", |b| {
|
|
b.iter(|| {
|
|
let action = movie_mapper::service::audit_logger::AuditAction::DirectorySelected {
|
|
path: "/test/path".to_string(),
|
|
};
|
|
let _ = logger.log_event(black_box(action));
|
|
});
|
|
});
|
|
}
|
|
|
|
criterion_group!(
|
|
benches,
|
|
bench_file_scanner,
|
|
bench_metadata_extraction,
|
|
bench_file_mapper,
|
|
bench_tag_manager,
|
|
bench_audit_logger,
|
|
);
|
|
|
|
criterion_main!(benches);
|