vfs: hybrid file pruning

This commit is contained in:
bitful-pannul 2024-09-11 22:18:09 +03:00
parent eabe9c971c
commit 41998cf27d

View File

@ -622,19 +622,36 @@ async fn open_file<P: AsRef<Path>>(
fn cleanup_files(open_files: &DashMap<PathBuf, (Arc<Mutex<fs::File>>, Instant)>) { fn cleanup_files(open_files: &DashMap<PathBuf, (Arc<Mutex<fs::File>>, Instant)>) {
let current_count = open_files.len(); let current_count = open_files.len();
let target_count = max(current_count / 2, MAX_OPEN_FILES / 2); let target_count: usize = max(current_count / 2, MAX_OPEN_FILES / 2);
// collect all entries, sort by last access time if current_count <= MAX_OPEN_FILES {
let mut entries: Vec<_> = open_files return;
}
// calculate average last access time
let now = Instant::now();
let sum_duration: Duration = open_files
.iter() .iter()
.map(|entry| (entry.key().clone(), entry.value().1)) .map(|entry| now.duration_since(entry.value().1))
.collect(); .sum();
entries.sort_by(|a, b| a.1.cmp(&b.1)); let avg_duration = sum_duration / current_count as u32;
// remove oldest entries until we reach the target count // first pass: remove files older than average
for (path, _) in entries.into_iter().take(current_count - target_count) { open_files.retain(|_, (file, last_access)| {
// use remove_if_present to avoid potential race conditions now.duration_since(*last_access) < avg_duration || Arc::strong_count(file) > 1
open_files.remove_if(&path, |_, _| true); });
// second pass: if we're still over target, remove oldest files
if open_files.len() > target_count {
let mut entries: Vec<_> = open_files
.iter()
.map(|entry| (entry.key().clone(), entry.value().1))
.collect();
entries.sort_by(|a, b| b.1.cmp(&a.1)); // Sort by most recent first
for (path, _) in entries.into_iter().skip(target_count) {
open_files.remove_if(&path, |_, (file, _)| Arc::strong_count(file) == 1);
}
} }
} }