111 lines
2.6 KiB
Rust
111 lines
2.6 KiB
Rust
/// Generic compaction operation executor
|
|||
|
|
///
|
||
|
|
/// Eliminates mode-based branching duplication.
|
||
|
|
/// Centralizes DryRun vs Execute logic.
|
||
|
|
|
||
|
|
use crate::compaction::CompactionMode;
|
||
|
|
use tracing::debug;
|
||
|
|
|
||
|
|
/// Generic compaction operation result
|
||
|
|
#[derive(Debug, Clone, Copy)]
|
||
|
|
pub struct OperationResult {
|
||
|
|
pub executed: bool,
|
||
|
|
pub count: usize,
|
||
|
|
pub bytes: usize,
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Execute a compaction operation (generically handles DryRun vs Execute)
|
||
|
|
///
|
||
|
|
/// # Example
|
||
|
|
/// ```ignore
|
||
|
|
/// let result = execute_operation(
|
||
|
|
/// mode,
|
||
|
|
/// "duplicate deletion",
|
||
|
|
/// 10, // count
|
||
|
|
/// |_| async { /* actual DB operation */ },
|
||
|
|
/// ).await?;
|
||
|
|
/// ```
|
||
|
|
pub async fn execute_operation<F>(
|
||
|
|
mode: CompactionMode,
|
||
|
|
operation_name: &str,
|
||
|
|
count: usize,
|
||
|
|
bytes: usize,
|
||
|
|
execute_fn: F,
|
||
|
|
) -> anyhow::Result<OperationResult>
|
||
|
|
where
|
||
|
|
F: std::future::Future<Output = anyhow::Result<()>>,
|
||
|
|
{
|
||
|
|
match mode {
|
||
|
|
CompactionMode::DryRun => {
|
||
|
|
debug!("DRY-RUN: Would {} ({} items, {} bytes)", operation_name, count, bytes);
|
||
|
|
Ok(OperationResult {
|
||
|
|
executed: false,
|
||
|
|
count,
|
||
|
|
bytes,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
CompactionMode::Execute => {
|
||
|
|
execute_fn.await?;
|
||
|
|
debug!("EXECUTED: {} ({} items, {} bytes)", operation_name, count, bytes);
|
||
|
|
Ok(OperationResult {
|
||
|
|
executed: true,
|
||
|
|
count,
|
||
|
|
bytes,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(test)]
|
||
|
|
mod tests {
|
||
|
|
use super::*;
|
||
|
|
|
||
|
|
#[tokio::test]
|
||
|
|
async fn test_operation_result_dry_run() {
|
||
|
|
let result = execute_operation(
|
||
|
|
CompactionMode::DryRun,
|
||
|
|
"test",
|
||
|
|
5,
|
||
|
|
1024,
|
||
|
|
async { Ok(()) },
|
||
|
|
)
|
||
|
|
.await
|
||
|
|
.unwrap();
|
||
|
|
|
||
|
|
assert!(!result.executed);
|
||
|
|
assert_eq!(result.count, 5);
|
||
|
|
assert_eq!(result.bytes, 1024);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[tokio::test]
|
||
|
|
async fn test_operation_result_execute() {
|
||
|
|
let result = execute_operation(
|
||
|
|
CompactionMode::Execute,
|
||
|
|
"test",
|
||
|
|
5,
|
||
|
|
1024,
|
||
|
|
async { Ok(()) },
|
||
|
|
)
|
||
|
|
.await
|
||
|
|
.unwrap();
|
||
|
|
|
||
|
|
assert!(result.executed);
|
||
|
|
assert_eq!(result.count, 5);
|
||
|
|
assert_eq!(result.bytes, 1024);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[tokio::test]
|
||
|
|
async fn test_operation_result_error_handling() {
|
||
|
|
let result = execute_operation(
|
||
|
|
CompactionMode::Execute,
|
||
|
|
"test",
|
||
|
|
5,
|
||
|
|
1024,
|
||
|
|
async { Err(anyhow::anyhow!("test error")) },
|
||
|
|
)
|
||
|
|
.await;
|
||
|
|
|
||
|
|
assert!(result.is_err());
|
||
|
|
}
|
||
|
|
}
|