Skip to content

Commit dc2015c

Browse files
committed
rustdoc-search: sort typ-based inverted indexes by length
This gives us incremental search results back for types, so type-based search feels faster even for queries with lots of matches.
1 parent ed454bf commit dc2015c

File tree

7 files changed

+468
-209
lines changed

7 files changed

+468
-209
lines changed

src/librustdoc/html/render/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ struct RenderType {
151151
}
152152

153153
impl RenderType {
154+
fn size(&self) -> usize {
155+
let mut size = 1;
156+
if let Some(generics) = &self.generics {
157+
size += generics.iter().map(RenderType::size).sum::<usize>();
158+
}
159+
if let Some(bindings) = &self.bindings {
160+
for (_, constraints) in bindings.iter() {
161+
size += 1;
162+
size += constraints.iter().map(RenderType::size).sum::<usize>();
163+
}
164+
}
165+
size
166+
}
154167
// Types are rendered as lists of lists, because that's pretty compact.
155168
// The contents of the lists are always integers in self-terminating hex
156169
// form, handled by `RenderTypeId::write_to_string`, so no commas are
@@ -296,6 +309,15 @@ pub(crate) struct IndexItemFunctionType {
296309
}
297310

298311
impl IndexItemFunctionType {
312+
fn size(&self) -> usize {
313+
self.inputs.iter().map(RenderType::size).sum::<usize>()
314+
+ self.output.iter().map(RenderType::size).sum::<usize>()
315+
+ self
316+
.where_clause
317+
.iter()
318+
.map(|constraints| constraints.iter().map(RenderType::size).sum::<usize>())
319+
.sum::<usize>()
320+
}
299321
fn read_from_string_without_param_names(string: &[u8]) -> (IndexItemFunctionType, usize) {
300322
let mut i = 0;
301323
if string[i] == b'`' {

src/librustdoc/html/render/search_index.rs

Lines changed: 148 additions & 94 deletions
Large diffs are not rendered by default.

src/librustdoc/html/render/search_index/encode.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,51 @@ pub fn read_signed_vlqhex_from_string(string: &[u8]) -> Option<(i32, usize)> {
5050
}
5151
None
5252
}
53+
54+
pub fn write_postings_to_string(postings: &[Vec<u32>], buf: &mut Vec<u8>) {
55+
for list in postings {
56+
if list.is_empty() {
57+
buf.push(0);
58+
continue;
59+
}
60+
let len_before = buf.len();
61+
stringdex::internals::encode::write_bitmap_to_bytes(&list, &mut *buf).unwrap();
62+
let len_after = buf.len();
63+
if len_after - len_before > 1 + (4 * list.len()) && list.len() < 0x3a {
64+
buf.truncate(len_before);
65+
buf.push(list.len() as u8);
66+
for &item in list {
67+
buf.push(item as u8);
68+
buf.push((item >> 8) as u8);
69+
buf.push((item >> 16) as u8);
70+
buf.push((item >> 24) as u8);
71+
}
72+
}
73+
}
74+
}
75+
76+
pub fn read_postings_from_string(postings: &mut Vec<Vec<u32>>, mut buf: &[u8]) {
77+
use stringdex::internals::decode::RoaringBitmap;
78+
while let Some(&c) = buf.get(0) {
79+
if c < 0x3a {
80+
buf = &buf[1..];
81+
let mut slot = Vec::new();
82+
for _ in 0..c {
83+
slot.push(
84+
(buf[0] as u32)
85+
| ((buf[1] as u32) << 8)
86+
| ((buf[2] as u32) << 16)
87+
| ((buf[3] as u32) << 24),
88+
);
89+
buf = &buf[4..];
90+
}
91+
postings.push(slot);
92+
} else {
93+
let (bitmap, consumed_bytes_len) =
94+
RoaringBitmap::from_bytes(buf).unwrap_or_else(|| (RoaringBitmap::default(), 0));
95+
assert_ne!(consumed_bytes_len, 0);
96+
postings.push(bitmap.to_vec());
97+
buf = &buf[consumed_bytes_len..];
98+
}
99+
}
100+
}

src/librustdoc/html/static/js/rustdoc.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ declare namespace rustdoc {
264264
*/
265265
interface TypeData {
266266
searchUnbox: boolean,
267-
invertedFunctionSignatureIndex: RoaringBitmap,
267+
invertedFunctionSignatureIndex: RoaringBitmap[],
268268
}
269269

270270
/**

0 commit comments

Comments
 (0)