blob: 416733f77fbd0c026f3fa42858c77fa980a25168 [file] [log] [blame]
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
using Assert = Lucene.Net.TestFramework.Assert;
using BitSet = J2N.Collections.BitSet;
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 AtomicReader = Lucene.Net.Index.AtomicReader;
using AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
using Directory = Lucene.Net.Store.Directory;
using DocIdBitSet = Lucene.Net.Util.DocIdBitSet;
using DocsEnum = Lucene.Net.Index.DocsEnum;
using Document = Documents.Document;
using Field = Field;
using FilterStrategy = Lucene.Net.Search.FilteredQuery.FilterStrategy;
using IBits = Lucene.Net.Util.IBits;
using IndexReader = Lucene.Net.Index.IndexReader;
using IOUtils = Lucene.Net.Util.IOUtils;
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
using Term = Lucene.Net.Index.Term;
using TestUtil = Lucene.Net.Util.TestUtil;
/// <summary>
/// FilteredQuery JUnit tests.
///
/// <p>Created: Apr 21, 2004 1:21:46 PM
///
///
/// @since 1.4
/// </summary>
[TestFixture]
public class TestFilteredQuery : LuceneTestCase
{
private IndexSearcher searcher;
private IndexReader reader;
private Directory directory;
private Query query;
private Filter filter;
[SetUp]
public override void SetUp()
{
base.SetUp();
directory = NewDirectory();
RandomIndexWriter writer = new RandomIndexWriter(Random, directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)).SetMergePolicy(NewLogMergePolicy()));
Document doc = new Document();
doc.Add(NewTextField("field", "one two three four five", Field.Store.YES));
doc.Add(NewTextField("sorter", "b", Field.Store.YES));
writer.AddDocument(doc);
doc = new Document();
doc.Add(NewTextField("field", "one two three four", Field.Store.YES));
doc.Add(NewTextField("sorter", "d", Field.Store.YES));
writer.AddDocument(doc);
doc = new Document();
doc.Add(NewTextField("field", "one two three y", Field.Store.YES));
doc.Add(NewTextField("sorter", "a", Field.Store.YES));
writer.AddDocument(doc);
doc = new Document();
doc.Add(NewTextField("field", "one two x", Field.Store.YES));
doc.Add(NewTextField("sorter", "c", Field.Store.YES));
writer.AddDocument(doc);
// tests here require single segment (eg try seed
// 8239472272678419952L), because SingleDocTestFilter(x)
// blindly accepts that docID in any sub-segment
writer.ForceMerge(1);
reader = writer.GetReader();
writer.Dispose();
searcher = NewSearcher(reader);
query = new TermQuery(new Term("field", "three"));
filter = NewStaticFilterB();
}
// must be static for serialization tests
private static Filter NewStaticFilterB()
{
return new FilterAnonymousClass();
}
private class FilterAnonymousClass : Filter
{
public FilterAnonymousClass()
{
}
public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
{
if (acceptDocs == null)
{
acceptDocs = new Bits.MatchAllBits(5);
}
BitSet bitset = new BitSet(5);
if (acceptDocs.Get(1))
{
bitset.Set(1);
}
if (acceptDocs.Get(3))
{
bitset.Set(3);
}
return new DocIdBitSet(bitset);
}
}
[TearDown]
public override void TearDown()
{
reader.Dispose();
directory.Dispose();
base.TearDown();
}
[Test]
public virtual void TestFilteredQuery_Mem()
{
// force the filter to be executed as bits
TFilteredQuery(true);
// force the filter to be executed as iterator
TFilteredQuery(false);
}
private void TFilteredQuery(bool useRandomAccess)
{
Query filteredquery = new FilteredQuery(query, filter, RandomFilterStrategy(Random, useRandomAccess));
ScoreDoc[] hits = searcher.Search(filteredquery, null, 1000).ScoreDocs;
Assert.AreEqual(1, hits.Length);
Assert.AreEqual(1, hits[0].Doc);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, filteredquery, searcher);
hits = searcher.Search(filteredquery, null, 1000, new Sort(new SortField("sorter", SortFieldType.STRING))).ScoreDocs;
Assert.AreEqual(1, hits.Length);
Assert.AreEqual(1, hits[0].Doc);
filteredquery = new FilteredQuery(new TermQuery(new Term("field", "one")), filter, RandomFilterStrategy(Random, useRandomAccess));
hits = searcher.Search(filteredquery, null, 1000).ScoreDocs;
Assert.AreEqual(2, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, filteredquery, searcher);
filteredquery = new FilteredQuery(new MatchAllDocsQuery(), filter, RandomFilterStrategy(Random, useRandomAccess));
hits = searcher.Search(filteredquery, null, 1000).ScoreDocs;
Assert.AreEqual(2, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, filteredquery, searcher);
filteredquery = new FilteredQuery(new TermQuery(new Term("field", "x")), filter, RandomFilterStrategy(Random, useRandomAccess));
hits = searcher.Search(filteredquery, null, 1000).ScoreDocs;
Assert.AreEqual(1, hits.Length);
Assert.AreEqual(3, hits[0].Doc);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, filteredquery, searcher);
filteredquery = new FilteredQuery(new TermQuery(new Term("field", "y")), filter, RandomFilterStrategy(Random, useRandomAccess));
hits = searcher.Search(filteredquery, null, 1000).ScoreDocs;
Assert.AreEqual(0, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, filteredquery, searcher);
// test boost
Filter f = NewStaticFilterA();
float boost = 2.5f;
BooleanQuery bq1 = new BooleanQuery();
TermQuery tq = new TermQuery(new Term("field", "one"));
tq.Boost = boost;
bq1.Add(tq, Occur.MUST);
bq1.Add(new TermQuery(new Term("field", "five")), Occur.MUST);
BooleanQuery bq2 = new BooleanQuery();
tq = new TermQuery(new Term("field", "one"));
filteredquery = new FilteredQuery(tq, f, RandomFilterStrategy(Random, useRandomAccess));
filteredquery.Boost = boost;
bq2.Add(filteredquery, Occur.MUST);
bq2.Add(new TermQuery(new Term("field", "five")), Occur.MUST);
AssertScoreEquals(bq1, bq2);
Assert.AreEqual(boost, filteredquery.Boost, 0);
Assert.AreEqual(1.0f, tq.Boost, 0); // the boost value of the underlying query shouldn't have changed
}
// must be static for serialization tests
private static Filter NewStaticFilterA()
{
return new FilterAnonymousClass2();
}
private class FilterAnonymousClass2 : Filter
{
public FilterAnonymousClass2()
{
}
public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
{
Assert.IsNull(acceptDocs, "acceptDocs should be null, as we have an index without deletions");
BitSet bitset = new BitSet(5);
bitset.Set(0, 5);
return new DocIdBitSet(bitset);
}
}
/// <summary>
/// Tests whether the scores of the two queries are the same.
/// </summary>
public virtual void AssertScoreEquals(Query q1, Query q2)
{
ScoreDoc[] hits1 = searcher.Search(q1, null, 1000).ScoreDocs;
ScoreDoc[] hits2 = searcher.Search(q2, null, 1000).ScoreDocs;
Assert.AreEqual(hits1.Length, hits2.Length);
for (int i = 0; i < hits1.Length; i++)
{
Assert.AreEqual(hits1[i].Score, hits2[i].Score, 0.000001f);
}
}
/// <summary>
/// this tests FilteredQuery's rewrite correctness
/// </summary>
[Test]
public virtual void TestRangeQuery()
{
// force the filter to be executed as bits
TRangeQuery(true);
TRangeQuery(false);
}
private void TRangeQuery(bool useRandomAccess)
{
TermRangeQuery rq = TermRangeQuery.NewStringRange("sorter", "b", "d", true, true);
Query filteredquery = new FilteredQuery(rq, filter, RandomFilterStrategy(Random, useRandomAccess));
ScoreDoc[] hits = searcher.Search(filteredquery, null, 1000).ScoreDocs;
Assert.AreEqual(2, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, filteredquery, searcher);
}
[Test]
public virtual void TestBooleanMUST()
{
// force the filter to be executed as bits
TBooleanMUST(true);
// force the filter to be executed as iterator
TBooleanMUST(false);
}
private void TBooleanMUST(bool useRandomAccess)
{
BooleanQuery bq = new BooleanQuery();
Query query = new FilteredQuery(new TermQuery(new Term("field", "one")), new SingleDocTestFilter(0), RandomFilterStrategy(Random, useRandomAccess));
bq.Add(query, Occur.MUST);
query = new FilteredQuery(new TermQuery(new Term("field", "one")), new SingleDocTestFilter(1), RandomFilterStrategy(Random, useRandomAccess));
bq.Add(query, Occur.MUST);
ScoreDoc[] hits = searcher.Search(bq, null, 1000).ScoreDocs;
Assert.AreEqual(0, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, query, searcher);
}
[Test]
public virtual void TestBooleanSHOULD()
{
// force the filter to be executed as bits
TBooleanSHOULD(true);
// force the filter to be executed as iterator
TBooleanSHOULD(false);
}
private void TBooleanSHOULD(bool useRandomAccess)
{
BooleanQuery bq = new BooleanQuery();
Query query = new FilteredQuery(new TermQuery(new Term("field", "one")), new SingleDocTestFilter(0), RandomFilterStrategy(Random, useRandomAccess));
bq.Add(query, Occur.SHOULD);
query = new FilteredQuery(new TermQuery(new Term("field", "one")), new SingleDocTestFilter(1), RandomFilterStrategy(Random, useRandomAccess));
bq.Add(query, Occur.SHOULD);
ScoreDoc[] hits = searcher.Search(bq, null, 1000).ScoreDocs;
Assert.AreEqual(2, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, query, searcher);
}
// Make sure BooleanQuery, which does out-of-order
// scoring, inside FilteredQuery, works
[Test]
public virtual void TestBoolean2()
{
// force the filter to be executed as bits
TBoolean2(true);
// force the filter to be executed as iterator
TBoolean2(false);
}
private void TBoolean2(bool useRandomAccess)
{
BooleanQuery bq = new BooleanQuery();
Query query = new FilteredQuery(bq, new SingleDocTestFilter(0), RandomFilterStrategy(Random, useRandomAccess));
bq.Add(new TermQuery(new Term("field", "one")), Occur.SHOULD);
bq.Add(new TermQuery(new Term("field", "two")), Occur.SHOULD);
ScoreDoc[] hits = searcher.Search(query, 1000).ScoreDocs;
Assert.AreEqual(1, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, query, searcher);
}
[Test]
public virtual void TestChainedFilters()
{
// force the filter to be executed as bits
TChainedFilters(true);
// force the filter to be executed as iterator
TChainedFilters(false);
}
private void TChainedFilters(bool useRandomAccess)
{
Query query = new FilteredQuery(new FilteredQuery(new MatchAllDocsQuery(), new CachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("field", "three")))), RandomFilterStrategy(Random, useRandomAccess)), new CachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("field", "four")))), RandomFilterStrategy(Random, useRandomAccess));
ScoreDoc[] hits = searcher.Search(query, 10).ScoreDocs;
Assert.AreEqual(2, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, query, searcher);
// one more:
query = new FilteredQuery(query, new CachingWrapperFilter(new QueryWrapperFilter(new TermQuery(new Term("field", "five")))), RandomFilterStrategy(Random, useRandomAccess));
hits = searcher.Search(query, 10).ScoreDocs;
Assert.AreEqual(1, hits.Length);
QueryUtils.Check(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
Random, query, searcher);
}
[Test]
public virtual void TestEqualsHashcode()
{
// some tests before, if the used queries and filters work:
Assert.AreEqual(new PrefixFilter(new Term("field", "o")), new PrefixFilter(new Term("field", "o")));
Assert.IsFalse((new PrefixFilter(new Term("field", "a"))).Equals(new PrefixFilter(new Term("field", "o"))));
QueryUtils.CheckHashEquals(new TermQuery(new Term("field", "one")));
QueryUtils.CheckUnequal(new TermQuery(new Term("field", "one")), new TermQuery(new Term("field", "two"))
);
// now test FilteredQuery equals/hashcode:
QueryUtils.CheckHashEquals(new FilteredQuery(new TermQuery(new Term("field", "one")), new PrefixFilter(new Term("field", "o"))));
QueryUtils.CheckUnequal(new FilteredQuery(new TermQuery(new Term("field", "one")), new PrefixFilter(new Term("field", "o"))), new FilteredQuery(new TermQuery(new Term("field", "two")), new PrefixFilter(new Term("field", "o")))
);
QueryUtils.CheckUnequal(new FilteredQuery(new TermQuery(new Term("field", "one")), new PrefixFilter(new Term("field", "a"))), new FilteredQuery(new TermQuery(new Term("field", "one")), new PrefixFilter(new Term("field", "o")))
);
}
[Test]
public virtual void TestInvalidArguments()
{
try
{
new FilteredQuery(null, null);
Assert.Fail("Should throw IllegalArgumentException");
}
#pragma warning disable 168
catch (ArgumentException iae)
#pragma warning restore 168
{
// pass
}
try
{
new FilteredQuery(new TermQuery(new Term("field", "one")), null);
Assert.Fail("Should throw IllegalArgumentException");
}
#pragma warning disable 168
catch (ArgumentException iae)
#pragma warning restore 168
{
// pass
}
try
{
new FilteredQuery(null, new PrefixFilter(new Term("field", "o")));
Assert.Fail("Should throw IllegalArgumentException");
}
#pragma warning disable 168
catch (ArgumentException iae)
#pragma warning restore 168
{
// pass
}
}
private FilterStrategy RandomFilterStrategy()
{
return RandomFilterStrategy(Random, true);
}
private void AssertRewrite(FilteredQuery fq, Type clazz)
{
// assign crazy boost to FQ
float boost = (float)Random.NextDouble() * 100.0f;
fq.Boost = boost;
// assign crazy boost to inner
float innerBoost = (float)Random.NextDouble() * 100.0f;
fq.Query.Boost = innerBoost;
// check the class and boosts of rewritten query
Query rewritten = searcher.Rewrite(fq);
Assert.IsTrue(clazz.IsInstanceOfType(rewritten), "is not instance of " + clazz.Name);
if (rewritten is FilteredQuery)
{
Assert.AreEqual(boost, rewritten.Boost, 1E-5f);
Assert.AreEqual(innerBoost, ((FilteredQuery)rewritten).Query.Boost, 1E-5f);
Assert.AreEqual(fq.Strategy, ((FilteredQuery)rewritten).Strategy);
}
else
{
Assert.AreEqual(boost * innerBoost, rewritten.Boost, 1E-5f);
}
// check that the original query was not modified
Assert.AreEqual(boost, fq.Boost, 1E-5f);
Assert.AreEqual(innerBoost, fq.Query.Boost, 1E-5f);
}
[Test]
public virtual void TestRewrite()
{
AssertRewrite(new FilteredQuery(new TermQuery(new Term("field", "one")), new PrefixFilter(new Term("field", "o")), RandomFilterStrategy()), typeof(FilteredQuery));
AssertRewrite(new FilteredQuery(new PrefixQuery(new Term("field", "one")), new PrefixFilter(new Term("field", "o")), RandomFilterStrategy()), typeof(FilteredQuery));
}
[Test]
public virtual void TestGetFilterStrategy()
{
FilterStrategy randomFilterStrategy = RandomFilterStrategy();
FilteredQuery filteredQuery = new FilteredQuery(new TermQuery(new Term("field", "one")), new PrefixFilter(new Term("field", "o")), randomFilterStrategy);
Assert.AreSame(randomFilterStrategy, filteredQuery.Strategy);
}
private static FilteredQuery.FilterStrategy RandomFilterStrategy(Random random, bool useRandomAccess)
{
if (useRandomAccess)
{
return new RandomAccessFilterStrategyAnonymousClass();
}
return TestUtil.RandomFilterStrategy(random);
}
private class RandomAccessFilterStrategyAnonymousClass : FilteredQuery.RandomAccessFilterStrategy
{
public RandomAccessFilterStrategyAnonymousClass()
{
}
protected override bool UseRandomAccess(IBits bits, int firstFilterDoc)
{
return true;
}
}
/*
* Test if the QueryFirst strategy calls the bits only if the document has
* been matched by the query and not otherwise
*/
[Test]
public virtual void TestQueryFirstFilterStrategy()
{
Directory directory = NewDirectory();
RandomIndexWriter writer = new RandomIndexWriter(Random, directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)));
int numDocs = AtLeast(50);
int totalDocsWithZero = 0;
for (int i = 0; i < numDocs; i++)
{
Document doc = new Document();
int num = Random.Next(5);
if (num == 0)
{
totalDocsWithZero++;
}
doc.Add(NewTextField("field", "" + num, Field.Store.YES));
writer.AddDocument(doc);
}
IndexReader reader = writer.GetReader();
writer.Dispose();
IndexSearcher searcher = NewSearcher(reader);
Query query = new FilteredQuery(new TermQuery(new Term("field", "0")), new FilterAnonymousClass3(this, reader), FilteredQuery.QUERY_FIRST_FILTER_STRATEGY);
TopDocs search = searcher.Search(query, 10);
Assert.AreEqual(totalDocsWithZero, search.TotalHits);
IOUtils.Dispose(reader, writer, directory);
}
private class FilterAnonymousClass3 : Filter
{
private readonly TestFilteredQuery outerInstance;
private IndexReader reader;
public FilterAnonymousClass3(TestFilteredQuery outerInstance, IndexReader reader)
{
this.outerInstance = outerInstance;
this.reader = reader;
}
public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
{
bool nullBitset = Random.Next(10) == 5;
AtomicReader reader = context.AtomicReader;
DocsEnum termDocsEnum = reader.GetTermDocsEnum(new Term("field", "0"));
if (termDocsEnum == null)
{
return null; // no docs -- return null
}
BitSet bitSet = new BitSet(reader.MaxDoc);
int d;
while ((d = termDocsEnum.NextDoc()) != DocsEnum.NO_MORE_DOCS)
{
bitSet.Set(d);
}
return new DocIdSetAnonymousClass(this, nullBitset, reader, bitSet);
}
private class DocIdSetAnonymousClass : DocIdSet
{
private readonly FilterAnonymousClass3 outerInstance;
private readonly bool nullBitset;
private readonly AtomicReader reader;
private readonly BitSet bitSet;
public DocIdSetAnonymousClass(FilterAnonymousClass3 outerInstance, bool nullBitset, AtomicReader reader, BitSet bitSet)
{
this.outerInstance = outerInstance;
this.nullBitset = nullBitset;
this.reader = reader;
this.bitSet = bitSet;
}
public override IBits Bits
{
get
{
if (nullBitset)
{
return null;
}
return new BitsAnonymousClass(this);
}
}
private class BitsAnonymousClass : IBits
{
private readonly DocIdSetAnonymousClass outerInstance;
public BitsAnonymousClass(DocIdSetAnonymousClass outerInstance)
{
this.outerInstance = outerInstance;
}
public bool Get(int index)
{
Assert.IsTrue(outerInstance.bitSet.Get(index), "filter was called for a non-matching doc");
return outerInstance.bitSet.Get(index);
}
public int Length => outerInstance.bitSet.Length;
}
public override DocIdSetIterator GetIterator()
{
Assert.IsTrue(nullBitset, "iterator should not be called if bitset is present");
return reader.GetTermDocsEnum(new Term("field", "0"));
}
}
}
/*
* Test if the leapfrog strategy works correctly in terms
* of advancing / next the right thing first
*/
[Test]
public virtual void TestLeapFrogStrategy()
{
Directory directory = NewDirectory();
RandomIndexWriter writer = new RandomIndexWriter(Random, directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)));
int numDocs = AtLeast(50);
int totalDocsWithZero = 0;
for (int i = 0; i < numDocs; i++)
{
Document doc = new Document();
int num = Random.Next(10);
if (num == 0)
{
totalDocsWithZero++;
}
doc.Add(NewTextField("field", "" + num, Field.Store.YES));
writer.AddDocument(doc);
}
IndexReader reader = writer.GetReader();
writer.Dispose();
bool queryFirst = Random.NextBoolean();
IndexSearcher searcher = NewSearcher(reader);
Query query = new FilteredQuery(new TermQuery(new Term("field", "0")), new FilterAnonymousClass4(this, queryFirst), queryFirst ? FilteredQuery.LEAP_FROG_QUERY_FIRST_STRATEGY : Random
.NextBoolean() ? FilteredQuery.RANDOM_ACCESS_FILTER_STRATEGY : FilteredQuery.LEAP_FROG_FILTER_FIRST_STRATEGY); // if filterFirst, we can use random here since bits are null
TopDocs search = searcher.Search(query, 10);
Assert.AreEqual(totalDocsWithZero, search.TotalHits);
IOUtils.Dispose(reader, writer, directory);
}
private class FilterAnonymousClass4 : Filter
{
private readonly TestFilteredQuery outerInstance;
private readonly bool queryFirst;
public FilterAnonymousClass4(TestFilteredQuery outerInstance, bool queryFirst)
{
this.outerInstance = outerInstance;
this.queryFirst = queryFirst;
}
public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
{
return new DocIdSetAnonymousClass2(this, context);
}
private class DocIdSetAnonymousClass2 : DocIdSet
{
private readonly FilterAnonymousClass4 outerInstance;
private readonly AtomicReaderContext context;
public DocIdSetAnonymousClass2(FilterAnonymousClass4 outerInstance, AtomicReaderContext context)
{
this.outerInstance = outerInstance;
this.context = context;
}
public override IBits Bits => null;
public override DocIdSetIterator GetIterator()
{
DocsEnum termDocsEnum = ((AtomicReader)context.Reader).GetTermDocsEnum(new Term("field", "0"));
if (termDocsEnum == null)
{
return null;
}
return new DocIdSetIteratorAnonymousClass(this, termDocsEnum);
}
private class DocIdSetIteratorAnonymousClass : DocIdSetIterator
{
private readonly DocIdSetAnonymousClass2 outerInstance;
private readonly DocsEnum termDocsEnum;
public DocIdSetIteratorAnonymousClass(DocIdSetAnonymousClass2 outerInstance, DocsEnum termDocsEnum)
{
this.outerInstance = outerInstance;
this.termDocsEnum = termDocsEnum;
}
internal bool nextCalled;
internal bool advanceCalled;
public override int NextDoc()
{
Assert.IsTrue(nextCalled || advanceCalled ^ !outerInstance.outerInstance.queryFirst, "queryFirst: " + outerInstance.outerInstance.queryFirst + " advanced: " + advanceCalled + " next: " + nextCalled);
nextCalled = true;
return termDocsEnum.NextDoc();
}
public override int DocID => termDocsEnum.DocID;
public override int Advance(int target)
{
Assert.IsTrue(advanceCalled || nextCalled ^ outerInstance.outerInstance.queryFirst, "queryFirst: " + outerInstance.outerInstance.queryFirst + " advanced: " + advanceCalled + " next: " + nextCalled);
advanceCalled = true;
return termDocsEnum.Advance(target);
}
public override long GetCost()
{
return termDocsEnum.GetCost();
}
}
}
}
}
}