Rollup merge of #71250 - GuillaumeGomez:use-json-instead-of-js, r=kinnison
Replace big JS dict with JSON parsing Part of #56545. @ollie27 suggested that using JSON instead of a JS dict might be faster, so I decided to test it. And the results far exceeded whatever expectations I had... I used https://github.com/adamgreig/stm32ral for my tests. If you want to build it locally: ```bash $ cargo doc --features doc --open ``` But I strongly recommend to do it with this PR. Some numbers: * Loading a page with the JSON search-index: less than 1 second * Loading a page with the JS search-index: crashed after 30 seconds I think the results are clear enough... r? @ollie27 cc @rust-lang/rustdoc
This commit is contained in:
commit
2f06ac08e9
@ -789,6 +789,37 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
Ok((ret, krates))
|
||||
}
|
||||
|
||||
fn collect_json(path: &Path, krate: &str) -> io::Result<(Vec<String>, Vec<String>)> {
|
||||
let mut ret = Vec::new();
|
||||
let mut krates = Vec::new();
|
||||
|
||||
if path.exists() {
|
||||
for line in BufReader::new(File::open(path)?).lines() {
|
||||
let line = line?;
|
||||
if !line.starts_with("\"") {
|
||||
continue;
|
||||
}
|
||||
if line.starts_with(&format!("\"{}\"", krate)) {
|
||||
continue;
|
||||
}
|
||||
if line.ends_with(",\\") {
|
||||
ret.push(line[..line.len() - 2].to_string());
|
||||
} else {
|
||||
// Ends with "\\" (it's the case for the last added crate line)
|
||||
ret.push(line[..line.len() - 1].to_string());
|
||||
}
|
||||
krates.push(
|
||||
line.split('"')
|
||||
.filter(|s| !s.is_empty())
|
||||
.next()
|
||||
.map(|s| s.to_owned())
|
||||
.unwrap_or_else(String::new),
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok((ret, krates))
|
||||
}
|
||||
|
||||
fn show_item(item: &IndexItem, krate: &str) -> String {
|
||||
format!(
|
||||
"{{'crate':'{}','ty':{},'name':'{}','desc':'{}','p':'{}'{}}}",
|
||||
@ -909,18 +940,18 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
|
||||
// Update the search index
|
||||
let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix));
|
||||
let (mut all_indexes, mut krates) = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
|
||||
let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name), &dst);
|
||||
all_indexes.push(search_index);
|
||||
|
||||
// Sort the indexes by crate so the file will be generated identically even
|
||||
// with rustdoc running in parallel.
|
||||
all_indexes.sort();
|
||||
{
|
||||
let mut v = String::from("var searchIndex={};\n");
|
||||
v.push_str(&all_indexes.join("\n"));
|
||||
let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
|
||||
v.push_str(&all_indexes.join(",\\\n"));
|
||||
// "addSearchOptions" has to be called first so the crate filtering can be set before the
|
||||
// search might start (if it's set into the URL for example).
|
||||
v.push_str("\naddSearchOptions(searchIndex);initSearch(searchIndex);");
|
||||
v.push_str("\\\n}');\naddSearchOptions(searchIndex);initSearch(searchIndex);");
|
||||
cx.shared.fs.write(&dst, &v)?;
|
||||
}
|
||||
if options.enable_index_page {
|
||||
|
@ -634,7 +634,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
|
||||
|
||||
// Collect the index into a string
|
||||
format!(
|
||||
r#"searchIndex["{}"] = {};"#,
|
||||
r#""{}":{}"#,
|
||||
krate.name,
|
||||
serde_json::to_string(&CrateData {
|
||||
doc: crate_doc,
|
||||
@ -642,6 +642,11 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
|
||||
paths: crate_paths,
|
||||
})
|
||||
.expect("failed serde conversion")
|
||||
// All these `replace` calls are because we have to go through JS string for JSON content.
|
||||
.replace(r"\", r"\\")
|
||||
.replace("'", r"\'")
|
||||
// We need to escape double quotes for the JSON.
|
||||
.replace("\\\"", "\\\\\"")
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user