Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
 /// <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());
         }
     }
 }
Пример #4
0
 /// <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());
     }
 }
Пример #5
0
        /// <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);
        }
Пример #6
0
 /// <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);
 }
Пример #7
0
        // 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);
                    }
                }
            }
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        /* 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;
                }
            }
        }
Пример #11
0
 public override int Doc()
 {
     return(reqScorer.Doc());            // reqScorer may be null when next() or skipTo() already return false
 }
Пример #12
0
 public override int Doc()
 {
     return(scorer.Doc());
 }
Пример #13
0
 public override int Doc()
 {
     return(countingSumScorer.Doc());
 }