Skip to content

Commit

Permalink
Fix: drop all old files from destinations, even if replaced
Browse files Browse the repository at this point in the history
  • Loading branch information
Gegy committed Jul 15, 2023
1 parent 1105571 commit d1a5ee9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 30 deletions.
48 changes: 24 additions & 24 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ async fn write_cache_index<P: AsRef<Path>>(path: P, index: &Index) -> io::Result

pub struct Loader {
root: PathBuf,
old_entries: HashMap<String, IndexEntry>,
entries: HashMap<String, IndexEntry>,
used_entries: HashSet<String>,
}
Expand All @@ -42,13 +43,15 @@ impl Loader {
}

let index = read_cache_index(&root.join("index.json")).await?;
let entries = index
let entries: HashMap<String, IndexEntry> = index
.entries
.into_iter()
.map(|entry| (entry.key.clone(), entry))
.collect();

Ok(Loader { root, entries, used_entries: HashSet::new() })
let old_entries = entries.clone();

Ok(Loader { root, old_entries, entries, used_entries: HashSet::new() })
}

pub fn entry<K: Into<String>>(&mut self, key: K) -> Entry {
Expand All @@ -68,10 +71,27 @@ impl Loader {
}
}

pub async fn close(self) -> io::Result<()> {
pub async fn close(mut self) -> io::Result<Vec<Reference>> {
let stale_entries: Vec<String> = self
.entries
.values()
.filter(|entry| !self.used_entries.contains(&entry.key))
.map(|entry| entry.key.clone())
.collect();
for key in stale_entries {
let entry = self.entries.remove(&key).unwrap();
let reference = self.reference_for(&entry);
fs::remove_file(&reference.path).await?;
}

let old_files = self.old_entries.clone().values()
.map(|entry| self.reference_for(&entry))
.collect();

let entries = self.entries.into_values().collect();
write_cache_index(&self.root.join("index.json"), &Index { entries }).await?;
Ok(())

Ok(old_files)
}

async fn update_entry(
Expand Down Expand Up @@ -127,26 +147,6 @@ impl Loader {
fn path_for(&self, key: &str) -> PathBuf {
self.root.join(key)
}

pub async fn drop_stale(&mut self) -> io::Result<Vec<Reference>> {
let stale_entries: Vec<String> = self
.entries
.values()
.filter(|entry| !self.used_entries.contains(&entry.key))
.map(|entry| entry.key.clone())
.collect();

let mut stale_references = Vec::with_capacity(stale_entries.len());
for key in stale_entries {
let entry = self.entries.remove(&key).unwrap();
let reference = self.reference_for(&entry);
fs::remove_file(&reference.path).await?;

stale_references.push(reference);
}

Ok(stale_references)
}
}

#[derive(Serialize, Deserialize, Clone)]
Expand Down
10 changes: 4 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,27 +183,25 @@ async fn prepare_destination(
}
}

let stale_files = cache.drop_stale().await?;

cache.close().await?;
let old_files = cache.close().await?;

Ok(PreparedDestination {
root: destination.path.clone(),
cache_files,
stale_files,
old_files,
})
}

struct PreparedDestination {
root: PathBuf,
cache_files: Vec<(String, cache::Reference)>,
stale_files: Vec<cache::Reference>,
old_files: Vec<cache::Reference>,
}

impl PreparedDestination {
async fn apply(&self) -> Result<()> {
if self.root.exists() {
for reference in &self.stale_files {
for reference in &self.old_files {
reference.remove_from(&self.root).await?;
}
} else {
Expand Down

0 comments on commit d1a5ee9

Please sign in to comment.