/// <summary>Returns the score of the current document matching the query. /// Initially invalid, until {@link #next()} is called the first time. /// </summary> /// <returns> The score of the required scorer, eventually increased by the score /// of the optional scorer when it also matches the current document. /// </returns> public override float Score() { int curDoc = reqScorer.Doc(); float reqScore = reqScorer.Score(); if (firstTimeOptScorer) { firstTimeOptScorer = false; if (!optScorer.SkipTo(curDoc)) { optScorer = null; return(reqScore); } } else if (optScorer == null) { return(reqScore); } else if ((optScorer.Doc() < curDoc) && (!optScorer.SkipTo(curDoc))) { optScorer = null; return(reqScore); } // assert (optScorer != null) && (optScorer.doc() >= curDoc); return((optScorer.Doc() == curDoc) ? reqScore + optScorer.Score() : reqScore); }
/// <summary>Advance to non excluded doc. /// <br>On entry: /// <ul> /// <li>reqScorer != null, /// <li>exclScorer != null, /// <li>reqScorer was advanced once via next() or skipTo() /// and reqScorer.doc() may still be excluded. /// </ul> /// Advances reqScorer a non excluded required doc, if any. /// </summary> /// <returns> true iff there is a non excluded required doc. /// </returns> private bool ToNonExcluded() { int exclDoc = exclScorer.Doc(); do { int reqDoc = reqScorer.Doc(); // may be excluded if (reqDoc < exclDoc) { return(true); // reqScorer advanced to before exclScorer, ie. not excluded } else if (reqDoc > exclDoc) { if (!exclScorer.SkipTo(reqDoc)) { exclScorer = null; // exhausted, no more exclusions return(true); } exclDoc = exclScorer.Doc(); if (exclDoc > reqDoc) { return(true); // not excluded } } }while (reqScorer.Next()); reqScorer = null; // exhausted, nothing left return(false); }
/// <summary>Scores and collects all matching documents.</summary> /// <param name="hc">The collector to which all matching documents are passed through /// {@link HitCollector#Collect(int, float)}. /// <br>When this method is used the {@link #Explain(int)} method should not be used. /// </param> public override void Score(HitCollector hc) { if (allowDocsOutOfOrder && requiredScorers.Count == 0 && prohibitedScorers.Count < 32) { // fall back to BooleanScorer, scores documents somewhat out of order BooleanScorer bs = new BooleanScorer(GetSimilarity(), minNrShouldMatch); System.Collections.IEnumerator si = optionalScorers.GetEnumerator(); while (si.MoveNext()) { bs.Add((Scorer)si.Current, false, false); } si = prohibitedScorers.GetEnumerator(); while (si.MoveNext()) { bs.Add((Scorer)si.Current, false, true); } bs.Score(hc); } else { if (countingSumScorer == null) { InitCountingSumScorer(); } while (countingSumScorer.Next()) { hc.Collect(countingSumScorer.Doc(), Score()); } } }
/// <summary>Scores and collects all matching documents.</summary> /// <param name="hc">The collector to which all matching documents are passed through /// {@link HitCollector#Collect(int, float)}. /// <br>When this method is used the {@link #Explain(int)} method should not be used. /// </param> public override void Score(HitCollector hc) { if (countingSumScorer == null) { InitCountingSumScorer(); } while (countingSumScorer.Next()) { hc.Collect(countingSumScorer.Doc(), Score()); } }
/// <summary>Advance all subscorers after the current document determined by the /// top of the <code>scorerQueue</code>. /// 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 <code>scorerQueue</code> has at least <code>minimumNrMatchers</code> /// 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, </code>currentDoc</code>, </code>currentSumScore</code>, /// and </code>nrMatchers</code> describe the match. /// /// </returns> /// <todo> Investigate whether it is possible to use skipTo() when </todo> /// <summary> the minimum number of matchers is bigger than one, ie. try and use the /// character of ConjunctionScorer for the minimum number of matchers. /// </summary> protected internal virtual bool AdvanceAfterCurrent() { do { // repeat until minimum nr of matchers Scorer top = (Scorer)scorerQueue.Top(); currentDoc = top.Doc(); currentScore = top.Score(); nrMatchers = 1; do { // Until all subscorers are after currentDoc if (top.Next()) { scorerQueue.AdjustTop(); } else { scorerQueue.Pop(); if (scorerQueue.Size() < (minimumNrMatchers - nrMatchers)) { // Not enough subscorers left for a match on this document, // and also no more chance of any further match. return(false); } if (scorerQueue.Size() == 0) { break; // nothing more to advance, check for last match. } } top = (Scorer)scorerQueue.Top(); if (top.Doc() != currentDoc) { break; // All remaining subscorers are after currentDoc. } else { currentScore += top.Score(); nrMatchers++; } }while (true); if (nrMatchers >= minimumNrMatchers) { return(true); } else if (scorerQueue.Size() < minimumNrMatchers) { return(false); } }while (true); }
/// <summary>Skips to the first match beyond the current whose document number is /// greater than or equal to a given target. /// <br>When this method is used the {@link #Explain(int)} method should not be used. /// <br>The implementation uses the skipTo() method on the subscorers. /// </summary> /// <param name="target">The target document number. /// </param> /// <returns> true iff there is such a match. /// </returns> public override bool SkipTo(int target) { if (scorerQueue == null) { InitScorerQueue(); } if (scorerQueue.Size() < minimumNrMatchers) { return(false); } if (target <= currentDoc) { target = currentDoc + 1; } do { Scorer top = (Scorer)scorerQueue.Top(); if (top.Doc() >= target) { return(AdvanceAfterCurrent()); } else if (top.SkipTo(target)) { scorerQueue.AdjustTop(); } else { scorerQueue.Pop(); if (scorerQueue.Size() < minimumNrMatchers) { return(false); } } }while (true); }
// inherit javadoc public override void Search(Weight weight, Filter filter, HitCollector results) { Scorer scorer = weight.Scorer(reader); if (scorer == null) { return; } if (filter == null) { scorer.Score(results); return; } DocIdSetIterator filterDocIdIterator = filter.GetDocIdSet(reader).Iterator(); // CHECKME: use ConjunctionScorer here? bool more = filterDocIdIterator.Next() && scorer.SkipTo(filterDocIdIterator.Doc()); while (more) { int filterDocId = filterDocIdIterator.Doc(); if (filterDocId > scorer.Doc() && !scorer.SkipTo(filterDocId)) { more = false; } else { int scorerDocId = scorer.Doc(); if (scorerDocId == filterDocId) // permitted by filter { results.Collect(scorerDocId, scorer.Score()); more = filterDocIdIterator.Next(); } else { more = filterDocIdIterator.SkipTo(scorerDocId); } } } }
public override bool Next() { bool more; do { while (bucketTable.first != null) { // more queued current = bucketTable.first; bucketTable.first = current.next; // pop the queue // check prohibited & required if ((current.bits & prohibitedMask) == 0 && (current.bits & requiredMask) == requiredMask) { return(true); } } // refill the queue more = false; end += BucketTable.SIZE; for (SubScorer sub = scorers; sub != null; sub = sub.next) { Scorer scorer = sub.scorer; while (!sub.done && scorer.Doc() < end) { sub.collector.Collect(scorer.Doc(), scorer.Score()); sub.done = !scorer.Next(); } if (!sub.done) { more = true; } } }while (bucketTable.first != null || more); return(false); }
private bool DoNext() { int first = 0; Scorer lastScorer = scorers[scorers.Length - 1]; Scorer firstScorer; while (more && (firstScorer = scorers[first]).Doc() < (lastDoc = lastScorer.Doc())) { more = firstScorer.SkipTo(lastDoc); lastScorer = firstScorer; first = (first == (scorers.Length - 1)) ? 0 : first + 1; } return(more); }
/* The subtree of subScorers at root is a min heap except possibly for its root element. * Bubble the root down as required to make the subtree a heap. */ private void HeapAdjust(int root) { Scorer scorer = (Scorer)subScorers[root]; int doc = scorer.Doc(); int i = root, size = subScorers.Count; while (i <= (size >> 1) - 1) { int lchild = (i << 1) + 1; Scorer lscorer = (Scorer)subScorers[lchild]; int ldoc = lscorer.Doc(); int rdoc = System.Int32.MaxValue, rchild = (i << 1) + 2; Scorer rscorer = null; if (rchild < size) { rscorer = (Scorer)subScorers[rchild]; rdoc = rscorer.Doc(); } if (ldoc < doc) { if (rdoc < ldoc) { subScorers[i] = rscorer; subScorers[rchild] = scorer; i = rchild; } else { subScorers[i] = lscorer; subScorers[lchild] = scorer; i = lchild; } } else if (rdoc < doc) { subScorers[i] = rscorer; subScorers[rchild] = scorer; i = rchild; } else { return; } } }
public override int Doc() { return(reqScorer.Doc()); // reqScorer may be null when next() or skipTo() already return false }
public override int Doc() { return(scorer.Doc()); }
public override int Doc() { return(countingSumScorer.Doc()); }