Skip to content

Commit 7bb1b2a

Browse files
committed
rustdoc-search: better hashing, faster unification
The hash changes are based on some tests with `arti` and various specific queries, aimed at reducing the false positive rate. Sorting the query elements so that generics always come first is instead aimed at reducing the number of Map operations on mgens, assuming if the bloom filter does find a false positive, it'll be able to reject the row without having to track a mapping.
1 parent 41677b3 commit 7bb1b2a

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

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

+19-11
Original file line numberDiff line numberDiff line change
@@ -2283,7 +2283,7 @@ function initSearch(rawSearchIndex) {
22832283
parsedQuery.elems.sort(sortQ);
22842284
parsedQuery.returned.sort(sortQ);
22852285
for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
2286-
handleArgs(searchIndex[i], i, results_others);
2286+
handleArgs(searchIndex[i], searchIndex[i].id, results_others);
22872287
}
22882288
}
22892289
}
@@ -2847,23 +2847,32 @@ ${item.displayPath}<span class="${type}">${name}</span>\
28472847
* @param {Set<number>} fps - Set of distinct items
28482848
*/
28492849
function buildFunctionTypeFingerprint(type, output, fps) {
2850-
28512850
let input = type.id;
28522851
// All forms of `[]` get collapsed down to one thing in the bloom filter.
28532852
// Differentiating between arrays and slices, if the user asks for it, is
28542853
// still done in the matching algorithm.
28552854
if (input === typeNameIdOfArray || input === typeNameIdOfSlice) {
28562855
input = typeNameIdOfArrayOrSlice;
28572856
}
2858-
if (input !== null) {
2857+
const fxScram = k => {
28592858
// https://docs.rs/rustc-hash/1.1.0/src/rustc_hash/lib.rs.html#60
2860-
// Rotate is skipped because we're only doing one cycle anyway.
2861-
const h0 = Math.imul(input, 0x9e3779b9);
2862-
const h1 = Math.imul(479001599 ^ input, 0x9e3779b9);
2863-
const h2 = Math.imul(433494437 ^ input, 0x9e3779b9);
2864-
output[0] |= 1 << (h0 % 32);
2865-
output[1] |= 1 << (h1 % 32);
2866-
output[2] |= 1 << (h2 % 32);
2859+
return Math.imul((k << 5) | (k >> 27), 0x9e3779b9);
2860+
};
2861+
const murmurScram = k => {
2862+
// https://en.wikipedia.org/wiki/MurmurHash
2863+
k = Math.imul(k, 0xcc9e2d51);
2864+
return Math.imul((k << 15) | (k >> 17), 0x1b873593);
2865+
};
2866+
if (input !== null) {
2867+
const h0a = fxScram(input);
2868+
const h0b = murmurScram(input);
2869+
const h1a = fxScram(479001599 ^ input);
2870+
const h1b = murmurScram(479001599 ^ input);
2871+
const h2a = fxScram(433494437 ^ input);
2872+
const h2b = murmurScram(433494437 ^ input);
2873+
output[0] |= (1 << (h0a % 32)) | (1 << (h0b % 32));
2874+
output[1] |= (1 << (h1a % 32)) | (1 << (h1b % 32));
2875+
output[2] |= (1 << (h2a % 32)) | (1 << (h2b % 32));
28672876
fps.add(input);
28682877
}
28692878
for (const g of type.generics) {
@@ -2892,7 +2901,6 @@ ${item.displayPath}<span class="${type}">${name}</span>\
28922901
* This function might return 0!
28932902
*/
28942903
function compareTypeFingerprints(fullId, queryFingerprint) {
2895-
28962904
const fh0 = functionTypeFingerprint[fullId * 4];
28972905
const fh1 = functionTypeFingerprint[(fullId * 4) + 1];
28982906
const fh2 = functionTypeFingerprint[(fullId * 4) + 2];

0 commit comments

Comments
 (0)