mirror of https://github.com/dswd/zvault
Fixes for cli and prune
This commit is contained in:
parent
e272e29628
commit
eb23713875
|
@ -99,7 +99,6 @@ Recommended: Brotli/2-7
|
||||||
|
|
||||||
### Core functionality
|
### Core functionality
|
||||||
- Fix vacuum inconsistencies (either index related, or bundle syncing related)
|
- Fix vacuum inconsistencies (either index related, or bundle syncing related)
|
||||||
- Proper bundle usage analysis with compressed size estimation
|
|
||||||
- Recompress & combine bundles
|
- Recompress & combine bundles
|
||||||
- Allow to use tar files for backup and restore (--tar, http://alexcrichton.com/tar-rs/tar/index.html)
|
- Allow to use tar files for backup and restore (--tar, http://alexcrichton.com/tar-rs/tar/index.html)
|
||||||
- Allow to mount backups (inode id == position in index, lru cache)
|
- Allow to mount backups (inode id == position in index, lru cache)
|
||||||
|
|
|
@ -41,7 +41,7 @@ fn get_backup(repo: &Repository, backup_name: &str) -> Backup {
|
||||||
checked(repo.get_backup(backup_name), "load backup")
|
checked(repo.get_backup(backup_name), "load backup")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_reference_backup(repo: &Repository, path: &str) -> Option<Backup> {
|
fn find_reference_backup(repo: &Repository, path: &str) -> Option<(String, Backup)> {
|
||||||
let mut matching = Vec::new();
|
let mut matching = Vec::new();
|
||||||
let hostname = match get_hostname() {
|
let hostname = match get_hostname() {
|
||||||
Ok(hostname) => hostname,
|
Ok(hostname) => hostname,
|
||||||
|
@ -58,12 +58,12 @@ fn find_reference_backup(repo: &Repository, path: &str) -> Option<Backup> {
|
||||||
exit(3)
|
exit(3)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for (_name, backup) in backup_map {
|
for (name, backup) in backup_map {
|
||||||
if backup.host == hostname && backup.path == path {
|
if backup.host == hostname && backup.path == path {
|
||||||
matching.push(backup);
|
matching.push((name, backup));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
matching.sort_by_key(|b| b.date);
|
matching.sort_by_key(|&(_, ref b)| b.date);
|
||||||
matching.pop()
|
matching.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ fn print_analysis(analysis: &HashMap<u32, BundleAnalysis>) {
|
||||||
println!("Reclaimable space (depending on vacuum ratio)");
|
println!("Reclaimable space (depending on vacuum ratio)");
|
||||||
#[allow(unknown_lints,needless_range_loop)]
|
#[allow(unknown_lints,needless_range_loop)]
|
||||||
for i in 0..11 {
|
for i in 0..11 {
|
||||||
println!(" - ratio={:3}: {:10}, {:4.1} %", i*10, to_file_size(reclaim_space[i] as u64), reclaim_space[i] as f32 / data_total as f32 * 100.0);
|
println!(" - ratio={:3}: {:>10}, {:4.1} %", i*10, to_file_size(reclaim_space[i] as u64), reclaim_space[i] as f32 / data_total as f32 * 100.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,16 +222,20 @@ pub fn run() {
|
||||||
let mut repo = open_repository(&repo_path);
|
let mut repo = open_repository(&repo_path);
|
||||||
let mut reference_backup = None;
|
let mut reference_backup = None;
|
||||||
if !full {
|
if !full {
|
||||||
reference_backup = reference.map(|r| get_backup(&repo, &r));
|
reference_backup = reference.map(|r| {
|
||||||
|
let b = get_backup(&repo, &r);
|
||||||
|
(r, b)
|
||||||
|
});
|
||||||
if reference_backup.is_none() {
|
if reference_backup.is_none() {
|
||||||
reference_backup = find_reference_backup(&repo, &src_path);
|
reference_backup = find_reference_backup(&repo, &src_path);
|
||||||
}
|
}
|
||||||
if let Some(ref backup) = reference_backup {
|
if let Some(&(ref name, _)) = reference_backup.as_ref() {
|
||||||
info!("Using backup from {} as reference", Local.timestamp(backup.date, 0).to_rfc2822());
|
info!("Using backup {} as reference", name);
|
||||||
} else {
|
} else {
|
||||||
info!("No reference backup found, doing a full scan instead");
|
info!("No reference backup found, doing a full scan instead");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let reference_backup = reference_backup.map(|(_, backup)| backup);
|
||||||
if let Some(excludes_from) = excludes_from {
|
if let Some(excludes_from) = excludes_from {
|
||||||
for line in BufReader::new(checked(File::open(excludes_from), "open excludes file")).lines() {
|
for line in BufReader::new(checked(File::open(excludes_from), "open excludes file")).lines() {
|
||||||
excludes.push(checked(line, "read excludes file"));
|
excludes.push(checked(line, "read excludes file"));
|
||||||
|
|
|
@ -13,7 +13,7 @@ use mmap::{MemoryMap, MapOption, MapError};
|
||||||
const MAGIC: [u8; 7] = *b"zvault\x02";
|
const MAGIC: [u8; 7] = *b"zvault\x02";
|
||||||
const VERSION: u8 = 1;
|
const VERSION: u8 = 1;
|
||||||
pub const MAX_USAGE: f64 = 0.9;
|
pub const MAX_USAGE: f64 = 0.9;
|
||||||
pub const MIN_USAGE: f64 = 0.25;
|
pub const MIN_USAGE: f64 = 0.35;
|
||||||
pub const INITIAL_SIZE: usize = 1024;
|
pub const INITIAL_SIZE: usize = 1024;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,26 +75,24 @@ impl Repository {
|
||||||
backups.push((name, date, backup));
|
backups.push((name, date, backup));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
backups.sort_by_key(|backup| backup.2.date);
|
backups.sort_by_key(|backup| -backup.2.date);
|
||||||
let mut keep = Bitmap::new(backups.len());
|
let mut keep = Bitmap::new(backups.len());
|
||||||
|
|
||||||
fn mark_needed<K: Eq, F: Fn(&DateTime<Local>) -> K>(backups: &[(String, DateTime<Local>, Backup)], keep: &mut Bitmap, max: usize, keyfn: F) {
|
fn mark_needed<K: Eq, F: Fn(&DateTime<Local>) -> K>(backups: &[(String, DateTime<Local>, Backup)], keep: &mut Bitmap, max: usize, keyfn: F) {
|
||||||
let mut unique = VecDeque::with_capacity(max+1);
|
let mut kept = 0;
|
||||||
let mut last = None;
|
let mut last = None;
|
||||||
for (i, backup) in backups.iter().enumerate() {
|
for (i, backup) in backups.iter().enumerate() {
|
||||||
let val = keyfn(&backup.1);
|
let val = keyfn(&backup.1);
|
||||||
let cur = Some(val);
|
let cur = Some(val);
|
||||||
if cur != last {
|
if cur != last {
|
||||||
last = cur;
|
if kept >= max {
|
||||||
unique.push_back(i);
|
break
|
||||||
if unique.len() > max {
|
|
||||||
unique.pop_front();
|
|
||||||
}
|
}
|
||||||
|
last = cur;
|
||||||
|
keep.set(i);
|
||||||
|
kept += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i in unique {
|
|
||||||
keep.set(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(max) = yearly {
|
if let Some(max) = yearly {
|
||||||
mark_needed(&backups, &mut keep, max, |d| d.year());
|
mark_needed(&backups, &mut keep, max, |d| d.year());
|
||||||
|
|
Loading…
Reference in New Issue