use super::*;
pub(super) enum Relocate {
Renamed,
DiskFull,
Refetch,
}
impl<H, F, G, C> Ctx<'_, H, F, G, C>
where
H: Http,
F: Filesystem,
G: Ffmpeg,
C: Clock,
{
pub(super) fn remove_superseded(
&self,
id: &str,
old: Option<&str>,
new: &str,
tracked_paths: &mut HashMap<String, u32>,
committed: &BTreeSet<String>,
label: &str,
) -> Result<(), Fail> {
if let Some(old) = old
&& !old.is_empty()
&& old != new
{
let still_referenced = tracked_paths
.get_mut(old)
.map(|count| {
*count = count.saturating_sub(1);
*count > 0
})
.unwrap_or(false);
if !still_referenced && !committed.contains(old) {
self.fs.remove(old).map_err(|err| {
disk_or_permanent(
id,
err.is_out_of_space(),
format!("disk full: no space left to remove old {label} {old}"),
format!("could not remove old {label} {old}: {err}"),
)
})?;
}
}
Ok(())
}
pub(super) fn try_relocate(
&self,
from: &str,
to: &str,
tracked_paths: &mut HashMap<String, u32>,
committed: &BTreeSet<String>,
) -> Relocate {
let exclusive =
tracked_paths.get(from).is_none_or(|count| *count <= 1) && !committed.contains(from);
if from != to && exclusive {
match self.fs.rename(from, to) {
Ok(()) => {
if let Some(count) = tracked_paths.get_mut(from) {
*count = count.saturating_sub(1);
}
return Relocate::Renamed;
}
Err(err) if err.is_out_of_space() => return Relocate::DiskFull,
Err(_) => {}
}
}
Relocate::Refetch
}
}