Skip to content

Commit 76fbc89

Browse files
committed
Explicitly yield while building index every 256 items
1 parent 3f0036a commit 76fbc89

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

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

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,11 +1450,10 @@ class NameTrie {
14501450

14511451
class DocSearch {
14521452
/**
1453-
* @param {Map<string, rustdoc.RawSearchIndexCrate>} rawSearchIndex
14541453
* @param {string} rootPath
14551454
* @param {rustdoc.SearchState} searchState
14561455
*/
1457-
constructor(rawSearchIndex, rootPath, searchState) {
1456+
constructor(rootPath, searchState) {
14581457
/**
14591458
* @type {Map<String, RoaringBitmap>}
14601459
*/
@@ -1585,7 +1584,7 @@ class DocSearch {
15851584
/**
15861585
* @type {Array<rustdoc.Row>}
15871586
*/
1588-
this.searchIndex = this.buildIndex(rawSearchIndex);
1587+
this.searchIndex = [];
15891588
}
15901589

15911590
/**
@@ -1911,9 +1910,9 @@ class DocSearch {
19111910
* Convert raw search index into in-memory search index.
19121911
*
19131912
* @param {Map<string, rustdoc.RawSearchIndexCrate>} rawSearchIndex
1914-
* @returns {rustdoc.Row[]}
1913+
* @returns {Promise<rustdoc.Row[]>}
19151914
*/
1916-
buildIndex(rawSearchIndex) {
1915+
async buildIndex(rawSearchIndex) {
19171916
/**
19181917
* Convert from RawFunctionSearchType to FunctionSearchType.
19191918
*
@@ -2177,6 +2176,20 @@ class DocSearch {
21772176
paths[i] = { ty, name, path, exactPath, unboxFlag };
21782177
}
21792178

2179+
// Throttlers are used to yield to the JavaScript event loop
2180+
// while this is being built.
2181+
// They're generated up-front to avoid the "nesting level"
2182+
// limit that limits our speed to 4ms per tick.
2183+
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html
2184+
const throttlers = [];
2185+
len = itemTypes.length;
2186+
for (let i = 0; i < len; ++i) {
2187+
if ((i & 0xFF) === 0) { // 256 - 1
2188+
throttlers.push(new Promise(resolve => {
2189+
setTimeout(resolve, 0);
2190+
}));
2191+
}
2192+
}
21802193
// convert `item*` into an object form, and construct word indices.
21812194
//
21822195
// before any analysis is performed lets gather the search terms to
@@ -2189,6 +2202,9 @@ class DocSearch {
21892202
let lastName = "";
21902203
let lastWord = "";
21912204
for (let i = 0; i < len; ++i) {
2205+
if ((i & 0xFF) === 0) { // 256 - 1
2206+
await throttlers[i >> 8];
2207+
}
21922208
const bitIndex = i + 1;
21932209
if (descIndex >= descShard.len &&
21942210
// @ts-expect-error
@@ -5377,20 +5393,26 @@ function updateCrate(ev) {
53775393
search(true);
53785394
}
53795395

5380-
// @ts-expect-error
5381-
function initSearch(searchIndx) {
5396+
/**
5397+
* @param {Map<string, import("./rustdoc").RawSearchIndexCrate>} searchIndx
5398+
*/
5399+
async function initSearch(searchIndx) {
5400+
if (ROOT_PATH === null) {
5401+
return;
5402+
}
53825403
rawSearchIndex = searchIndx;
53835404
if (typeof window !== "undefined") {
5384-
// @ts-expect-error
5385-
docSearch = new DocSearch(rawSearchIndex, ROOT_PATH, searchState);
5405+
docSearch = new DocSearch(ROOT_PATH, window.searchState);
5406+
docSearch.searchIndex = await docSearch.buildIndex(rawSearchIndex);
53865407
registerSearchEvents();
53875408
// If there's a search term in the URL, execute the search now.
53885409
if (window.searchState.getQueryStringParams().search !== undefined) {
53895410
search();
53905411
}
53915412
} else if (typeof exports !== "undefined") {
5392-
// @ts-expect-error
5393-
docSearch = new DocSearch(rawSearchIndex, ROOT_PATH, searchState);
5413+
// @ts-ignore
5414+
docSearch = new DocSearch(ROOT_PATH, searchState);
5415+
docSearch.searchIndex = await docSearch.buildIndex(rawSearchIndex);
53945416
exports.docSearch = docSearch;
53955417
exports.parseQuery = DocSearch.parseQuery;
53965418
}

src/tools/rustdoc-js/tester.js

Lines changed: 3 additions & 3 deletions
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)