mirror of
https://github.com/uutils/coreutils
synced 2025-01-19 00:24:13 +00:00
Implements internal read/write buffer optimization
- Spoiler Alert: Turns out it was just the lcm.
This commit is contained in:
parent
ef6c850833
commit
96fd665ce1
4 changed files with 1093 additions and 1082 deletions
2057
Cargo.lock
generated
2057
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue