/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
namespace Lucene.Net.Search{
/// <summary>A Scorer for queries with a required part and an optional part.
/// Delays skipTo() on the optional part until a score() is needed.
/// <br>
/// This <code>Scorer</code> implements {@link Scorer#SkipTo(int)}.
/// </summary>
public class ReqOptSumScorer : Scorer
{
/// <summary>The scorers passed from the constructor.
/// These are set to null as soon as their next() or skipTo() returns false.
/// </summary>
private Scorer reqScorer;
private Scorer optScorer;
/// <summary>Construct a <code>ReqOptScorer</code>.</summary>
/// <param name="reqScorer">The required scorer. This must match.
/// </param>
/// <param name="optScorer">The optional scorer. This is used for scoring only.
/// </param>
public ReqOptSumScorer(Scorer reqScorer, Scorer optScorer) : base(null)
{ // No similarity used.
this.reqScorer = reqScorer;
this.optScorer = optScorer;
}
private bool firstTimeOptScorer = true;
public override bool Next()
{
return reqScorer.Next();
}
public override bool SkipTo(int target)
{
return reqScorer.SkipTo(target);
}
public override int Doc()
{
return reqScorer.Doc();
}
/// <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>Explain the score of a document.</summary>
/// <todo> Also show the total score. </todo>
/// <summary> See BooleanScorer.explain() on how to do this.
/// </summary>
public override Explanation Explain(int doc)
{
Explanation res = new Explanation();
res.SetDescription("required, optional");
res.AddDetail(reqScorer.Explain(doc));
res.AddDetail(optScorer.Explain(doc));
return res;
}
}
}
|