mirror of https://github.com/dswd/zvault
Combine smaller bundles into larger ones (closes #15)
This commit is contained in:
parent
001a36a1eb
commit
d18cb17281
|
@ -43,6 +43,11 @@ should be avoided when the storage space permits it.
|
||||||
|
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
|
* `--combine`:
|
||||||
|
|
||||||
|
Also combine small bundles into larger ones.
|
||||||
|
|
||||||
|
|
||||||
* `-r`, `--ratio <NUM>`:
|
* `-r`, `--ratio <NUM>`:
|
||||||
|
|
||||||
Do not rewrite bundles with more than `NUM`% of used chunks.
|
Do not rewrite bundles with more than `NUM`% of used chunks.
|
||||||
|
|
|
@ -52,7 +52,8 @@ pub enum Arguments {
|
||||||
Vacuum {
|
Vacuum {
|
||||||
repo_path: String,
|
repo_path: String,
|
||||||
ratio: f32,
|
ratio: f32,
|
||||||
force: bool
|
force: bool,
|
||||||
|
combine: bool
|
||||||
},
|
},
|
||||||
Check {
|
Check {
|
||||||
repo_path: String,
|
repo_path: String,
|
||||||
|
@ -337,6 +338,7 @@ pub fn parse() -> Result<(LogLevel, Arguments), ErrorCode> {
|
||||||
.subcommand(SubCommand::with_name("vacuum").about("Reclaim space by rewriting bundles")
|
.subcommand(SubCommand::with_name("vacuum").about("Reclaim space by rewriting bundles")
|
||||||
.arg(Arg::from_usage("-r --ratio [NUM] 'Ratio in % of unused space in a bundle to rewrite that bundle'")
|
.arg(Arg::from_usage("-r --ratio [NUM] 'Ratio in % of unused space in a bundle to rewrite that bundle'")
|
||||||
.default_value(DEFAULT_VACUUM_RATIO_STR).validator(validate_num))
|
.default_value(DEFAULT_VACUUM_RATIO_STR).validator(validate_num))
|
||||||
|
.arg(Arg::from_usage("--combine 'Combine small bundles into larger ones'"))
|
||||||
.arg(Arg::from_usage("-f --force 'Actually run the vacuum instead of simulating it'"))
|
.arg(Arg::from_usage("-f --force 'Actually run the vacuum instead of simulating it'"))
|
||||||
.arg(Arg::from_usage("<REPO> 'Path of the repository'")
|
.arg(Arg::from_usage("<REPO> 'Path of the repository'")
|
||||||
.validator(|val| validate_repo_path(val, true, Some(false), Some(false)))))
|
.validator(|val| validate_repo_path(val, true, Some(false), Some(false)))))
|
||||||
|
@ -490,6 +492,7 @@ pub fn parse() -> Result<(LogLevel, Arguments), ErrorCode> {
|
||||||
Arguments::Vacuum {
|
Arguments::Vacuum {
|
||||||
repo_path: repository.to_string(),
|
repo_path: repository.to_string(),
|
||||||
force: args.is_present("force"),
|
force: args.is_present("force"),
|
||||||
|
combine: args.is_present("combine"),
|
||||||
ratio: parse_num(args.value_of("ratio").unwrap()).unwrap() as f32 / 100.0
|
ratio: parse_num(args.value_of("ratio").unwrap()).unwrap() as f32 / 100.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -435,10 +435,10 @@ pub fn run() -> Result<(), ErrorCode> {
|
||||||
info!("Run with --force to actually execute this command");
|
info!("Run with --force to actually execute this command");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Arguments::Vacuum{repo_path, ratio, force} => {
|
Arguments::Vacuum{repo_path, ratio, force, combine} => {
|
||||||
let mut repo = try!(open_repository(&repo_path));
|
let mut repo = try!(open_repository(&repo_path));
|
||||||
let info_before = repo.info();
|
let info_before = repo.info();
|
||||||
checked!(repo.vacuum(ratio, force), "vacuum", ErrorCode::VacuumRun);
|
checked!(repo.vacuum(ratio, combine, force), "vacuum", ErrorCode::VacuumRun);
|
||||||
if !force {
|
if !force {
|
||||||
info!("Run with --force to actually execute this command");
|
info!("Run with --force to actually execute this command");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -284,7 +284,7 @@ impl Repository {
|
||||||
},
|
},
|
||||||
Err(err) => return Err(err)
|
Err(err) => return Err(err)
|
||||||
};
|
};
|
||||||
for (name, mut backup) in ProgressIter::new("ckecking backups", backup_map.len(), backup_map.into_iter()) {
|
for (name, mut backup) in ProgressIter::new("checking backups", backup_map.len(), backup_map.into_iter()) {
|
||||||
let path = format!("{}::", name);
|
let path = format!("{}::", name);
|
||||||
match self.check_subtree(Path::new(&path).to_path_buf(), &backup.root, &mut checked, repair) {
|
match self.check_subtree(Path::new(&path).to_path_buf(), &backup.root, &mut checked, repair) {
|
||||||
Ok(None) => (),
|
Ok(None) => (),
|
||||||
|
|
|
@ -13,7 +13,7 @@ impl Repository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vacuum(&mut self, ratio: f32, force: bool) -> Result<(), RepositoryError> {
|
pub fn vacuum(&mut self, ratio: f32, combine: bool, force: bool) -> Result<(), RepositoryError> {
|
||||||
try!(self.flush());
|
try!(self.flush());
|
||||||
info!("Locking repository");
|
info!("Locking repository");
|
||||||
try!(self.write_mode());
|
try!(self.write_mode());
|
||||||
|
@ -36,6 +36,28 @@ impl Repository {
|
||||||
reclaim_space += bundle.get_unused_size();
|
reclaim_space += bundle.get_unused_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if combine {
|
||||||
|
let mut small_meta = vec![];
|
||||||
|
let mut small_data = vec![];
|
||||||
|
for (id, bundle) in &usage {
|
||||||
|
if bundle.info.encoded_size * 4 < self.config.bundle_size {
|
||||||
|
match bundle.info.mode {
|
||||||
|
BundleMode::Meta => small_meta.push(*id),
|
||||||
|
BundleMode::Data => small_data.push(*id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if small_meta.len() >= 2 {
|
||||||
|
for bundle in small_meta {
|
||||||
|
rewrite_bundles.insert(bundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if small_data.len() >= 2 {
|
||||||
|
for bundle in small_data {
|
||||||
|
rewrite_bundles.insert(bundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
info!("Reclaiming {} by rewriting {} bundles", to_file_size(reclaim_space as u64), rewrite_bundles.len());
|
info!("Reclaiming {} by rewriting {} bundles", to_file_size(reclaim_space as u64), rewrite_bundles.len());
|
||||||
if !force {
|
if !force {
|
||||||
self.dirty = false;
|
self.dirty = false;
|
||||||
|
|
Loading…
Reference in New Issue