1
Fork 0

Rollup merge of #93608 - nnethercote:speed-up-find_library_crate, r=petrochenkov

Clean up `find_library_crate`

Some clean-ups.

r? `@petrochenkov`
This commit is contained in:
Matthias Krüger 2022-02-04 18:42:16 +01:00 committed by GitHub
commit 9b7f1f5649
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 90 deletions

View file

@ -1,13 +1,11 @@
//! A module for searching for libraries
pub use self::FileMatch::*;
use std::env;
use std::fs;
use std::iter::FromIterator;
use std::path::{Path, PathBuf};
use crate::search_paths::{PathKind, SearchPath, SearchPathFile};
use crate::search_paths::{PathKind, SearchPath};
use rustc_fs_util::fix_windows_verbatim_for_gcc;
use tracing::debug;
@ -43,36 +41,6 @@ impl<'a> FileSearch<'a> {
self.get_lib_path().join("self-contained")
}
pub fn search<F>(&self, mut pick: F)
where
F: FnMut(&SearchPathFile, PathKind) -> FileMatch,
{
for search_path in self.search_paths() {
debug!("searching {}", search_path.dir.display());
fn is_rlib(spf: &SearchPathFile) -> bool {
if let Some(f) = &spf.file_name_str { f.ends_with(".rlib") } else { false }
}
// Reading metadata out of rlibs is faster, and if we find both
// an rlib and a dylib we only read one of the files of
// metadata, so in the name of speed, bring all rlib files to
// the front of the search list.
let files1 = search_path.files.iter().filter(|spf| is_rlib(&spf));
let files2 = search_path.files.iter().filter(|spf| !is_rlib(&spf));
for spf in files1.chain(files2) {
debug!("testing {}", spf.path.display());
let maybe_picked = pick(spf, search_path.kind);
match maybe_picked {
FileMatches => {
debug!("picked {}", spf.path.display());
}
FileDoesntMatch => {
debug!("rejected {}", spf.path.display());
}
}
}
}
}
pub fn new(
sysroot: &'a Path,
triple: &'a str,

View file

@ -15,22 +15,15 @@ pub struct SearchPath {
/// doable, but very slow, because it involves calls to `file_name` and
/// `extension` that are themselves slow.
///
/// This type augments the `PathBuf` with an `Option<String>` containing the
/// This type augments the `PathBuf` with an `String` containing the
/// `PathBuf`'s filename. The prefix and suffix checking is much faster on the
/// `Option<String>` than the `PathBuf`. (It's an `Option` because
/// `Path::file_name` can fail; if that happens then all subsequent checking
/// will also fail, which is fine.)
/// `String` than the `PathBuf`. (The filename must be valid UTF-8. If it's
/// not, the entry should be skipped, because all Rust output files are valid
/// UTF-8, and so a non-UTF-8 filename couldn't be one we're looking for.)
#[derive(Clone, Debug)]
pub struct SearchPathFile {
pub path: PathBuf,
pub file_name_str: Option<String>,
}
impl SearchPathFile {
fn new(path: PathBuf) -> SearchPathFile {
let file_name_str = path.file_name().and_then(|f| f.to_str()).map(|s| s.to_string());
SearchPathFile { path, file_name_str }
}
pub file_name_str: String,
}
#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, Encodable, Decodable)]
@ -85,7 +78,14 @@ impl SearchPath {
// Get the files within the directory.
let files = match std::fs::read_dir(&dir) {
Ok(files) => files
.filter_map(|e| e.ok().map(|e| SearchPathFile::new(e.path())))
.filter_map(|e| {
e.ok().and_then(|e| {
e.file_name().to_str().map(|s| SearchPathFile {
path: e.path(),
file_name_str: s.to_string(),
})
})
})
.collect::<Vec<_>>(),
Err(..) => vec![],
};