(args: &[String], results: &mut Vec<QueryResult>)
| 173 | } |
| 174 | |
| 175 | fn run_query(args: &[String], results: &mut Vec<QueryResult>) -> Result<()> { |
| 176 | let exec_path = &args[0]; |
| 177 | let exec_args = &args[1..]; |
| 178 | |
| 179 | let mut child = Command::new(exec_path) |
| 180 | .args(exec_args) |
| 181 | .stdout(Stdio::piped()) |
| 182 | .spawn() |
| 183 | .expect("Failed to start benchmark"); |
| 184 | |
| 185 | let stdout = child.stdout.take().unwrap(); |
| 186 | let reader = BufReader::new(stdout); |
| 187 | |
| 188 | // Buffer child's stdout |
| 189 | let lines: Result<Vec<String>, std::io::Error> = |
| 190 | reader.lines().collect::<Result<_, _>>(); |
| 191 | |
| 192 | child |
| 193 | .wait() |
| 194 | .expect("Benchmark process exited with an error"); |
| 195 | |
| 196 | // Parse after child process terminates |
| 197 | let lines = lines?; |
| 198 | let mut iter = lines.iter().peekable(); |
| 199 | |
| 200 | // Look for lines that contain execution time / memory stats |
| 201 | while let Some(line) = iter.next() { |
| 202 | if let Some((query, duration_ms)) = parse_query_time(line) |
| 203 | && let Some(next_line) = iter.peek() |
| 204 | && let Some((peak_rss, peak_commit, page_faults)) = parse_vm_line(next_line) |
| 205 | { |
| 206 | results.push(QueryResult { |
| 207 | query, |
| 208 | duration_ms, |
| 209 | peak_rss, |
| 210 | peak_commit, |
| 211 | page_faults, |
| 212 | }); |
| 213 | break; |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | Ok(()) |
| 218 | } |
| 219 | |
| 220 | #[derive(Debug)] |
| 221 | struct QueryResult { |
no test coverage detected
searching dependent graphs…