Skip to content

Commit 5c40b7f

Browse files
committed
Auto merge of #8937 - alexcrichton:optimize-vendor-a-bit, r=Eh2406
Slightly optimize `cargo vendor` I've noticed recently that `cargo vendor` feels really sluggish and slow, and apparently this is primarily because we delete the registry caches and re-extract all the tarballs. This commit implements one possible optimization without changing this, however, which is that currently we both copy a file and checksum it, but that ends up reading all the contents twice. Those two functions are now folded into one, shaving about 3s locally from Cargo's own vendor times.
2 parents 78beb37 + 01f1c01 commit 5c40b7f

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/cargo/ops/vendor.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use serde::Serialize;
99
use std::collections::HashSet;
1010
use std::collections::{BTreeMap, BTreeSet, HashMap};
1111
use std::fs;
12+
use std::fs::File;
13+
use std::io::{Read, Write};
1214
use std::path::{Path, PathBuf};
1315

1416
pub struct VendorOptions<'a> {
@@ -182,6 +184,7 @@ fn sync(
182184
}
183185

184186
let mut sources = BTreeSet::new();
187+
let mut tmp_buf = [0; 64 * 1024];
185188
for (id, pkg) in ids.iter() {
186189
// Next up, copy it to the vendor directory
187190
let src = pkg
@@ -216,7 +219,7 @@ fn sync(
216219
let pathsource = PathSource::new(src, id.source_id(), config);
217220
let paths = pathsource.list_files(pkg)?;
218221
let mut map = BTreeMap::new();
219-
cp_sources(src, &paths, &dst, &mut map)
222+
cp_sources(src, &paths, &dst, &mut map, &mut tmp_buf)
220223
.chain_err(|| format!("failed to copy over vendored sources for: {}", id))?;
221224

222225
// Finally, emit the metadata about this package
@@ -299,6 +302,7 @@ fn cp_sources(
299302
paths: &[PathBuf],
300303
dst: &Path,
301304
cksums: &mut BTreeMap<String, String>,
305+
tmp_buf: &mut [u8],
302306
) -> CargoResult<()> {
303307
for p in paths {
304308
let relative = p.strip_prefix(&src).unwrap();
@@ -334,9 +338,27 @@ fn cp_sources(
334338

335339
paths::create_dir_all(dst.parent().unwrap())?;
336340

337-
paths::copy(&p, &dst)?;
338-
let cksum = Sha256::new().update_path(dst)?.finish_hex();
341+
let cksum = copy_and_checksum(&p, &dst, tmp_buf)?;
339342
cksums.insert(relative.to_str().unwrap().replace("\\", "/"), cksum);
340343
}
341344
Ok(())
342345
}
346+
347+
fn copy_and_checksum(src_path: &Path, dst_path: &Path, buf: &mut [u8]) -> CargoResult<String> {
348+
let mut src = File::open(src_path).chain_err(|| format!("failed to open {:?}", src_path))?;
349+
let mut dst =
350+
File::create(dst_path).chain_err(|| format!("failed to create {:?}", dst_path))?;
351+
let mut cksum = Sha256::new();
352+
loop {
353+
let n = src
354+
.read(buf)
355+
.chain_err(|| format!("failed to read from {:?}", src_path))?;
356+
if n == 0 {
357+
break Ok(cksum.finish_hex());
358+
}
359+
let data = &buf[..n];
360+
cksum.update(data);
361+
dst.write_all(data)
362+
.chain_err(|| format!("failed to write to {:?}", dst_path))?;
363+
}
364+
}

0 commit comments

Comments
 (0)