#![allow(dead_code)]
use crate::cache::DiffCache;
use crate::services::git::GitService;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
pub struct CachedDiffService {
git_service: Arc<GitService>,
cache: Mutex<DiffCache>,
}
impl CachedDiffService {
pub fn new(git_service: Arc<GitService>) -> Self {
Self {
git_service,
cache: Mutex::new(DiffCache::default()),
}
}
pub fn get_diff(
&self,
repo_path: &str,
file_path: &str,
staged: bool,
context: usize,
) -> Result<DiffResult, String> {
let path = PathBuf::from(file_path);
{
let mut cache = self.cache.lock().unwrap();
if let Some(entry) = cache.get(&path, staged) {
tracing::debug!("Diff cache HIT: {}", file_path);
return Ok(DiffResult {
content: entry.content.clone(),
truncated: entry.truncated,
total_lines: entry.total_lines,
from_cache: true,
});
}
}
tracing::debug!("Diff cache MISS: {}", file_path);
let content = self.git_service
.diff(repo_path, file_path, staged, context)
.map_err(|e| e.to_string())?;
let total_lines = content.lines().count();
let truncated = total_lines > 5000;
{
let mut cache = self.cache.lock().unwrap();
cache.put(path, staged, content.clone(), truncated, total_lines);
}
Ok(DiffResult {
content,
truncated,
total_lines,
from_cache: false,
})
}
pub fn invalidate(&self, file_path: &str) {
let path = PathBuf::from(file_path);
let mut cache = self.cache.lock().unwrap();
cache.invalidate(&path);
}
pub fn clear(&self) {
let mut cache = self.cache.lock().unwrap();
cache.clear();
}
pub fn stats(&self) -> crate::cache::diff::CacheStats {
let cache = self.cache.lock().unwrap();
cache.stats()
}
}
#[derive(Debug, Clone)]
pub struct DiffResult {
pub content: String,
pub truncated: bool,
pub total_lines: usize,
pub from_cache: bool,
}