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();
|
||||
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.
|
||||
//
|
||||
// Each iteration reads blocks from the input and writes
|
||||
|
@ -427,7 +431,7 @@ where
|
|||
// best buffer size for reading based on the number of
|
||||
// blocks already read and the number of blocks remaining.
|
||||
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() {
|
||||
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.
|
||||
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 -------------------------------------------------
|
||||
fn perform_swab(buf: &mut [u8]) {
|
||||
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
|
||||
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 {
|
||||
Some(ch) => i.fill_blocks(&mut buf, ch)?,
|
||||
_ => i.fill_consecutive(&mut buf)?,
|
||||
};
|
||||
// Return early if no data
|
||||
if rstat.reads_complete == 0 && rstat.reads_partial == 0 {
|
||||
return Ok((rstat, buf));
|
||||
return Ok(rstat);
|
||||
}
|
||||
|
||||
// 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 {
|
||||
Some(ref mode) => {
|
||||
let buf = conv_block_unblock_helper(buf, mode, &mut rstat);
|
||||
Ok((rstat, buf))
|
||||
*buf = conv_block_unblock_helper(buf.clone(), mode, &mut rstat);
|
||||
Ok(rstat)
|
||||
}
|
||||
None => Ok((rstat, buf)),
|
||||
None => Ok(rstat),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue