diff options
| author | Michael Howell <michael@notriddle.com> | 2021-03-10 19:31:49 -0700 |
|---|---|---|
| committer | Michael Howell <michael@notriddle.com> | 2021-03-10 20:20:42 -0700 |
| commit | 3934dd1b3e7514959202de6ca0d2636bcae21830 (patch) | |
| tree | 7fbf782e112d17e18477bd09ffff4604f8646bc5 /src/librustdoc/html/render | |
| parent | f98721f886ab52d32d622ad0a46216ad03f3e525 (diff) | |
| download | rust-3934dd1b3e7514959202de6ca0d2636bcae21830.tar.gz rust-3934dd1b3e7514959202de6ca0d2636bcae21830.zip | |
rustdoc: tweak the search index format
This essentially switches search-index.js from a "array of struct"
to a "struct of array" format, like this:
{
"doc": "Crate documentation",
"t": [ 1, 1, 2, 3, ... ],
"n": [ "Something", "SomethingElse", "whatever", "do_stuff", ... ],
"q": [ "a::b", "", "", "", ... ],
"d": [ "A Struct That Does Something", "Another Struct", "a function", "another function", ... ],
"i": [ 0, 0, 1, 1, ... ],
"f": [ null, null, [], [], ... ],
"p": ...,
"a": ...
}
So `{ty: 1, name: "Something", path: "a::b", desc: "A Struct That Does Something", parent_idx: 0, search_type: null}` is the first item.
This makes the uncompressed version smaller, but it really shows on the
compressed version:
notriddle:rust$ wc -c new-search-index1.52.0.js
2622427 new-search-index1.52.0.js
notriddle:rust$ wc -c old-search-index1.52.0.js
2725046 old-search-index1.52.0.js
notriddle:rust$ gzip new-search-index1.52.0.js
notriddle:rust$ gzip old-search-index1.52.0.js
notriddle:rust$ wc -c new-search-index1.52.0.js.gz
239385 new-search-index1.52.0.js.gz
notriddle:rust$ wc -c old-search-index1.52.0.js.gz
296328 old-search-index1.52.0.js.gz
notriddle:rust$
That's a 4% improvement on the uncompressed version (fewer `[]`),
and 20% improvement after gzipping it, thanks to putting like-typed
data next to each other. Any compression algorithm based on a sliding
window will probably show this kind of improvement.
Diffstat (limited to 'src/librustdoc/html/render')
| -rw-r--r-- | src/librustdoc/html/render/cache.rs | 60 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 17 |
2 files changed, 54 insertions, 23 deletions
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index a21cf5266fe..56fee2c9fec 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -4,7 +4,7 @@ use std::path::Path; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{sym, Symbol}; -use serde::Serialize; +use serde::ser::{Serialize, SerializeStruct, Serializer}; use crate::clean::types::{ FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, TypeKind, WherePredicate, @@ -133,21 +133,69 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< .map(|module| module.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s))) .unwrap_or_default(); - #[derive(Serialize)] struct CrateData<'a> { doc: String, - #[serde(rename = "i")] items: Vec<&'a IndexItem>, - #[serde(rename = "p")] paths: Vec<(ItemType, String)>, // The String is alias name and the vec is the list of the elements with this alias. // // To be noted: the `usize` elements are indexes to `items`. - #[serde(rename = "a")] - #[serde(skip_serializing_if = "BTreeMap::is_empty")] aliases: &'a BTreeMap<String, Vec<usize>>, } + impl<'a> Serialize for CrateData<'a> { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let has_aliases = !self.aliases.is_empty(); + let mut crate_data = + serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?; + crate_data.serialize_field("doc", &self.doc)?; + crate_data.serialize_field( + "t", + &self.items.iter().map(|item| &item.ty).collect::<Vec<_>>(), + )?; + crate_data.serialize_field( + "n", + &self.items.iter().map(|item| &item.name).collect::<Vec<_>>(), + )?; + crate_data.serialize_field( + "q", + &self.items.iter().map(|item| &item.path).collect::<Vec<_>>(), + )?; + crate_data.serialize_field( + "d", + &self.items.iter().map(|item| &item.desc).collect::<Vec<_>>(), + )?; + crate_data.serialize_field( + "i", + &self + .items + .iter() + .map(|item| { + assert_eq!( + item.parent.is_some(), + item.parent_idx.is_some(), + "`{}` is missing idx", + item.name + ); + item.parent_idx.map(|x| x + 1).unwrap_or(0) + }) + .collect::<Vec<_>>(), + )?; + crate_data.serialize_field( + "f", + &self.items.iter().map(|item| &item.search_type).collect::<Vec<_>>(), + )?; + crate_data.serialize_field("p", &self.paths)?; + if has_aliases { + crate_data.serialize_field("a", &self.aliases)?; + } + crate_data.end() + } + } + // Collect the index into a string format!( r#""{}":{}"#, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index a4621fb8ed5..66c47f14655 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -166,23 +166,6 @@ crate struct IndexItem { crate search_type: Option<IndexItemFunctionType>, } -impl Serialize for IndexItem { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - assert_eq!( - self.parent.is_some(), - self.parent_idx.is_some(), - "`{}` is missing idx", - self.name - ); - - (self.ty, &self.name, &self.path, &self.desc, self.parent_idx, &self.search_type) - .serialize(serializer) - } -} - /// A type used for the search index. #[derive(Debug)] crate struct RenderType { |
