Implements internal read/write buffer optimization

- Spoiler Alert: Turns out it was just the lcm.
This commit is contained in:
Tyler 2021-06-08 14:14:19 -07:00
parent ef6c850833
commit 96fd665ce1
4 changed files with 1093 additions and 1082 deletions

2057
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -19,11 +19,11 @@ uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
# Probably best to keep this identical to the version of getopts in the uucore crate
getopts = "<= 0.2.21"
gcd = "2.0"
[dev-dependencies]
md-5 = "0.9"
hex-literal = "0.3"
rand = "0.8"
[[bin]]
name = "dd"

View file

@ -18,6 +18,7 @@ mod parseargs;
mod conversion_tables;
use conversion_tables::*;
use gcd::Gcd;
use std::cmp;
use std::convert::TryInto;
use std::error::Error;
@ -783,21 +784,6 @@ fn read_helper<R: Read, W: Write>(i: &mut Input<R>, o: &mut Output<W>, bsize: us
}
}
/// Write obs-size blocks
// fn write_helper<W: Write>(o: &mut Output<W>, buf: Vec<u8>) -> Result<usize, Box<dyn Error>>
// {
// let mut base_idx = 0;
//
// while base_idx < buf.len()
// {
// let width = cmp::min(base_idx+o.obs, buf.len());
// let wlen = o.write(&mut buf[base_idx..width])?;
// base_idx += wlen;
// }
//
// Ok(base_idx)
// }
/// Generate a progress updater that tracks progress, receives updates, and TODO: responds to signals.
fn gen_prog_updater(rx: mpsc::Receiver<usize>) -> impl Fn() -> ()
{
@ -822,11 +808,13 @@ fn gen_prog_updater(rx: mpsc::Receiver<usize>) -> impl Fn() -> ()
}
}
/// Find the greatest common factor for the pair of integers.
fn gcf(u: usize, v: usize) -> usize
#[inline]
fn calc_bsize(ibs: usize, obs: usize) -> usize
{
// TODO: 1 is not the gcf of all pairs of integers...
1
let gcd = Gcd::gcd(ibs, obs);
let lcm = (ibs*obs)/gcd;
lcm
}
/// Perform the copy/convert opertaions. Stdout version
@ -836,8 +824,7 @@ fn dd_stdout<R: Read>(mut i: Input<R>, mut o: Output<io::Stdout>) -> Result<(usi
{
let mut bytes_in = 0;
let mut bytes_out = 0;
let gcf = gcf(i.ibs, o.obs);
let buf_size = (i.ibs/gcf)*(o.obs/gcf);
let bsize = calc_bsize(i.ibs, o.obs);
let prog_tx = if i.xfer_stats == StatusLevel::Progress
{
@ -852,7 +839,7 @@ fn dd_stdout<R: Read>(mut i: Input<R>, mut o: Output<io::Stdout>) -> Result<(usi
loop
{
match read_helper(&mut i, &mut o, buf_size)?
match read_helper(&mut i, &mut o, bsize)?
{
(0, _) =>
break,
@ -891,8 +878,7 @@ fn dd_fileout<R: Read>(mut i: Input<R>, mut o: Output<File>) -> Result<(usize, u
{
let mut bytes_in = 0;
let mut bytes_out = 0;
let gcf = gcf(i.ibs, o.obs);
let buf_size = (i.ibs/gcf)*(o.obs/gcf);
let bsize = calc_bsize(i.ibs, o.obs);
let prog_tx = if i.xfer_stats == StatusLevel::Progress
{
@ -907,13 +893,13 @@ fn dd_fileout<R: Read>(mut i: Input<R>, mut o: Output<File>) -> Result<(usize, u
loop
{
match read_helper(&mut i, &mut o, buf_size)?
match read_helper(&mut i, &mut o, bsize)?
{
(0, _) =>
break,
(rlen, buf) =>
{
let wlen = o.write(&buf)?;
let wlen = o.write_blocks(buf)?;
bytes_in += rlen;
bytes_out += wlen;

View file

@ -65,3 +65,81 @@ make_spec_test!(
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(),
format!("./test-resources/FAILED-{}.test", "random-73k-obs-lt-not-a-multiple-ibs")
);
// Test internal buffer size fn
#[test]
fn bsize_test_primes()
{
let (n,m) = (7901, 7919);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, n*m);
}
#[test]
fn bsize_test_rel_prime_obs_greater()
{
let (n,m) = (7*5119, 13*5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7*13*5119);
}
#[test]
fn bsize_test_rel_prime_ibs_greater()
{
let (n,m) = (13*5119, 7*5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7*13*5119);
}
#[test]
fn bsize_test_3fac_rel_prime()
{
let (n,m) = (11*13*5119, 7*11*5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7*11*13*5119);
}
#[test]
fn bsize_test_ibs_greater()
{
let (n,m) = (512*1024, 256*1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, n);
}
#[test]
fn bsize_test_obs_greater()
{
let (n,m) = (256*1024, 512*1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, m);
}
#[test]
fn bsize_test_bs_eq()
{
let (n,m) = (1024, 1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, m);
}