blob: 13bb99b562fccb86a41dde5660a5bc059b2687cb [file] [log] [blame]
using NUnit.Framework;
using Assert = Lucene.Net.TestFramework.Assert;
namespace Lucene.Net.Search
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
using Directory = Lucene.Net.Store.Directory;
using IndexReader = Lucene.Net.Index.IndexReader;
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
using Term = Lucene.Net.Index.Term;
[TestFixture]
public class TestScoreCachingWrappingScorer : LuceneTestCase
{
private sealed class SimpleScorer : Scorer
{
private int idx = 0;
private int doc = -1;
public SimpleScorer(Weight weight)
: base(weight)
{
}
public override float GetScore()
{
// advance idx on purpose, so that consecutive calls to score will get
// different results. this is to emulate computation of a score. If
// ScoreCachingWrappingScorer is used, this should not be called more than
// once per document.
return idx == scores.Length ? float.NaN : scores[idx++];
}
public override int Freq => 1;
public override int DocID => doc;
public override int NextDoc()
{
return ++doc < scores.Length ? doc : NO_MORE_DOCS;
}
public override int Advance(int target)
{
doc = target;
return doc < scores.Length ? doc : NO_MORE_DOCS;
}
public override long GetCost()
{
return scores.Length;
}
}
private sealed class ScoreCachingCollector : ICollector
{
private int idx = 0;
private Scorer scorer;
public readonly float[] mscores;
public ScoreCachingCollector(int numToCollect)
{
mscores = new float[numToCollect];
}
public void Collect(int doc)
{
// just a sanity check to avoid IOOB.
if (idx == mscores.Length)
{
return;
}
// just call score() a couple of times and record the score.
mscores[idx] = scorer.GetScore();
mscores[idx] = scorer.GetScore();
mscores[idx] = scorer.GetScore();
++idx;
}
public void SetNextReader(AtomicReaderContext context)
{
}
public void SetScorer(Scorer scorer)
{
this.scorer = new ScoreCachingWrappingScorer(scorer);
}
public bool AcceptsDocsOutOfOrder => true;
}
private static readonly float[] scores = new float[] { 0.7767749f, 1.7839992f, 8.9925785f, 7.9608946f, 0.07948637f, 2.6356435f, 7.4950366f, 7.1490803f, 8.108544f, 4.961808f, 2.2423935f, 7.285586f, 4.6699767f };
[Test]
public virtual void TestGetScores()
{
Directory directory = NewDirectory();
RandomIndexWriter writer = new RandomIndexWriter(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, directory);
writer.Commit();
IndexReader ir = writer.GetReader();
writer.Dispose();
IndexSearcher searcher = NewSearcher(ir);
Weight fake = (new TermQuery(new Term("fake", "weight"))).CreateWeight(searcher);
Scorer s = new SimpleScorer(fake);
ScoreCachingCollector scc = new ScoreCachingCollector(scores.Length);
scc.SetScorer(s);
// We need to iterate on the scorer so that its doc() advances.
int doc;
while ((doc = s.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
{
scc.Collect(doc);
}
for (int i = 0; i < scores.Length; i++)
{
Assert.AreEqual(scores[i], scc.mscores[i], 0f);
}
ir.Dispose();
directory.Dispose();
}
}
}