From 115df577573ffba1534e9d04bc7b131bf32cffe8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 16 Jun 2018 20:44:55 +0200 Subject: [PATCH] reduce search-index size --- src/librustdoc/html/render.rs | 39 ++++++++++++++++--------- src/librustdoc/html/static/main.js | 46 ++++++++++++++++++------------ src/tools/rustdoc-js/tester.js | 1 + 3 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 130451d07af86..e4afb9ae54b8a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -414,13 +414,13 @@ impl ToJson for Type { fn to_json(&self) -> Json { match self.name { Some(ref name) => { - let mut data = BTreeMap::new(); - data.insert("n".to_owned(), name.to_json()); + let mut data = Vec::with_capacity(2); + data.push(name.to_json()); if let Some(ref generics) = self.generics { - data.insert("g".to_owned(), generics.to_json()); + data.push(generics.to_json()); } - Json::Object(data) - }, + Json::Array(data) + } None => Json::Null } } @@ -439,14 +439,12 @@ impl ToJson for IndexItemFunctionType { if self.inputs.iter().chain(self.output.iter()).any(|ref i| i.name.is_none()) { Json::Null } else { - let mut data = BTreeMap::new(); - if !self.inputs.is_empty() { - data.insert("i".to_owned(), self.inputs.to_json()); - } + let mut data = Vec::with_capacity(2); + data.push(self.inputs.to_json()); if let Some(ref output) = self.output { - data.insert("o".to_owned(), output.to_json()); + data.push(output.to_json()); } - Json::Object(data) + Json::Array(data) } } } @@ -963,9 +961,11 @@ themePicker.onblur = handleThemeButtonsBlur; // with rustdoc running in parallel. all_indexes.sort(); let mut w = try_err!(File::create(&dst), &dst); - try_err!(writeln!(&mut w, "var searchIndex = {{}};"), &dst); + try_err!(writeln!(&mut w, "var N = null;var searchIndex = {{}};"), &dst); for index in &all_indexes { - try_err!(writeln!(&mut w, "{}", *index), &dst); + try_err!(write_minify_replacer(&mut w, &*index, enable_minification, + &[(minifier::js::Keyword::Null, "N")]), + &dst); } try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst); @@ -1076,6 +1076,19 @@ fn write_minify(dst: PathBuf, contents: &str, enable_minification: bool) -> Resu } } +fn write_minify_replacer(dst: &mut W, + contents: &str, + enable_minification: bool, + keywords_to_replace: &[(minifier::js::Keyword, &str)]) + -> io::Result<()> { + if enable_minification { + writeln!(dst, "{}", + minifier::js::minify_and_replace_keywords(contents, keywords_to_replace)) + } else { + writeln!(dst, "{}", contents) + } +} + /// Takes a path to a source file and cleans the path to it. This canonicalizes /// things like ".." to components which preserve the "top down" hierarchy of a /// static HTML tree. Each component in the cleaned path will be passed as an diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 01eb1ce7407be..f3c9ce424106d 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -415,6 +415,10 @@ var currentResults, index, searchIndex; var MAX_LEV_DISTANCE = 3; var MAX_RESULTS = 200; + var GENERICS_DATA = 1; + var NAME = 0; + var INPUTS_DATA = 0; + var OUTPUT_DATA = 1; var params = getQueryStringParams(); // Populate search bar with query string search term when provided, @@ -603,8 +607,9 @@ // match as well. var lev_distance = MAX_LEV_DISTANCE + 1; if (val.generics.length > 0) { - if (obj.g && obj.g.length >= val.generics.length) { - var elems = obj.g.slice(0); + if (obj.length > GENERICS_DATA && + obj[GENERICS_DATA].length >= val.generics.length) { + var elems = obj[GENERICS_DATA].slice(0); var total = 0; var done = 0; // We need to find the type that matches the most to remove it in order @@ -636,11 +641,12 @@ // Check for type name and type generics (if any). function checkType(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - if (obj.n === val.name) { + if (obj[NAME] === val.name) { if (literalSearch === true) { if (val.generics && val.generics.length !== 0) { - if (obj.g && obj.length >= val.generics.length) { - var elems = obj.g.slice(0); + if (obj.length > GENERICS_DATA && + obj[GENERICS_DATA].length >= val.generics.length) { + var elems = obj[GENERICS_DATA].slice(0); var allFound = true; var x; @@ -664,7 +670,7 @@ } // If the type has generics but don't match, then it won't return at this point. // Otherwise, `checkGenerics` will return 0 and it'll return. - if (obj.g && obj.g.length !== 0) { + if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) { var tmp_lev = checkGenerics(obj, val); if (tmp_lev <= MAX_LEV_DISTANCE) { return tmp_lev; @@ -675,22 +681,23 @@ } // Names didn't match so let's check if one of the generic types could. if (literalSearch === true) { - if (obj.g && obj.g.length > 0) { - for (var x = 0; x < obj.g.length; ++x) { - if (obj.g[x] === val.name) { + if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { + for (var x = 0; x < obj[GENERICS_DATA].length; ++x) { + if (obj[GENERICS_DATA][x] === val.name) { return true; } } } return false; } - var lev_distance = Math.min(levenshtein(obj.n, val.name), lev_distance); + var lev_distance = Math.min(levenshtein(obj[NAME], val.name), + lev_distance); if (lev_distance <= MAX_LEV_DISTANCE) { lev_distance = Math.min(checkGenerics(obj, val), lev_distance); - } else if (obj.g && obj.g.length > 0) { + } else if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { // We can check if the type we're looking for is inside the generics! - for (var x = 0; x < obj.g.length; ++x) { - lev_distance = Math.min(levenshtein(obj.g[x], val.name), + for (var x = 0; x < obj[GENERICS_DATA].length; ++x) { + lev_distance = Math.min(levenshtein(obj[GENERICS_DATA][x], val.name), lev_distance); } } @@ -702,9 +709,10 @@ function findArg(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - if (obj && obj.type && obj.type.i && obj.type.i.length > 0) { - for (var i = 0; i < obj.type.i.length; i++) { - var tmp = checkType(obj.type.i[i], val, literalSearch); + if (obj && obj.type && obj.type[INPUTS_DATA] && + obj.type[INPUTS_DATA].length > 0) { + for (var i = 0; i < obj.type[INPUTS_DATA].length; i++) { + var tmp = checkType(obj.type[INPUTS_DATA][i], val, literalSearch); if (literalSearch === true && tmp === true) { return true; } @@ -720,8 +728,8 @@ function checkReturned(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - if (obj && obj.type && obj.type.o) { - var tmp = checkType(obj.type.o, val, literalSearch); + if (obj && obj.type && obj.type.length > OUTPUT_DATA) { + var tmp = checkType(obj.type[OUTPUT_DATA], val, literalSearch); if (literalSearch === true && tmp === true) { return true; } @@ -866,7 +874,7 @@ var fullId = generateId(ty); // allow searching for void (no output) functions as well - var typeOutput = type.o ? type.o.name : ""; + var typeOutput = type.length > OUTPUT_DATA ? type[OUTPUT_DATA].name : ""; var returned = checkReturned(ty, output, true); if (output.name === "*" || returned === true) { var in_args = false; diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 3c1fceaf8faa8..c8ce4cf8bb5be 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -233,6 +233,7 @@ function main(argv) { var arraysToLoad = ["itemTypes"]; var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", + "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA", "TY_PRIMITIVE", "TY_KEYWORD", "levenshtein_row2"]; // execQuery first parameter is built in getQuery (which takes in the search input).