| 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 Document = Documents.Document; |
| using IndexReader = Lucene.Net.Index.IndexReader; |
| using LuceneTestCase = Lucene.Net.Util.LuceneTestCase; |
| using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter; |
| |
| [TestFixture] |
| public class TestTopDocsCollector : LuceneTestCase |
| { |
| private sealed class MyTopsDocCollector : TopDocsCollector<ScoreDoc> |
| { |
| private int idx = 0; |
| private int @base = 0; |
| |
| public MyTopsDocCollector(int size) |
| : base(new HitQueue(size, false)) |
| { |
| } |
| |
| protected override TopDocs NewTopDocs(ScoreDoc[] results, int start) |
| { |
| if (results == null) |
| { |
| return EMPTY_TOPDOCS; |
| } |
| |
| float maxScore = float.NaN; |
| if (start == 0) |
| { |
| maxScore = results[0].Score; |
| } |
| else |
| { |
| for (int i = m_pq.Count; i > 1; i--) |
| { |
| m_pq.Pop(); |
| } |
| maxScore = m_pq.Pop().Score; |
| } |
| |
| return new TopDocs(TotalHits, results, maxScore); |
| } |
| |
| public override void Collect(int doc) |
| { |
| ++TotalHits; |
| m_pq.InsertWithOverflow(new ScoreDoc(doc + @base, scores[idx++])); |
| } |
| |
| public override void SetNextReader(AtomicReaderContext context) |
| { |
| @base = context.DocBase; |
| } |
| |
| public override void SetScorer(Scorer scorer) |
| { |
| // Don't do anything. Assign scores in random |
| } |
| |
| public override bool AcceptsDocsOutOfOrder => true; |
| } |
| |
| // Scores array to be used by MyTopDocsCollector. If it is changed, MAX_SCORE |
| // must also change. |
| 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, 2.9655676f, 6.953706f, 5.383931f, 6.9916306f, 8.365894f, 7.888485f, 8.723962f, 3.1796896f, 0.39971232f, 1.3077754f, 6.8489285f, 9.17561f, 5.060466f, 7.9793315f, 8.601509f, 4.1858315f, 0.28146625f }; |
| |
| private const float MAX_SCORE = 9.17561f; |
| |
| private Directory dir; |
| private IndexReader reader; |
| |
| private TopDocsCollector<ScoreDoc> DoSearch(int numResults) |
| { |
| Query q = new MatchAllDocsQuery(); |
| IndexSearcher searcher = NewSearcher(reader); |
| TopDocsCollector<ScoreDoc> tdc = new MyTopsDocCollector(numResults); |
| searcher.Search(q, tdc); |
| return tdc; |
| } |
| |
| [SetUp] |
| public override void SetUp() |
| { |
| base.SetUp(); |
| |
| // populate an index with 30 documents, this should be enough for the test. |
| // The documents have no content - the test uses MatchAllDocsQuery(). |
| dir = NewDirectory(); |
| RandomIndexWriter writer = new RandomIndexWriter( |
| #if FEATURE_INSTANCE_TESTDATA_INITIALIZATION |
| this, |
| #endif |
| Random, dir); |
| for (int i = 0; i < 30; i++) |
| { |
| writer.AddDocument(new Document()); |
| } |
| reader = writer.GetReader(); |
| writer.Dispose(); |
| } |
| |
| [TearDown] |
| public override void TearDown() |
| { |
| reader.Dispose(); |
| dir.Dispose(); |
| dir = null; |
| base.TearDown(); |
| } |
| |
| [Test] |
| public virtual void TestInvalidArguments() |
| { |
| int numResults = 5; |
| TopDocsCollector<ScoreDoc> tdc = DoSearch(numResults); |
| |
| // start < 0 |
| Assert.AreEqual(0, tdc.GetTopDocs(-1).ScoreDocs.Length); |
| |
| // start > pq.Size() |
| Assert.AreEqual(0, tdc.GetTopDocs(numResults + 1).ScoreDocs.Length); |
| |
| // start == pq.Size() |
| Assert.AreEqual(0, tdc.GetTopDocs(numResults).ScoreDocs.Length); |
| |
| // howMany < 0 |
| Assert.AreEqual(0, tdc.GetTopDocs(0, -1).ScoreDocs.Length); |
| |
| // howMany == 0 |
| Assert.AreEqual(0, tdc.GetTopDocs(0, 0).ScoreDocs.Length); |
| } |
| |
| [Test] |
| public virtual void TestZeroResults() |
| { |
| TopDocsCollector<ScoreDoc> tdc = new MyTopsDocCollector(5); |
| Assert.AreEqual(0, tdc.GetTopDocs(0, 1).ScoreDocs.Length); |
| } |
| |
| [Test] |
| public virtual void TestFirstResultsPage() |
| { |
| TopDocsCollector<ScoreDoc> tdc = DoSearch(15); |
| Assert.AreEqual(10, tdc.GetTopDocs(0, 10).ScoreDocs.Length); |
| } |
| |
| [Test] |
| public virtual void TestSecondResultsPages() |
| { |
| TopDocsCollector<ScoreDoc> tdc = DoSearch(15); |
| // ask for more results than are available |
| Assert.AreEqual(5, tdc.GetTopDocs(10, 10).ScoreDocs.Length); |
| |
| // ask for 5 results (exactly what there should be |
| tdc = DoSearch(15); |
| Assert.AreEqual(5, tdc.GetTopDocs(10, 5).ScoreDocs.Length); |
| |
| // ask for less results than there are |
| tdc = DoSearch(15); |
| Assert.AreEqual(4, tdc.GetTopDocs(10, 4).ScoreDocs.Length); |
| } |
| |
| [Test] |
| public virtual void TestGetAllResults() |
| { |
| TopDocsCollector<ScoreDoc> tdc = DoSearch(15); |
| Assert.AreEqual(15, tdc.GetTopDocs().ScoreDocs.Length); |
| } |
| |
| [Test] |
| public virtual void TestGetResultsFromStart() |
| { |
| TopDocsCollector<ScoreDoc> tdc = DoSearch(15); |
| // should bring all results |
| Assert.AreEqual(15, tdc.GetTopDocs(0).ScoreDocs.Length); |
| |
| tdc = DoSearch(15); |
| // get the last 5 only. |
| Assert.AreEqual(5, tdc.GetTopDocs(10).ScoreDocs.Length); |
| } |
| |
| [Test] |
| public virtual void TestMaxScore() |
| { |
| // ask for all results |
| TopDocsCollector<ScoreDoc> tdc = DoSearch(15); |
| TopDocs td = tdc.GetTopDocs(); |
| Assert.AreEqual(MAX_SCORE, td.MaxScore, 0f); |
| |
| // ask for 5 last results |
| tdc = DoSearch(15); |
| td = tdc.GetTopDocs(10); |
| Assert.AreEqual(MAX_SCORE, td.MaxScore, 0f); |
| } |
| |
| // this does not test the PQ's correctness, but whether topDocs() |
| // implementations return the results in decreasing score order. |
| [Test] |
| public virtual void TestResultsOrder() |
| { |
| TopDocsCollector<ScoreDoc> tdc = DoSearch(15); |
| ScoreDoc[] sd = tdc.GetTopDocs().ScoreDocs; |
| |
| Assert.AreEqual(MAX_SCORE, sd[0].Score, 0f); |
| for (int i = 1; i < sd.Length; i++) |
| { |
| Assert.IsTrue(sd[i - 1].Score >= sd[i].Score); |
| } |
| } |
| } |
| } |