Skip to content

Commit 3ec7346

Browse files
committed
Use Vec as the underlying store for FilesIndex
1 parent 081797d commit 3ec7346

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

compiler/rustc_session/src/search_paths.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::collections::BTreeMap;
2-
use std::ops::Bound;
31
use std::path::{Path, PathBuf};
42
use std::sync::Arc;
53

@@ -18,36 +16,45 @@ pub struct SearchPath {
1816

1917
/// [FilesIndex] contains paths that can be efficiently looked up with (prefix, suffix) pairs.
2018
#[derive(Clone, Debug)]
21-
pub struct FilesIndex(BTreeMap<Arc<str>, Arc<SearchPathFile>>);
19+
pub struct FilesIndex(Vec<(Arc<str>, SearchPathFile)>);
2220

2321
impl FilesIndex {
2422
/// Look up [SearchPathFile] by (prefix, suffix) pair.
2523
pub fn query<'this, 'prefix, 'suffix>(
2624
&'this self,
2725
prefix: &'prefix str,
2826
suffix: &'suffix str,
29-
) -> Option<impl Iterator<Item = (String, Arc<SearchPathFile>)> + use<'this, 'prefix, 'suffix>>
27+
) -> Option<impl Iterator<Item = (String, &'this SearchPathFile)> + use<'this, 'prefix, 'suffix>>
3028
{
31-
let start = prefix;
32-
let end = format!("{prefix}\u{FFFF}");
33-
let mut ret = self
34-
.0
35-
.range::<str, _>((Bound::Included(start), Bound::Excluded(end.as_str())))
36-
.filter_map(move |(k, v)| {
37-
k.ends_with(suffix).then(|| {
38-
(
39-
String::from(
40-
&v.file_name_str[prefix.len()..v.file_name_str.len() - suffix.len()],
41-
),
42-
Arc::clone(v),
43-
)
44-
})
29+
let start = self.0.partition_point(|(k, _)| {
30+
let k: &str = &k;
31+
k < prefix
32+
});
33+
if start == self.0.len() {
34+
return None;
35+
}
36+
let prefixed_items;
37+
let end = self.0[start..].partition_point(|(k, _)| k.starts_with(prefix));
38+
if end + start == self.0.len() {
39+
prefixed_items = &self.0[start..];
40+
} else {
41+
prefixed_items = &self.0[start..start + end];
42+
}
43+
44+
let ret = prefixed_items.into_iter().filter_map(move |(k, v)| {
45+
k.ends_with(suffix).then(|| {
46+
(
47+
String::from(
48+
&v.file_name_str[prefix.len()..v.file_name_str.len() - suffix.len()],
49+
),
50+
v,
51+
)
4552
})
46-
.peekable();
47-
ret.peek().is_some().then(|| ret)
53+
});
54+
Some(ret)
4855
}
4956
pub fn retain(&mut self, prefixes: &[&str]) {
50-
self.0.retain(|k, _| prefixes.iter().any(|prefix| k.starts_with(prefix)));
57+
self.0.retain(|(k, _)| prefixes.iter().any(|prefix| k.starts_with(prefix)));
5158
}
5259
}
5360
/// The obvious implementation of `SearchPath::files` is a `Vec<PathBuf>`. But
@@ -135,23 +142,24 @@ impl SearchPath {
135142

136143
pub fn new(kind: PathKind, dir: PathBuf) -> Self {
137144
// Get the files within the directory.
138-
let files = match std::fs::read_dir(&dir) {
145+
let mut files = match std::fs::read_dir(&dir) {
139146
Ok(files) => files
140147
.filter_map(|e| {
141148
e.ok().and_then(|e| {
142149
e.file_name().to_str().map(|s| {
143150
let file_name_str: Arc<str> = s.into();
144-
(
145-
Arc::clone(&file_name_str),
146-
Arc::new(SearchPathFile { path: e.path().into(), file_name_str }),
147-
)
151+
(Arc::clone(&file_name_str), SearchPathFile {
152+
path: e.path().into(),
153+
file_name_str,
154+
})
148155
})
149156
})
150157
})
151-
.collect::<BTreeMap<_, _>>(),
158+
.collect::<Vec<_>>(),
152159

153160
Err(..) => Default::default(),
154161
};
162+
files.sort_by(|(lhs, _), (rhs, _)| lhs.cmp(rhs));
155163
let files = FilesIndex(files);
156164
SearchPath { kind, dir, files }
157165
}

0 commit comments

Comments
 (0)