extern crate clap; extern crate ecpool; #[macro_use] extern crate trackable; #[cfg(not(unix))] fn main() { panic!("Unsupported platform"); } #[cfg(unix)] fn main() -> Result<(), trackable::error::MainError> { use clap::{App, Arg}; use ecpool::{BuildCoder, ErasureCode}; use std::fs; use std::io::{Read, Write}; use std::num::NonZeroUsize; use std::time::Instant; use trackable::error::Failed; let matches = App::new("encode") .arg(Arg::with_name("INPUT_FILE").index(1).required(true)) .arg( Arg::with_name("DATA_FRAGMENTS") .short("k") .takes_value(true) .default_value("6"), ).arg( Arg::with_name("PARITY_FRAGMENTS") .short("m") .takes_value(true) .default_value("3"), ).arg( Arg::with_name("CHECKSUM") .short("c") .takes_value(true) .possible_values(&["none", "crc32", "md5"]) .default_value("none"), ).get_matches(); let input_file = matches.value_of("INPUT_FILE").unwrap(); let mut input_data = Vec::new(); let mut file = track_any_err!(fs::File::open(input_file))?; track_any_err!(file.read_to_end(&mut input_data))?; println!("# READ INPUT FILE: bytes={}", input_data.len()); let k = track_any_err!(matches.value_of("DATA_FRAGMENTS").unwrap().parse())?; let m = track_any_err!(matches.value_of("PARITY_FRAGMENTS").unwrap().parse())?; let checksum = match matches.value_of("CHECKSUM").unwrap() { "none" => ecpool::liberasurecode::Checksum::None, "crc32" => ecpool::liberasurecode::Checksum::Crc32, "md5" => ecpool::liberasurecode::Checksum::Md5, _ => unreachable!(), }; let k = track_assert_some!(NonZeroUsize::new(k), Failed); let m = track_assert_some!(NonZeroUsize::new(m), Failed); let mut ec = track!( ecpool::liberasurecode::LibErasureCoderBuilder::new(k, m) .checksum(checksum) .build_coder() )?; let start_time = Instant::now(); let fragments = track!(ec.encode(&input_data[..]))?; let elapsed = start_time.elapsed(); println!( "# ENCODE TIME: {} sec", elapsed.as_secs() as f64 + (elapsed.subsec_nanos() as f64 / 1_000_000_000.0) ); let encoded_size: usize = fragments.iter().map(|f| f.len()).sum(); println!( "# ENCODED SIZE: bytes={} ({}/{} = {})", encoded_size, encoded_size, input_data.len(), encoded_size as f64 / input_data.len() as f64 ); for (i, fragment) in fragments.iter().enumerate().take(k.get()) { let path = format!("{}.data_{}", input_file, i); println!( "# DATA FRAGMENT({}): bytes={}, file={:?}", i, fragment.len(), path ); let mut file = track_any_err!(fs::File::create(path))?; track_any_err!(file.write_all(&fragment[..]))?; } for i in 0..m.get() { let path = format!("{}.parity_{}", input_file, i); println!( "# PARITY FRAGMENT({}): bytes={}, file={:?}", i, fragments[k.get() + i].len(), path ); let mut file = track_any_err!(fs::File::create(path))?; track_any_err!(file.write_all(&fragments[k.get() + i][..]))?; } Ok(()) }