/// <summary>Advance all subscorers after the current document determined by the /// top of the <c>scorerDocQueue</c>. /// Repeat until at least the minimum number of subscorers match on the same /// document and all subscorers are after that document or are exhausted. /// <br/>On entry the <c>scorerDocQueue</c> has at least <c>minimumNrMatchers</c> /// available. At least the scorer with the minimum document number will be advanced. /// </summary> /// <returns> true iff there is a match. /// <br/>In case there is a match, <c>currentDoc</c>, <c>currentSumScore</c>, /// and <c>nrMatchers</c> describe the match. /// /// TODO: Investigate whether it is possible to use skipTo() when /// the minimum number of matchers is bigger than one, ie. try and use the /// character of ConjunctionScorer for the minimum number of matchers. /// Also delay calling score() on the sub scorers until the minimum number of /// matchers is reached. /// <br/>For this, a Scorer array with minimumNrMatchers elements might /// hold Scorers at currentDoc that are temporarily popped from scorerQueue. /// </returns> protected internal virtual bool AdvanceAfterCurrent(IState state) { do { // repeat until minimum nr of matchers currentDoc = scorerDocQueue.TopDoc(); var buffer = ArrayPool <float> .Shared.Rent(scorerDocQueue.MaxSize); buffer[0] = scorerDocQueue.TopScore(state); nrMatchers = 1; do { // Until all subscorers are after currentDoc if (!scorerDocQueue.TopNextAndAdjustElsePop(state)) { if (scorerDocQueue.Size() == 0) { break; // nothing more to advance, check for last match. } } if (scorerDocQueue.TopDoc() != currentDoc) { break; // All remaining subscorers are after currentDoc. } buffer[nrMatchers++] = scorerDocQueue.TopScore(state); } while (true); Array.Sort(buffer, 0, nrMatchers); currentScore = 0; for (int i = 0; i < nrMatchers; i++) { currentScore += buffer[i]; } ArrayPool <float> .Shared.Return(buffer); if (nrMatchers >= minimumNrMatchers) { return(true); } else if (scorerDocQueue.Size() < minimumNrMatchers) { return(false); } }while (true); }
/// <summary>Advance all subscorers after the current document determined by the /// top of the <c>scorerDocQueue</c>. /// Repeat until at least the minimum number of subscorers match on the same /// document and all subscorers are after that document or are exhausted. /// <br/>On entry the <c>scorerDocQueue</c> has at least <c>minimumNrMatchers</c> /// available. At least the scorer with the minimum document number will be advanced. /// </summary> /// <returns> true iff there is a match. /// <br/>In case there is a match, <c>currentDoc</c>, <c>currentSumScore</c>, /// and <c>nrMatchers</c> describe the match. /// /// TODO: Investigate whether it is possible to use skipTo() when /// the minimum number of matchers is bigger than one, ie. try and use the /// character of ConjunctionScorer for the minimum number of matchers. /// Also delay calling score() on the sub scorers until the minimum number of /// matchers is reached. /// <br/>For this, a Scorer array with minimumNrMatchers elements might /// hold Scorers at currentDoc that are temporarily popped from scorerQueue. /// </returns> protected internal virtual bool AdvanceAfterCurrent(IState state) { do { // repeat until minimum nr of matchers currentDoc = scorerDocQueue.TopDoc(); currentScore = scorerDocQueue.TopScore(state); nrMatchers = 1; do { // Until all subscorers are after currentDoc if (!scorerDocQueue.TopNextAndAdjustElsePop(state)) { if (scorerDocQueue.Size() == 0) { break; // nothing more to advance, check for last match. } } if (scorerDocQueue.TopDoc() != currentDoc) { break; // All remaining subscorers are after currentDoc. } currentScore += scorerDocQueue.TopScore(state); nrMatchers++; }while (true); if (nrMatchers >= minimumNrMatchers) { return(true); } else if (scorerDocQueue.Size() < minimumNrMatchers) { return(false); } }while (true); }