Skip to content

Commit 9bc517d

Browse files
authored
Rollup merge of #129426 - notriddle:smaller-index-2024-08-22, r=GuillaumeGomez
rustdoc-search: use tighter json for names and parents File size --------- ```console $ du -hs doc.old/search-index1.82.0.js doc/search-index1.82.0.js 3.2M doc.old/search-index1.82.0.js 2.8M doc/search-index1.82.0.js $ gzip doc/search-index1.82.0.js $ gzip doc.old/search-index1.82.0.js $ du -hs doc.old/search-index1.82.0.js.gz doc/search-index1.82.0.js.gz 464K doc.old/search-index1.82.0.js.gz 456K doc/search-index1.82.0.js.gz $ du -hs compiler-doc.old/search-index.js compiler-doc/search-index.js 8.5M compiler-doc.old/search-index.js 6.5M compiler-doc/search-index.js $ gzip compiler-doc/search-index1.82.0.js $ gzip compiler-doc.old/search-index1.82.0.js $ du -hs compiler-doc.old/search-index.js.gz compiler-doc/search-index.js.gz 1.4M compiler-doc.old/search-index.js.gz 1.4M compiler-doc/search-index.js.gz ``` Performance ----------- Firefox profile: [before](https://profiler.firefox.com/public/jf1741wycma0n38asdf7kdtw8egs0pqakbr03jg/calltree/?globalTrackOrder=0w3&implementation=js&thread=3&v=10), [after](https://profiler.firefox.com/public/p4fptad7vncsfgrgk9a18yx7m6w8kdpgfy15f8r/calltree/?globalTrackOrder=0w3&implementation=js&thread=3&v=10) CLI profiler scripts comparison: https://notriddle.com/rustdoc-html-demo-9/smaller-index-2024-08-22/index.html | Benchmark | Before | After | % Diff | --------- | ----------:| ----------:| ------: | arti | 225692 KiB | 218744 KiB | 3% | cortex-m | 58276 KiB | 57852 KiB | 0% | sqlx | 123132 KiB | 125448 KiB | -2% | stm32f4 | 556828 KiB | 548996 KiB | 1% | ripgrep | 86964 KiB | 86180 KiB | 1%
2 parents 41b9420 + 8151de2 commit 9bc517d

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

Diff for: src/librustdoc/html/render/search_index.rs

+30-6
Original file line numberDiff line numberDiff line change
@@ -579,12 +579,14 @@ pub(crate) fn build_index<'tcx>(
579579
let mut names = Vec::with_capacity(self.items.len());
580580
let mut types = String::with_capacity(self.items.len());
581581
let mut full_paths = Vec::with_capacity(self.items.len());
582-
let mut parents = Vec::with_capacity(self.items.len());
582+
let mut parents = String::with_capacity(self.items.len());
583+
let mut parents_backref_queue = VecDeque::new();
583584
let mut functions = String::with_capacity(self.items.len());
584585
let mut deprecated = Vec::with_capacity(self.items.len());
585586

586-
let mut backref_queue = VecDeque::new();
587+
let mut type_backref_queue = VecDeque::new();
587588

589+
let mut last_name = None;
588590
for (index, item) in self.items.iter().enumerate() {
589591
let n = item.ty as u8;
590592
let c = char::try_from(n + b'A').expect("item types must fit in ASCII");
@@ -597,17 +599,39 @@ pub(crate) fn build_index<'tcx>(
597599
"`{}` is missing idx",
598600
item.name
599601
);
600-
// 0 is a sentinel, everything else is one-indexed
601-
parents.push(item.parent_idx.map(|x| x + 1).unwrap_or(0));
602+
assert!(
603+
parents_backref_queue.len() <= 16,
604+
"the string encoding only supports 16 slots of lookback"
605+
);
606+
let parent: i32 = item.parent_idx.map(|x| x + 1).unwrap_or(0).try_into().unwrap();
607+
if let Some(idx) = parents_backref_queue.iter().position(|p: &i32| *p == parent) {
608+
parents.push(
609+
char::try_from('0' as u32 + u32::try_from(idx).unwrap())
610+
.expect("last possible value is '?'"),
611+
);
612+
} else if parent == 0 {
613+
write_vlqhex_to_string(parent, &mut parents);
614+
} else {
615+
parents_backref_queue.push_front(parent);
616+
write_vlqhex_to_string(parent, &mut parents);
617+
if parents_backref_queue.len() > 16 {
618+
parents_backref_queue.pop_back();
619+
}
620+
}
602621

603-
names.push(item.name.as_str());
622+
if Some(item.name.as_str()) == last_name {
623+
names.push("");
624+
} else {
625+
names.push(item.name.as_str());
626+
last_name = Some(item.name.as_str());
627+
}
604628

605629
if !item.path.is_empty() {
606630
full_paths.push((index, &item.path));
607631
}
608632

609633
match &item.search_type {
610-
Some(ty) => ty.write_to_string(&mut functions, &mut backref_queue),
634+
Some(ty) => ty.write_to_string(&mut functions, &mut type_backref_queue),
611635
None => functions.push('`'),
612636
}
613637

Diff for: src/librustdoc/html/static/js/search.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -3546,7 +3546,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
35463546
// Used to de-duplicate inlined and re-exported stuff
35473547
const itemReexports = new Map(crateCorpus.r);
35483548
// an array of (Number) the parent path index + 1 to `paths`, or 0 if none
3549-
const itemParentIdxs = crateCorpus.i;
3549+
const itemParentIdxDecoder = new VlqHexDecoder(crateCorpus.i, noop => noop);
35503550
// a map Number, string for impl disambiguators
35513551
const implDisambiguator = new Map(crateCorpus.b);
35523552
// an array of [(Number) item type,
@@ -3593,6 +3593,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
35933593
// faster analysis operations
35943594
lastPath = "";
35953595
len = itemTypes.length;
3596+
let lastName = "";
3597+
let lastWord = "";
35963598
for (let i = 0; i < len; ++i) {
35973599
const bitIndex = i + 1;
35983600
if (descIndex >= descShard.len &&
@@ -3608,10 +3610,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
36083610
descIndex = 0;
36093611
descShardList.push(descShard);
36103612
}
3611-
let word = "";
3612-
if (typeof itemNames[i] === "string") {
3613-
word = itemNames[i].toLowerCase();
3614-
}
3613+
const name = itemNames[i] === "" ? lastName : itemNames[i];
3614+
const word = itemNames[i] === "" ? lastWord : itemNames[i].toLowerCase();
36153615
const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath;
36163616
const type = itemFunctionDecoder.next();
36173617
if (type !== null) {
@@ -3633,15 +3633,16 @@ ${item.displayPath}<span class="${type}">${name}</span>\
36333633
}
36343634
// This object should have exactly the same set of fields as the "crateRow"
36353635
// object defined above.
3636+
const itemParentIdx = itemParentIdxDecoder.next();
36363637
const row = {
36373638
crate,
36383639
ty: itemTypes.charCodeAt(i) - 65, // 65 = "A"
3639-
name: itemNames[i],
3640+
name,
36403641
path,
36413642
descShard,
36423643
descIndex,
36433644
exactPath: itemReexports.has(i) ? itemPaths.get(itemReexports.get(i)) : path,
3644-
parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined,
3645+
parent: itemParentIdx > 0 ? paths[itemParentIdx - 1] : undefined,
36453646
type,
36463647
id,
36473648
word,
@@ -3655,6 +3656,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
36553656
if (!searchIndexEmptyDesc.get(crate).contains(bitIndex)) {
36563657
descIndex += 1;
36573658
}
3659+
lastName = name;
3660+
lastWord = word;
36583661
}
36593662

36603663
if (aliases) {

0 commit comments

Comments
 (0)