Skip to content

Commit

Permalink
Scan cache in inode order
Browse files Browse the repository at this point in the history
  • Loading branch information
james58899 committed May 29, 2024
1 parent 3b1e8d3 commit d955b92
Showing 1 changed file with 70 additions and 12 deletions.
82 changes: 70 additions & 12 deletions src/cache_manager.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{
collections::HashMap,
collections::{BTreeMap, HashMap},
ffi::OsStr,
fmt::Display,
fs::Metadata,
io::Error,
Expand Down Expand Up @@ -287,9 +288,10 @@ impl CacheManager {
.map(|dir| async move {
let mut time = FileTime::now();
let mut stream = read_dir(&dir).await?;
let mut btree = BTreeMap::new();
while let Some(entry) = stream.next_entry().await? {
let path = entry.path();
let metadata = metadata(&path).await;
let metadata = entry.metadata().await;
if let Err(err) = metadata {
error!("Read cache file metadata error: path={:?}, err={}", path, err);
continue;
Expand Down Expand Up @@ -324,8 +326,40 @@ impl CacheManager {
}

if verify_cache {
// We need verify cache integrity, save path to btree and delay size calculation
let inode = get_inode(&metadata).unwrap_or(btree.len() as u64); // sort by inode or sequential
btree.insert(inode, path);
} else {
self.total_size.fetch_add(file_real_size_fast(&path, &metadata)?, Relaxed);

// Add recently accessed file to the cache.
let mtime = FileTime::from_last_modification_time(&metadata);
if mtime > lru_cutoff {
self.mark_recently_accessed(&info, false).await;
}
if mtime < time {
time = mtime;
}
}
}

if verify_cache {
while let Some((_, path)) = btree.pop_first() {
let mut file = match File::open(&path).await {
Ok(file) => file,
Err(err) => {
error!("Open cache file {} error: {}", path.display(), err);
continue;
}
};
let info = match path.file_name().and_then(OsStr::to_str).and_then(CacheFileInfo::from_file_id) {
Some(info) => info,
None => {
warn!("Failed to parse cache info: {:?}", path);
continue;
}
};
let mut hasher = Sha1::new();
let mut file = File::open(&path).await?;
let mut buf = vec![0; 1024 * 1024]; // 1MiB
loop {
match file.read(&mut buf).await {
Expand All @@ -352,17 +386,20 @@ impl CacheManager {
}
continue;
}
}

self.total_size.fetch_add(file_real_size_fast(&path, &metadata)?, Relaxed);
// File is correct, calculate size
if let Ok(metadata) = file.metadata().await {
self.total_size.fetch_add(file_real_size_fast(&path, &metadata)?, Relaxed);

// Add recently accessed file to the cache.
let mtime = FileTime::from_last_modification_time(&metadata);
if mtime > lru_cutoff {
self.mark_recently_accessed(&info, false).await;
}
if mtime < time {
time = mtime;
// Add recently accessed file to the cache.
let mtime = FileTime::from_last_modification_time(&metadata);
if mtime > lru_cutoff {
self.mark_recently_accessed(&info, false).await;
}
if mtime < time {
time = mtime;
}
}
}
}

Expand Down Expand Up @@ -553,6 +590,27 @@ fn get_available_space(path: &Path) -> Option<u64> {
None // Not support
}

#[cfg(unix)]
fn get_inode(metadata: &Metadata) -> Option<u64> {
use std::os::unix::fs::MetadataExt;

Some(metadata.ino())
}

#[cfg(windows)]
fn get_inode(metadata: &Metadata) -> Option<u64> {
use std::os::windows::fs::MetadataExt;

// On windows file_index not stable yet, use ctime instead
Some(metadata.creation_time())
}

#[cfg(not(any(unix, windows)))]
fn get_inode(_metadata: &Metadata) -> Option<u64> {
// Not support
None
}

async fn clean_temp_dir(path: &Path) {
info!("Deleting old temp files");

Expand Down

0 comments on commit d955b92

Please sign in to comment.