[cache_metadata_size (rust)] First code drop

This commit is contained in:
Ming-Hung Tsai 2021-10-08 22:02:57 +08:00
parent cc89cef43f
commit 34f6b6fc62
5 changed files with 111 additions and 0 deletions

View File

@ -30,6 +30,8 @@ fn main_() -> Result<()> {
cache_check::run(&new_args);
} else if name_eq(name, "cache_dump") {
cache_dump::run(&new_args);
} else if name_eq(name, "cache_metadata_size") {
cache_metadata_size::run(&new_args);
} else if name_eq(name, "cache_repair") {
cache_repair::run(&new_args);
} else if name_eq(name, "cache_restore") {

19
src/cache/metadata_size.rs vendored Normal file
View File

@ -0,0 +1,19 @@
use anyhow::Result;
pub struct CacheMetadataSizeOptions {
pub nr_blocks: u64,
pub max_hint_width: u32, // bytes
}
pub fn metadata_size(opts: &CacheMetadataSizeOptions) -> Result<u64> {
const SECTOR_SHIFT: u64 = 9; // 512 bytes per sector
const BYTES_PER_BLOCK_SHIFT: u64 = 4; // 16 bytes for key and value
const TRANSACTION_OVERHEAD: u64 = 8192; // in sectors; 4 MB
const HINT_OVERHEAD_PER_BLOCK: u64 = 8; // 8 bytes for the key
let mapping_size = (opts.nr_blocks << BYTES_PER_BLOCK_SHIFT) >> SECTOR_SHIFT;
let hint_size =
(opts.nr_blocks * (opts.max_hint_width as u64 + HINT_OVERHEAD_PER_BLOCK)) >> SECTOR_SHIFT;
Ok(TRANSACTION_OVERHEAD + mapping_size + hint_size)
}

1
src/cache/mod.rs vendored
View File

@ -3,6 +3,7 @@ pub mod dump;
pub mod hint;
pub mod ir;
pub mod mapping;
pub mod metadata_size;
pub mod repair;
pub mod restore;
pub mod superblock;

View File

@ -0,0 +1,88 @@
extern crate clap;
use clap::{value_t_or_exit, App, Arg, ArgGroup};
use std::ffi::OsString;
use std::process;
use crate::cache::metadata_size::{metadata_size, CacheMetadataSizeOptions};
use crate::math::div_up;
//------------------------------------------
fn parse_args<I, T>(args: I) -> CacheMetadataSizeOptions
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let parser = App::new("cache_metadata_size")
.version(crate::version::tools_version())
.about("Estimate the size of the metadata device needed for a given configuration.")
.usage("cache_metadata_size [OPTIONS] <--device-size <SECTORS> --block-size <SECTORS> | --nr-blocks <NUM>>")
// options
.arg(
Arg::with_name("BLOCK_SIZE")
.help("Specify the size of each cache block")
.long("block-size")
.requires("DEVICE_SIZE")
.value_name("SECTORS"),
)
.arg(
Arg::with_name("DEVICE_SIZE")
.help("Specify total size of the fast device used in the cache")
.long("device-size")
.requires("BLOCK_SIZE")
.value_name("SECTORS"),
)
.arg(
Arg::with_name("NR_BLOCKS")
.help("Specify the number of cache blocks")
.long("nr-blocks")
.value_name("NUM"),
)
.arg(
Arg::with_name("MAX_HINT_WIDTH")
.help("Specity the per-block hint width")
.long("max-hint-width")
.value_name("BYTES")
.default_value("4"),
)
.group(
ArgGroup::with_name("selection")
.args(&["DEVICE_SIZE", "NR_BLOCKS"])
.required(true)
);
let matches = parser.get_matches_from(args);
let nr_blocks = matches.value_of("NR_BLOCKS").map_or_else(
|| {
let device_size = value_t_or_exit!(matches.value_of("DEVICE_SIZE"), u64);
let block_size = value_t_or_exit!(matches.value_of("BLOCK_SIZE"), u32);
div_up(device_size, block_size as u64)
},
|_| value_t_or_exit!(matches.value_of("NR_BLOCKS"), u64),
);
let max_hint_width = value_t_or_exit!(matches.value_of("MAX_HINT_WIDTH"), u32);
CacheMetadataSizeOptions {
nr_blocks,
max_hint_width,
}
}
pub fn run(args: &[std::ffi::OsString]) {
let opts = parse_args(args);
match metadata_size(&opts) {
Ok(size) => {
println!("{} sectors", size);
}
Err(reason) => {
eprintln!("{}", reason);
process::exit(1);
}
}
}
//------------------------------------------

View File

@ -1,5 +1,6 @@
pub mod cache_check;
pub mod cache_dump;
pub mod cache_metadata_size;
pub mod cache_repair;
pub mod cache_restore;
pub mod era_check;