Fixes for cli and prune

This commit is contained in:
Dennis Schwerdel 2017-03-25 13:09:45 +01:00 committed by Dennis Schwerdel
parent e272e29628
commit eb23713875
4 changed files with 20 additions and 19 deletions

View File

@ -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)

View File

@ -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"));

View 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;

View File

@ -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());