private void pruneSimilar(TopDocs docs) throws IOException {
   if (docs.scoreDocs.length == 0) {
     return;
   }
   int cutoff = docs.scoreDocs.length;
   double threshold = 0.005 * docs.scoreDocs[0].score;
   for (int i = 0, j = 100; j < docs.scoreDocs.length; i++, j++) {
     float delta = docs.scoreDocs[i].score - docs.scoreDocs[j].score;
     if (delta < threshold) {
       cutoff = j;
       break;
     }
   }
   if (cutoff < docs.scoreDocs.length) {
     //            LOG.info("pruned results from " + docs.scoreDocs.length + " to " + cutoff);
     docs.scoreDocs = ArrayUtils.subarray(docs.scoreDocs, 0, cutoff);
   }
 }
    public TopDocs topDocs(int start, int howMany) {

      try {

        TopDocs mainDocs = mainCollector.topDocs(0, Math.max(reRankDocs, length));

        if (mainDocs.totalHits == 0 || mainDocs.scoreDocs.length == 0) {
          return mainDocs;
        }

        if (boostedPriority != null) {
          SolrRequestInfo info = SolrRequestInfo.getRequestInfo();
          Map requestContext = null;
          if (info != null) {
            requestContext = info.getReq().getContext();
          }

          IntIntOpenHashMap boostedDocs =
              QueryElevationComponent.getBoostDocs(
                  (SolrIndexSearcher) searcher, boostedPriority, requestContext);

          ScoreDoc[] mainScoreDocs = mainDocs.scoreDocs;
          ScoreDoc[] reRankScoreDocs = new ScoreDoc[Math.min(mainScoreDocs.length, reRankDocs)];
          System.arraycopy(mainScoreDocs, 0, reRankScoreDocs, 0, reRankScoreDocs.length);

          mainDocs.scoreDocs = reRankScoreDocs;

          Map<Integer, Float> scoreMap = getScoreMap(mainDocs.scoreDocs, mainDocs.scoreDocs.length);

          TopDocs rescoredDocs =
              new QueryRescorer(reRankQuery) {
                @Override
                protected float combine(
                    float firstPassScore, boolean secondPassMatches, float secondPassScore) {
                  float score = firstPassScore;
                  if (secondPassMatches) {
                    score += reRankWeight * secondPassScore;
                  }
                  return score;
                }
              }.rescore(searcher, mainDocs, mainDocs.scoreDocs.length);

          Arrays.sort(
              rescoredDocs.scoreDocs,
              new BoostedComp(boostedDocs, mainDocs.scoreDocs, rescoredDocs.getMaxScore()));

          // Lower howMany if we've collected fewer documents.
          howMany = Math.min(howMany, mainScoreDocs.length);

          if (howMany == rescoredDocs.scoreDocs.length) {
            if (scale) {
              scaleScores(rescoredDocs, scoreMap);
            }
            return rescoredDocs; // Just return the rescoredDocs
          } else if (howMany > rescoredDocs.scoreDocs.length) {
            // We need to return more then we've reRanked, so create the combined page.
            ScoreDoc[] scoreDocs = new ScoreDoc[howMany];
            System.arraycopy(
                mainScoreDocs, 0, scoreDocs, 0, scoreDocs.length); // lay down the initial docs
            System.arraycopy(
                rescoredDocs.scoreDocs,
                0,
                scoreDocs,
                0,
                rescoredDocs.scoreDocs.length); // overlay the re-ranked docs.
            rescoredDocs.scoreDocs = scoreDocs;
            if (scale) {
              scaleScores(rescoredDocs, scoreMap);
            }
            return rescoredDocs;
          } else {
            // We've rescored more then we need to return.
            ScoreDoc[] scoreDocs = new ScoreDoc[howMany];
            System.arraycopy(rescoredDocs.scoreDocs, 0, scoreDocs, 0, howMany);
            rescoredDocs.scoreDocs = scoreDocs;
            if (scale) {
              scaleScores(rescoredDocs, scoreMap);
            }
            return rescoredDocs;
          }

        } else {

          ScoreDoc[] mainScoreDocs = mainDocs.scoreDocs;

          /*
           *  Create the array for the reRankScoreDocs.
           */
          ScoreDoc[] reRankScoreDocs = new ScoreDoc[Math.min(mainScoreDocs.length, reRankDocs)];

          /*
           *  Copy the initial results into the reRankScoreDocs array.
           */
          System.arraycopy(mainScoreDocs, 0, reRankScoreDocs, 0, reRankScoreDocs.length);

          mainDocs.scoreDocs = reRankScoreDocs;

          Map<Integer, Float> scoreMap = getScoreMap(mainDocs.scoreDocs, mainDocs.scoreDocs.length);

          TopDocs rescoredDocs =
              new QueryRescorer(reRankQuery) {
                @Override
                protected float combine(
                    float firstPassScore, boolean secondPassMatches, float secondPassScore) {
                  float score = firstPassScore;
                  if (secondPassMatches) {
                    score += reRankWeight * secondPassScore;
                  }
                  return score;
                }
              }.rescore(searcher, mainDocs, mainDocs.scoreDocs.length);

          // Lower howMany to return if we've collected fewer documents.
          howMany = Math.min(howMany, mainScoreDocs.length);

          if (howMany == rescoredDocs.scoreDocs.length) {
            if (scale) {
              scaleScores(rescoredDocs, scoreMap);
            }
            return rescoredDocs; // Just return the rescoredDocs
          } else if (howMany > rescoredDocs.scoreDocs.length) {

            // We need to return more then we've reRanked, so create the combined page.
            ScoreDoc[] scoreDocs = new ScoreDoc[howMany];
            // lay down the initial docs
            System.arraycopy(mainScoreDocs, 0, scoreDocs, 0, scoreDocs.length);
            // overlay the rescoreds docs
            System.arraycopy(
                rescoredDocs.scoreDocs, 0, scoreDocs, 0, rescoredDocs.scoreDocs.length);
            rescoredDocs.scoreDocs = scoreDocs;
            if (scale) {
              assert (scoreMap != null);
              scaleScores(rescoredDocs, scoreMap);
            }
            return rescoredDocs;
          } else {
            // We've rescored more then we need to return.
            ScoreDoc[] scoreDocs = new ScoreDoc[howMany];
            System.arraycopy(rescoredDocs.scoreDocs, 0, scoreDocs, 0, howMany);
            rescoredDocs.scoreDocs = scoreDocs;
            if (scale) {
              scaleScores(rescoredDocs, scoreMap);
            }
            return rescoredDocs;
          }
        }
      } catch (Exception e) {
        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
      }
    }