Skip to content

Commit

Permalink
Avoid quadratic complexity when splitting output into lines
Browse files Browse the repository at this point in the history
When searching for newlines in a process output keep track which part of
buffer was already examined to avoid processing the same data again and
again.
  • Loading branch information
tmiasko committed Jun 18, 2021
1 parent 9f60fca commit 8df771f
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions crates/cargo-util/src/process_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,27 @@ impl ProcessBuilder {
.stdin(Stdio::null());

let mut callback_error = None;
let mut stdout_pos = 0;
let mut stderr_pos = 0;
let status = (|| {
let mut child = cmd.spawn()?;
let out = child.stdout.take().unwrap();
let err = child.stderr.take().unwrap();
read2(out, err, &mut |is_out, data, eof| {
let pos = if is_out {
&mut stdout_pos
} else {
&mut stderr_pos
};
let idx = if eof {
data.len()
} else {
match data.iter().rposition(|b| *b == b'\n') {
Some(i) => i + 1,
None => return,
match data[*pos..].iter().rposition(|b| *b == b'\n') {
Some(i) => *pos + i + 1,
None => {
*pos = data.len();
return;
}
}
};

Expand All @@ -280,6 +290,7 @@ impl ProcessBuilder {
}

data.drain(..idx);
*pos = 0;
})?;
child.wait()
})()
Expand Down

0 comments on commit 8df771f

Please sign in to comment.