@@ -24,9 +24,9 @@ class InMemoryPackageIndex {
2424 final List <PackageDocument > _documents;
2525 final _documentsByName = < String , PackageDocument > {};
2626 late final PackageNameIndex _packageNameIndex;
27- late final TokenIndex _descrIndex;
28- late final TokenIndex _readmeIndex;
29- late final TokenIndex _apiSymbolIndex;
27+ late final TokenIndex < String > _descrIndex;
28+ late final TokenIndex < String > _readmeIndex;
29+ late final TokenIndex < IndexedApiDocPage > _apiSymbolIndex;
3030
3131 /// Adjusted score takes the overall score and transforms
3232 /// it linearly into the [0.4-1.0] range.
@@ -51,16 +51,17 @@ class InMemoryPackageIndex {
5151 InMemoryPackageIndex ({
5252 required Iterable <PackageDocument > documents,
5353 }) : _documents = [...documents] {
54- final apiDocPageKeys = < String > [];
54+ final apiDocPageKeys = < IndexedApiDocPage > [];
5555 final apiDocPageValues = < String > [];
56- for (final doc in _documents) {
56+ for (var i = 0 ; i < _documents.length; i++ ) {
57+ final doc = _documents[i];
5758 _documentsByName[doc.package] = doc;
5859
5960 final apiDocPages = doc.apiDocPages;
6061 if (apiDocPages != null ) {
6162 for (final page in apiDocPages) {
6263 if (page.symbols != null && page.symbols! .isNotEmpty) {
63- apiDocPageKeys.add (_apiDocPageId ( doc.package, page));
64+ apiDocPageKeys.add (IndexedApiDocPage (i, doc.package, page));
6465 apiDocPageValues.add (page.symbols! .join (' ' ));
6566 }
6667 }
@@ -233,8 +234,7 @@ class InMemoryPackageIndex {
233234 packageHits = packageHits.map ((ps) {
234235 final apiPages = textResults.topApiPages[ps.package]
235236 // TODO(https://github.com/dart-lang/pub-dev/issues/7106): extract title for the page
236- ? .map ((MapEntry <String , double > e) =>
237- ApiPageRef (path: _apiDocPath (e.key)))
237+ ? .map ((MapEntry <String , double > e) => ApiPageRef (path: e.key))
238238 .toList ();
239239 return ps.change (apiPages: apiPages);
240240 }).toList ();
@@ -264,7 +264,7 @@ class InMemoryPackageIndex {
264264 }
265265
266266 _TextResults ? _searchText (
267- IndexedScore packageScores,
267+ IndexedScore < String > packageScores,
268268 String ? text, {
269269 required bool includeNameMatches,
270270 }) {
@@ -310,64 +310,58 @@ class InMemoryPackageIndex {
310310 packageScores.multiplyAllFrom (wordScore);
311311 }
312312
313- final core = packageScores.toScore ();
314-
315- var symbolPages = Score .empty;
316- if (! checkAborted ()) {
317- symbolPages = _apiSymbolIndex.searchWords (words, weight: 0.70 );
318- }
319-
320- final apiPackages = < String , double > {};
321313 final topApiPages = < String , List <MapEntry <String , double >>> {};
322314 const maxApiPageCount = 2 ;
323- for (final entry in symbolPages.entries) {
324- final pkg = _apiDocPkg (entry.key);
325- if (! packages.contains (pkg)) continue ;
326-
327- // skip if the previously found pages are better than the current one
328- final pages = topApiPages.putIfAbsent (pkg, () => []);
329- if (pages.length >= maxApiPageCount && pages.last.value > entry.value) {
330- continue ;
331- }
315+ if (! checkAborted ()) {
316+ final symbolPages = _apiSymbolIndex.searchWords (words, weight: 0.70 );
332317
333- // update the top api packages score
334- apiPackages[pkg] = math.max (entry.value, apiPackages[pkg] ?? 0.0 );
318+ for (var i = 0 ; i < symbolPages.length; i++ ) {
319+ final value = symbolPages.getValue (i);
320+ if (value < 0.01 ) continue ;
335321
336- // add the page and re-sort the current results
337- pages.add (entry);
338- if (pages.length > 1 ) {
339- pages.sort ((a, b) => - a.value.compareTo (b.value));
340- }
341- // keep the results limited to the max count
342- if (pages.length > maxApiPageCount) {
343- pages.removeLast ();
322+ final doc = symbolPages.keys[i];
323+ if (! packages.contains (doc.package)) continue ;
324+
325+ // skip if the previously found pages are better than the current one
326+ final pages = topApiPages.putIfAbsent (doc.package, () => []);
327+ if (pages.length >= maxApiPageCount && pages.last.value > value) {
328+ continue ;
329+ }
330+
331+ // update the top api packages score
332+ packageScores.setValueMaxOf (doc.index, value);
333+
334+ // add the page and re-sort the current results
335+ pages.add (MapEntry (doc.page.relativePath, value));
336+ if (pages.length > 1 ) {
337+ pages.sort ((a, b) => - a.value.compareTo (b.value));
338+ }
339+
340+ // keep the results limited to the max count
341+ if (pages.length > maxApiPageCount) {
342+ pages.removeLast ();
343+ }
344344 }
345345 }
346346
347- final apiPkgScore = Score (apiPackages);
348- var score = Score .max ([core, apiPkgScore])
349- .removeLowValues (fraction: 0.2 , minValue: 0.01 );
350-
351347 // filter results based on exact phrases
352348 final phrases = extractExactPhrases (text);
353349 if (! aborted && phrases.isNotEmpty) {
354- final matched = < String , double > {};
355- for (final MapEntry (key: package, value: packageScore)
356- in score.entries) {
357- final doc = _documentsByName[package]! ;
358- final bool matchedAllPhrases = phrases.every ((phrase) =>
350+ for (var i = 0 ; i < packageScores.length; i++ ) {
351+ if (packageScores.isNotPositive (i)) continue ;
352+ final doc = _documents[i];
353+ final matchedAllPhrases = phrases.every ((phrase) =>
359354 doc.package.contains (phrase) ||
360355 doc.description! .contains (phrase) ||
361356 doc.readme! .contains (phrase));
362- if (matchedAllPhrases) {
363- matched[package] = packageScore ;
357+ if (! matchedAllPhrases) {
358+ packageScores. setValue (i, 0 ) ;
364359 }
365360 }
366- score = Score (matched);
367361 }
368362
369363 return _TextResults (
370- score ,
364+ packageScores. toScore () ,
371365 topApiPages,
372366 nameMatches: nameMatches? .toList (),
373367 );
@@ -441,18 +435,6 @@ class InMemoryPackageIndex {
441435 if (x != 0 ) return x;
442436 return _compareUpdated (a, b);
443437 }
444-
445- String _apiDocPageId (String package, ApiDocPage page) {
446- return '$package ::${page .relativePath }' ;
447- }
448-
449- String _apiDocPkg (String id) {
450- return id.split ('::' ).first;
451- }
452-
453- String _apiDocPath (String id) {
454- return id.split ('::' ).last;
455- }
456438}
457439
458440class _TextResults {
@@ -494,7 +476,7 @@ class PackageNameIndex {
494476 /// Search [text] and return the matching packages with scores.
495477 @visibleForTesting
496478 Score search (String text) {
497- IndexedScore ? score;
479+ IndexedScore < String > ? score;
498480 for (final w in splitForQuery (text)) {
499481 final s = searchWord (w, filterOnNonZeros: score);
500482 if (score == null ) {
@@ -511,9 +493,9 @@ class PackageNameIndex {
511493 ///
512494 /// When [filterOnNonZeros] is present, only the indexes with an already
513495 /// non-zero value are evaluated.
514- IndexedScore searchWord (
496+ IndexedScore < String > searchWord (
515497 String word, {
516- IndexedScore ? filterOnNonZeros,
498+ IndexedScore < String > ? filterOnNonZeros,
517499 }) {
518500 final score = IndexedScore (_packageNames);
519501 final singularWord = word.length <= 3 || ! word.endsWith ('s' )
@@ -570,3 +552,11 @@ class IndexedPackageHit {
570552
571553 IndexedPackageHit (this .index, this .hit);
572554}
555+
556+ class IndexedApiDocPage {
557+ final int index;
558+ final String package;
559+ final ApiDocPage page;
560+
561+ IndexedApiDocPage (this .index, this .package, this .page);
562+ }
0 commit comments