@@ -263,6 +263,13 @@ class InMemoryPackageIndex {
263
263
// extra item, that will be addressed after the ranking score is determined.
264
264
var totalCount = packageScores? .positiveCount () ?? predicateFilterCount;
265
265
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
+
266
273
Iterable <IndexedPackageHit > indexedHits;
267
274
switch (query.effectiveOrder) {
268
275
case SearchOrder .top:
@@ -512,33 +519,37 @@ class InMemoryPackageIndex {
512
519
return _TextResults (topApiPages);
513
520
}
514
521
515
- List <IndexedPackageHit > _rankWithValues (
522
+ Iterable <IndexedPackageHit > _rankWithValues (
516
523
IndexedScore <String > score, {
517
524
// if the item count is fewer than this threshold, an empty list will be returned
518
525
required int requiredLengthThreshold,
519
526
// When no best name match is applied, this parameter will be `-1`
520
527
required int bestNameIndex,
521
528
}) {
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 > [];
523
541
for (var i = 0 ; i < score.length; i++ ) {
524
542
final value = score.getValue (i);
525
543
if (value <= 0.0 && i != bestNameIndex) continue ;
526
- list.add (IndexedPackageHit (
527
- i, PackageHit (package: score.keys[i], score: value)));
544
+ list.add (i);
528
545
}
529
546
if (requiredLengthThreshold > list.length) {
530
547
// There is no point to sort or even keep the results, as the search query offset ignores these anyway.
531
548
return [];
532
549
}
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))));
542
553
}
543
554
544
555
List <IndexedPackageHit > _rankWithComparator (
0 commit comments