#![forbid(unsafe_code)]
use std::path::PathBuf;
use crate::optimizer::background::optimize_pass;
use crate::optimizer::policy::OptimizeOptions;
use crate::store::{Store, StoreConfig};
#[derive(Debug, Clone, clap::Args)]
pub struct OptimizeArgs {
#[arg(value_name = "STORE")]
pub store: PathBuf,
#[arg(long)]
pub raw_only: bool,
#[arg(long)]
pub raw_rans: bool,
#[arg(long)]
pub no_dsfb: bool,
}
pub fn run(args: &OptimizeArgs) -> Result<(), String> {
crate::fsck::ensure_unmounted(&args.store)?;
let config = StoreConfig::default();
let store = Store::open(&args.store, &config).map_err(|e| e.to_string())?;
let mut options = OptimizeOptions::default();
if args.raw_only {
options = OptimizeOptions::raw_only();
} else if args.raw_rans {
options = OptimizeOptions::raw_rans();
}
if args.no_dsfb {
options.allow_dsfb_ranking = false;
}
let stats = optimize_pass(&store, options, None, None).map_err(|e| e.to_string())?;
println!(
"optimize: scanned {} extents, rewrote {}, saved ~{} persisted bytes (stale {}, no-gain {}, errors {})",
stats.scanned,
stats.rewritten,
stats.saved_bytes,
stats.stale_skips,
stats.no_gain,
stats.errors
);
let shared = crate::optimizer::background::shared_dict_pass(&store, options, None)
.map_err(|e| e.to_string())?;
if shared.rewritten > 0 || shared.scanned > 0 {
println!(
"optimize: shared-dict pass scanned {} extents, rewrote {}, saved ~{} persisted bytes (no-gain {}, errors {})",
shared.scanned, shared.rewritten, shared.saved_bytes, shared.no_gain, shared.errors
);
}
let models = crate::optimizer::background::model_bundle_pass(&store, options, None)
.map_err(|e| e.to_string())?;
if models.rewritten > 0 || models.scanned > 0 {
println!(
"optimize: model-bundle pass scanned {} extents, rewrote {}, saved ~{} persisted bytes (no-gain {}, errors {})",
models.scanned, models.rewritten, models.saved_bytes, models.no_gain, models.errors
);
}
Ok(())
}