private boolean checkNextPageHasEntry(ScoreDoc after,EnumSet<QueryOption> options,IndexSearcher s,Query tq,Sort sort,int count,QuerySpecification qs,long queryStartTimeMicros) throws Throwable {
  boolean hasValidNextPageEntry=false;
  while (after != null) {
    TopDocs nextPageResults;
    if (sort == null) {
      nextPageResults=s.searchAfter(after,tq,count);
    }
 else {
      nextPageResults=s.searchAfter(after,tq,count,sort,false,false);
    }
    if (nextPageResults == null) {
      break;
    }
    ScoreDoc[] hits=nextPageResults.scoreDocs;
    if (hits.length == 0) {
      break;
    }
    ServiceDocumentQueryResult rspForNextPage=new ServiceDocumentQueryResult();
    rspForNextPage.documents=new HashMap<>();
    after=processQueryResults(qs,options,count,s,rspForNextPage,hits,queryStartTimeMicros);
    if (rspForNextPage.documentCount > 0) {
      hasValidNextPageEntry=true;
      break;
    }
  }
  return hasValidNextPageEntry;
}

private boolean checkNextPageHasEntry ( ScoreDoc after , EnumSet < QueryOption > options , IndexSearcher s , Query tq , Sort sort , int count , QuerySpecification qs , long queryStartTimeMicros ) throws Throwable { boolean hasValidNextPageEntry = false ; while ( after != null ) { TopDocs nextPageResults ; if ( sort == null ) { nextPageResults = s . searchAfter ( after , tq , count ) ; } else { nextPageResults = s . searchAfter ( after , tq , count , sort , false , false ) ; } if ( nextPageResults == null ) { break ; } ScoreDoc [ ] hits = nextPageResults . scoreDocs ; if ( hits . length == 0 ) { break ; } ServiceDocumentQueryResult rspForNextPage = new ServiceDocumentQueryResult ( ) ; rspForNextPage . documents = new HashMap < > ( ) ; after = processQueryResults ( qs , options , count , s , rspForNextPage , hits , queryStartTimeMicros ) ; if ( rspForNextPage . documentCount > 0 ) { hasValidNextPageEntry = true ; break ; } } return hasValidNextPageEntry ; }
checks next page exists or not . if there is a valid entry in searchafter result , this returns true . if searchafter result is empty or entries are all invalid ( expired , etc ) , this returns false . for example , let ' s say there are 5 docs . doc = 1 , 2 , 5 are valid and doc = 3 , 4 are expired ( invalid ) . when limit = 2 , the first page shows doc = 1 , 2 . in this logic , searchafter will first fetch doc = 3 , 4 but they are invalid ( filtered out in ` processqueryresults ` ) . next iteration will hit doc = 5 and it is a valid entry . therefore , it returns true . if doc = 1 , 2 are valid and doc = 3 , 4 , 5 are invalid , then searchafter will hit doc = 3 , 4 and doc = 5 . however , all entries are invalid . this returns false indicating there is no next page .
