@@ -263,6 +263,13 @@ class InMemoryPackageIndex {
263263 // extra item, that will be addressed after the ranking score is determined.
264264 var totalCount = packageScores? .positiveCount () ?? predicateFilterCount;
265265
266+ // Checking if it is worth to calculate the sorted order, estimating the
267+ // total count by overcounting the best name matches.
268+ final maximumTotalCount = totalCount + (bestNameIndex != null ? 1 : 0 );
269+ if (maximumTotalCount < query.offset) {
270+ return PackageSearchResult .empty ();
271+ }
272+
266273 Iterable <IndexedPackageHit > indexedHits;
267274 switch (query.effectiveOrder) {
268275 case SearchOrder .top:
@@ -512,33 +519,37 @@ class InMemoryPackageIndex {
512519 return _TextResults (topApiPages);
513520 }
514521
515- List <IndexedPackageHit > _rankWithValues (
522+ Iterable <IndexedPackageHit > _rankWithValues (
516523 IndexedScore <String > score, {
517524 // if the item count is fewer than this threshold, an empty list will be returned
518525 required int requiredLengthThreshold,
519526 // When no best name match is applied, this parameter will be `-1`
520527 required int bestNameIndex,
521528 }) {
522- final list = < IndexedPackageHit > [];
529+ int compare (int aIndex, int bIndex) {
530+ if (aIndex == bestNameIndex) return - 1 ;
531+ if (bIndex == bestNameIndex) return 1 ;
532+ final aScore = score.getValue (aIndex);
533+ final bScore = score.getValue (bIndex);
534+ final scoreCompare = - aScore.compareTo (bScore);
535+ if (scoreCompare != 0 ) return scoreCompare;
536+ // if two packages got the same score, order by last updated
537+ return _compareUpdated (_documents[aIndex], _documents[bIndex]);
538+ }
539+
540+ final list = < int > [];
523541 for (var i = 0 ; i < score.length; i++ ) {
524542 final value = score.getValue (i);
525543 if (value <= 0.0 && i != bestNameIndex) continue ;
526- list.add (IndexedPackageHit (
527- i, PackageHit (package: score.keys[i], score: value)));
544+ list.add (i);
528545 }
529546 if (requiredLengthThreshold > list.length) {
530547 // There is no point to sort or even keep the results, as the search query offset ignores these anyway.
531548 return [];
532549 }
533- list.sort ((a, b) {
534- if (a.index == bestNameIndex) return - 1 ;
535- if (b.index == bestNameIndex) return 1 ;
536- final scoreCompare = - a.hit.score! .compareTo (b.hit.score! );
537- if (scoreCompare != 0 ) return scoreCompare;
538- // if two packages got the same score, order by last updated
539- return _compareUpdated (_documents[a.index], _documents[b.index]);
540- });
541- return list;
550+ list.sort (compare);
551+ return list.map ((i) => IndexedPackageHit (
552+ i, PackageHit (package: score.keys[i], score: score.getValue (i))));
542553 }
543554
544555 List <IndexedPackageHit > _rankWithComparator (
0 commit comments