Skip to content

Commit 8ca1590

Browse files
committed
Explicitly yield while building index every 256 items
1 parent c364dd9 commit 8ca1590

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

src/librustdoc/html/static/js/search.js

+26-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// ignore-tidy-filelength
2-
/* global addClass, getNakedUrl, getSettingValue */
2+
/* global addClass, getNakedUrl, getSettingValue, getVar */
33
/* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi, exports */
44

55
"use strict";
@@ -1298,7 +1298,7 @@ class NameTrie {
12981298
}
12991299

13001300
class DocSearch {
1301-
constructor(rawSearchIndex, rootPath, searchState) {
1301+
constructor(rootPath, searchState) {
13021302
/**
13031303
* @type {Map<String, RoaringBitmap>}
13041304
*/
@@ -1417,7 +1417,7 @@ class DocSearch {
14171417
/**
14181418
* @type {Array<Row>}
14191419
*/
1420-
this.searchIndex = this.buildIndex(rawSearchIndex);
1420+
this.searchIndex = [];
14211421
}
14221422

14231423
/**
@@ -1695,7 +1695,7 @@ class DocSearch {
16951695
*
16961696
* @param {[string, RawSearchIndexCrate][]} rawSearchIndex
16971697
*/
1698-
buildIndex(rawSearchIndex) {
1698+
async buildIndex(rawSearchIndex) {
16991699
/**
17001700
* Convert from RawFunctionSearchType to FunctionSearchType.
17011701
*
@@ -1903,6 +1903,20 @@ class DocSearch {
19031903
paths[i] = { ty, name, path, exactPath, unboxFlag };
19041904
}
19051905

1906+
// Throttlers are used to yield to the JavaScript event loop
1907+
// while this is being built.
1908+
// They're generated up-front to avoid the "nesting level"
1909+
// limit that limits our speed to 4ms per tick.
1910+
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html
1911+
const throttlers = [];
1912+
len = itemTypes.length;
1913+
for (let i = 0; i < len; ++i) {
1914+
if ((i & 0xFF) === 0) { // 256 - 1
1915+
throttlers.push(new Promise(resolve => {
1916+
setTimeout(resolve, 0);
1917+
}));
1918+
}
1919+
}
19061920
// convert `item*` into an object form, and construct word indices.
19071921
//
19081922
// before any analysis is performed lets gather the search terms to
@@ -1915,6 +1929,9 @@ class DocSearch {
19151929
let lastName = "";
19161930
let lastWord = "";
19171931
for (let i = 0; i < len; ++i) {
1932+
if ((i & 0xFF) === 0) { // 256 - 1
1933+
await throttlers[i >> 8];
1934+
}
19181935
const bitIndex = i + 1;
19191936
if (descIndex >= descShard.len &&
19201937
!this.searchIndexEmptyDesc.get(crate).contains(bitIndex)) {
@@ -4864,17 +4881,19 @@ function updateCrate(ev) {
48644881
search(true);
48654882
}
48664883

4867-
function initSearch(searchIndx) {
4884+
async function initSearch(searchIndx) {
48684885
rawSearchIndex = searchIndx;
48694886
if (typeof window !== "undefined") {
4870-
docSearch = new DocSearch(rawSearchIndex, ROOT_PATH, searchState);
4887+
docSearch = new DocSearch(ROOT_PATH, searchState);
4888+
docSearch.searchIndex = await docSearch.buildIndex(rawSearchIndex);
48714889
registerSearchEvents();
48724890
// If there's a search term in the URL, execute the search now.
48734891
if (window.searchState.getQueryStringParams().search !== undefined) {
48744892
search();
48754893
}
48764894
} else if (typeof exports !== "undefined") {
4877-
docSearch = new DocSearch(rawSearchIndex, ROOT_PATH, searchState);
4895+
docSearch = new DocSearch(ROOT_PATH, searchState);
4896+
docSearch.searchIndex = await docSearch.buildIndex(rawSearchIndex);
48784897
exports.docSearch = docSearch;
48794898
exports.parseQuery = DocSearch.parseQuery;
48804899
}

src/tools/rustdoc-js/tester.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ async function runChecks(testFile, doSearch, parseQuery, getCorrections) {
398398
* `parseQuery` function exported from the search module; and `getCorrections`, which runs
399399
* a search but returns type name corrections instead of results.
400400
*/
401-
function loadSearchJS(doc_folder, resource_suffix) {
401+
async function loadSearchJS(doc_folder, resource_suffix) {
402402
const searchIndexJs = path.join(doc_folder, "search-index" + resource_suffix + ".js");
403403
const searchIndex = require(searchIndexJs);
404404

@@ -433,7 +433,7 @@ function loadSearchJS(doc_folder, resource_suffix) {
433433
const staticFiles = path.join(doc_folder, "static.files");
434434
const searchJs = fs.readdirSync(staticFiles).find(f => f.match(/search.*\.js$/));
435435
const searchModule = require(path.join(staticFiles, searchJs));
436-
searchModule.initSearch(searchIndex.searchIndex);
436+
await searchModule.initSearch(searchIndex.searchIndex);
437437
const docSearch = searchModule.docSearch;
438438
return {
439439
doSearch: async function(queryStr, filterCrate, currentCrate) {
@@ -549,7 +549,7 @@ async function main(argv) {
549549
return 1;
550550
}
551551

552-
const parseAndSearch = loadSearchJS(
552+
const parseAndSearch = await loadSearchJS(
553553
opts["doc_folder"],
554554
opts["resource_suffix"],
555555
);

0 commit comments

Comments
 (0)