mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-02 22:17:45 +00:00
dd: reuse buffer for the most common cases
This commit is contained in:
parent
d1f7f51f99
commit
4cc058a789
1 changed files with 17 additions and 7 deletions
|
@ -414,6 +414,10 @@ where
|
||||||
let (prog_tx, rx) = mpsc::channel();
|
let (prog_tx, rx) = mpsc::channel();
|
||||||
thread::spawn(gen_prog_updater(rx, i.print_level));
|
thread::spawn(gen_prog_updater(rx, i.print_level));
|
||||||
|
|
||||||
|
// Create a common buffer with a capacity of the block size.
|
||||||
|
// This is the max size needed.
|
||||||
|
let mut buf = vec![BUF_INIT_BYTE; bsize];
|
||||||
|
|
||||||
// The main read/write loop.
|
// The main read/write loop.
|
||||||
//
|
//
|
||||||
// Each iteration reads blocks from the input and writes
|
// Each iteration reads blocks from the input and writes
|
||||||
|
@ -427,7 +431,7 @@ where
|
||||||
// best buffer size for reading based on the number of
|
// best buffer size for reading based on the number of
|
||||||
// blocks already read and the number of blocks remaining.
|
// blocks already read and the number of blocks remaining.
|
||||||
let loop_bsize = calc_loop_bsize(&i.count, &rstat, &wstat, i.ibs, bsize);
|
let loop_bsize = calc_loop_bsize(&i.count, &rstat, &wstat, i.ibs, bsize);
|
||||||
let (rstat_update, buf) = read_helper(&mut i, loop_bsize)?;
|
let rstat_update = read_helper(&mut i, &mut buf, loop_bsize)?;
|
||||||
if rstat_update.is_empty() {
|
if rstat_update.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -600,7 +604,11 @@ impl Write for Output<io::Stdout> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read helper performs read operations common to all dd reads, and dispatches the buffer to relevant helper functions as dictated by the operations requested by the user.
|
/// Read helper performs read operations common to all dd reads, and dispatches the buffer to relevant helper functions as dictated by the operations requested by the user.
|
||||||
fn read_helper<R: Read>(i: &mut Input<R>, bsize: usize) -> std::io::Result<(ReadStat, Vec<u8>)> {
|
fn read_helper<R: Read>(
|
||||||
|
i: &mut Input<R>,
|
||||||
|
mut buf: &mut Vec<u8>,
|
||||||
|
bsize: usize,
|
||||||
|
) -> std::io::Result<ReadStat> {
|
||||||
// Local Helper Fns -------------------------------------------------
|
// Local Helper Fns -------------------------------------------------
|
||||||
fn perform_swab(buf: &mut [u8]) {
|
fn perform_swab(buf: &mut [u8]) {
|
||||||
for base in (1..buf.len()).step_by(2) {
|
for base in (1..buf.len()).step_by(2) {
|
||||||
|
@ -609,14 +617,16 @@ fn read_helper<R: Read>(i: &mut Input<R>, bsize: usize) -> std::io::Result<(Read
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// Read
|
// Read
|
||||||
let mut buf = vec![BUF_INIT_BYTE; bsize];
|
// Resize the buffer to the bsize. Any garbage data in the buffer is overwritten or truncated, so there is no need to fill with BUF_INIT_BYTE first.
|
||||||
|
buf.resize(bsize, BUF_INIT_BYTE);
|
||||||
|
|
||||||
let mut rstat = match i.cflags.sync {
|
let mut rstat = match i.cflags.sync {
|
||||||
Some(ch) => i.fill_blocks(&mut buf, ch)?,
|
Some(ch) => i.fill_blocks(&mut buf, ch)?,
|
||||||
_ => i.fill_consecutive(&mut buf)?,
|
_ => i.fill_consecutive(&mut buf)?,
|
||||||
};
|
};
|
||||||
// Return early if no data
|
// Return early if no data
|
||||||
if rstat.reads_complete == 0 && rstat.reads_partial == 0 {
|
if rstat.reads_complete == 0 && rstat.reads_partial == 0 {
|
||||||
return Ok((rstat, buf));
|
return Ok(rstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform any conv=x[,x...] options
|
// Perform any conv=x[,x...] options
|
||||||
|
@ -626,10 +636,10 @@ fn read_helper<R: Read>(i: &mut Input<R>, bsize: usize) -> std::io::Result<(Read
|
||||||
|
|
||||||
match i.cflags.mode {
|
match i.cflags.mode {
|
||||||
Some(ref mode) => {
|
Some(ref mode) => {
|
||||||
let buf = conv_block_unblock_helper(buf, mode, &mut rstat);
|
*buf = conv_block_unblock_helper(buf.clone(), mode, &mut rstat);
|
||||||
Ok((rstat, buf))
|
Ok(rstat)
|
||||||
}
|
}
|
||||||
None => Ok((rstat, buf)),
|
None => Ok(rstat),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue