@@ -2268,8 +2268,27 @@ function initSearch(rawSearchIndex) {
22682268 ) ;
22692269 }
22702270 } else if ( parsedQuery . foundElems > 0 ) {
2271+ // Sort input and output so that generic type variables go first and
2272+ // types with generic parameters go last.
2273+ // That's because of the way unification is structured: it eats off
2274+ // the end, and hits a fast path if the last item is a simple atom.
2275+ const sortQ = ( a , b ) => {
2276+ const ag = a . generics . length === 0 && a . bindings . size === 0 ;
2277+ const bg = b . generics . length === 0 && b . bindings . size === 0 ;
2278+ if ( ag !== bg ) {
2279+ return ag - bg ;
2280+ }
2281+ const ai = a . id > 0 ;
2282+ const bi = b . id > 0 ;
2283+ if ( ai !== bi ) {
2284+ return ai - bi ;
2285+ }
2286+ return 0 ;
2287+ } ;
2288+ parsedQuery . elems . sort ( sortQ ) ;
2289+ parsedQuery . returned . sort ( sortQ ) ;
22712290 for ( i = 0 , nSearchWords = searchWords . length ; i < nSearchWords ; ++ i ) {
2272- handleArgs ( searchIndex [ i ] , i , results_others ) ;
2291+ handleArgs ( searchIndex [ i ] , searchIndex [ i ] . id , results_others ) ;
22732292 }
22742293 }
22752294 }
@@ -2841,15 +2860,25 @@ ${item.displayPath}<span class="${type}">${name}</span>\
28412860 if ( input === typeNameIdOfArray || input === typeNameIdOfSlice ) {
28422861 input = typeNameIdOfArrayOrSlice ;
28432862 }
2844- if ( input !== null ) {
2863+ const fxScram = k => {
28452864 // https://docs.rs/rustc-hash/1.1.0/src/rustc_hash/lib.rs.html#60
2846- // Rotate is skipped because we're only doing one cycle anyway.
2847- const h0 = Math . imul ( input , 0x9e3779b9 ) ;
2848- const h1 = Math . imul ( 479001599 ^ input , 0x9e3779b9 ) ;
2849- const h2 = Math . imul ( 433494437 ^ input , 0x9e3779b9 ) ;
2850- output [ 0 ] |= 1 << ( h0 % 32 ) ;
2851- output [ 1 ] |= 1 << ( h1 % 32 ) ;
2852- output [ 2 ] |= 1 << ( h2 % 32 ) ;
2865+ return Math . imul ( ( k << 5 ) | ( k >> 27 ) , 0x9e3779b9 ) ;
2866+ } ;
2867+ const murmurScram = k => {
2868+ // https://en.wikipedia.org/wiki/MurmurHash
2869+ k = Math . imul ( k , 0xcc9e2d51 ) ;
2870+ return Math . imul ( ( k << 15 ) | ( k >> 17 ) , 0x1b873593 ) ;
2871+ } ;
2872+ if ( input !== null ) {
2873+ const h0a = fxScram ( input ) ;
2874+ const h0b = murmurScram ( input ) ;
2875+ const h1a = fxScram ( 479001599 ^ input ) ;
2876+ const h1b = murmurScram ( 479001599 ^ input ) ;
2877+ const h2a = fxScram ( 433494437 ^ input ) ;
2878+ const h2b = murmurScram ( 433494437 ^ input ) ;
2879+ output [ 0 ] |= ( 1 << ( h0a % 32 ) ) | ( 1 << ( h0b % 32 ) ) ;
2880+ output [ 1 ] |= ( 1 << ( h1a % 32 ) ) | ( 1 << ( h1b % 32 ) ) ;
2881+ output [ 2 ] |= ( 1 << ( h2a % 32 ) ) | ( 1 << ( h2b % 32 ) ) ;
28532882 fps . add ( input ) ;
28542883 }
28552884 for ( const g of type . generics ) {
@@ -2878,7 +2907,6 @@ ${item.displayPath}<span class="${type}">${name}</span>\
28782907 * This function might return 0!
28792908 */
28802909 function compareTypeFingerprints ( fullId , queryFingerprint ) {
2881-
28822910 const fh0 = functionTypeFingerprint [ fullId * 4 ] ;
28832911 const fh1 = functionTypeFingerprint [ ( fullId * 4 ) + 1 ] ;
28842912 const fh2 = functionTypeFingerprint [ ( fullId * 4 ) + 2 ] ;
0 commit comments