in src/Lucene.Net.TestFramework/Index/BasePostingsFormatTestCase.cs [655:1059]
private void VerifyEnum(ThreadState threadState,
string field,
BytesRef term,
TermsEnum termsEnum,
// Maximum options (docs/freqs/positions/offsets) to test:
IndexOptions maxTestOptions,
IndexOptions maxIndexOptions,
ISet<Option> options,
bool alwaysTestMax)
{
if (Verbose)
{
Console.WriteLine(" verifyEnum: options=" + options + " maxTestOptions=" + maxTestOptions);
}
// Make sure TermsEnum really is positioned on the
// expected term:
Assert.AreEqual(term, termsEnum.Term);
// 50% of the time time pass liveDocs:
bool useLiveDocs = options.Contains(Option.LIVE_DOCS) && Random.NextBoolean();
IBits liveDocs;
if (useLiveDocs)
{
liveDocs = globalLiveDocs;
if (Verbose)
{
Console.WriteLine(" use liveDocs");
}
}
else
{
liveDocs = null;
if (Verbose)
{
Console.WriteLine(" no liveDocs");
}
}
FieldInfo fieldInfo = currentFieldInfos.FieldInfo(field);
// NOTE: can be empty list if we are using liveDocs:
SeedPostings expected = GetSeedPostings(term.Utf8ToString(),
fields[field][term],
useLiveDocs,
maxIndexOptions);
Assert.AreEqual(expected.DocFreq, termsEnum.DocFreq);
// LUCENENET specific - to avoid boxing, changed from CompareTo() to IndexOptionsComparer.Compare()
bool allowFreqs = IndexOptionsComparer.Default.Compare(fieldInfo.IndexOptions, IndexOptions.DOCS_AND_FREQS) >= 0 &&
IndexOptionsComparer.Default.Compare(maxTestOptions, IndexOptions.DOCS_AND_FREQS) >= 0;
bool doCheckFreqs = allowFreqs && (alwaysTestMax || Random.Next(3) <= 2);
// LUCENENET specific - to avoid boxing, changed from CompareTo() to IndexOptionsComparer.Compare()
bool allowPositions = IndexOptionsComparer.Default.Compare(fieldInfo.IndexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0 &&
IndexOptionsComparer.Default.Compare(maxTestOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
bool doCheckPositions = allowPositions && (alwaysTestMax || Random.Next(3) <= 2);
// LUCENENET specific - to avoid boxing, changed from CompareTo() to IndexOptionsComparer.Compare()
bool allowOffsets = IndexOptionsComparer.Default.Compare(fieldInfo.IndexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >=0 &&
IndexOptionsComparer.Default.Compare(maxTestOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
bool doCheckOffsets = allowOffsets && (alwaysTestMax || Random.Next(3) <= 2);
bool doCheckPayloads = options.Contains(Option.PAYLOADS) && allowPositions && fieldInfo.HasPayloads && (alwaysTestMax || Random.Next(3) <= 2);
DocsEnum prevDocsEnum = null;
DocsEnum docsEnum;
DocsAndPositionsEnum docsAndPositionsEnum;
if (!doCheckPositions)
{
if (allowPositions && Random.Next(10) == 7)
{
// 10% of the time, even though we will not check positions, pull a DocsAndPositions enum
if (options.Contains(Option.REUSE_ENUMS) && Random.Next(10) < 9)
{
prevDocsEnum = threadState.ReuseDocsAndPositionsEnum;
}
DocsAndPositionsFlags flags = 0;
if (alwaysTestMax || Random.NextBoolean())
{
flags |= DocsAndPositionsFlags.OFFSETS;
}
if (alwaysTestMax || Random.NextBoolean())
{
flags |= DocsAndPositionsFlags.PAYLOADS;
}
if (Verbose)
{
Console.WriteLine(" get DocsAndPositionsEnum (but we won't check positions) flags=" + flags);
}
threadState.ReuseDocsAndPositionsEnum = termsEnum.DocsAndPositions(liveDocs, (DocsAndPositionsEnum)prevDocsEnum, flags);
docsEnum = threadState.ReuseDocsAndPositionsEnum;
docsAndPositionsEnum = threadState.ReuseDocsAndPositionsEnum;
}
else
{
if (Verbose)
{
Console.WriteLine(" get DocsEnum");
}
if (options.Contains(Option.REUSE_ENUMS) && Random.Next(10) < 9)
{
prevDocsEnum = threadState.ReuseDocsEnum;
}
threadState.ReuseDocsEnum = termsEnum.Docs(liveDocs, prevDocsEnum, doCheckFreqs ? DocsFlags.FREQS : DocsFlags.NONE);
docsEnum = threadState.ReuseDocsEnum;
docsAndPositionsEnum = null;
}
}
else
{
if (options.Contains(Option.REUSE_ENUMS) && Random.Next(10) < 9)
{
prevDocsEnum = threadState.ReuseDocsAndPositionsEnum;
}
DocsAndPositionsFlags flags = 0;
if (alwaysTestMax || doCheckOffsets || Random.Next(3) == 1)
{
flags |= DocsAndPositionsFlags.OFFSETS;
}
if (alwaysTestMax || doCheckPayloads || Random.Next(3) == 1)
{
flags |= DocsAndPositionsFlags.PAYLOADS;
}
if (Verbose)
{
Console.WriteLine(" get DocsAndPositionsEnum flags=" + flags);
}
threadState.ReuseDocsAndPositionsEnum = termsEnum.DocsAndPositions(liveDocs, (DocsAndPositionsEnum)prevDocsEnum, flags);
docsEnum = threadState.ReuseDocsAndPositionsEnum;
docsAndPositionsEnum = threadState.ReuseDocsAndPositionsEnum;
}
Assert.IsNotNull(docsEnum, "null DocsEnum");
int initialDocID = docsEnum.DocID;
Assert.AreEqual(-1, initialDocID, "inital docID should be -1" + docsEnum);
if (Verbose)
{
if (prevDocsEnum is null)
{
Console.WriteLine(" got enum=" + docsEnum);
}
else if (prevDocsEnum == docsEnum)
{
Console.WriteLine(" got reuse enum=" + docsEnum);
}
else
{
Console.WriteLine(" got enum=" + docsEnum + " (reuse of " + prevDocsEnum + " failed)");
}
}
// 10% of the time don't consume all docs:
int stopAt;
if (!alwaysTestMax && options.Contains(Option.PARTIAL_DOC_CONSUME) && expected.DocFreq > 1 && Random.Next(10) == 7)
{
stopAt = Random.Next(expected.DocFreq - 1);
if (Verbose)
{
Console.WriteLine(" will not consume all docs (" + stopAt + " vs " + expected.DocFreq + ")");
}
}
else
{
stopAt = expected.DocFreq;
if (Verbose)
{
Console.WriteLine(" consume all docs");
}
}
double skipChance = alwaysTestMax ? 0.5 : Random.NextDouble();
int numSkips = expected.DocFreq < 3 ? 1 : TestUtil.NextInt32(Random, 1, Math.Min(20, expected.DocFreq / 3));
int skipInc = expected.DocFreq / numSkips;
int skipDocInc = maxDoc / numSkips;
// Sometimes do 100% skipping:
bool doAllSkipping = options.Contains(Option.SKIPPING) && Random.Next(7) == 1;
double freqAskChance = alwaysTestMax ? 1.0 : Random.NextDouble();
double payloadCheckChance = alwaysTestMax ? 1.0 : Random.NextDouble();
double offsetCheckChance = alwaysTestMax ? 1.0 : Random.NextDouble();
if (Verbose)
{
if (options.Contains(Option.SKIPPING))
{
Console.WriteLine(" skipChance=" + skipChance + " numSkips=" + numSkips);
}
else
{
Console.WriteLine(" no skipping");
}
if (doCheckFreqs)
{
Console.WriteLine(" freqAskChance=" + freqAskChance);
}
if (doCheckPayloads)
{
Console.WriteLine(" payloadCheckChance=" + payloadCheckChance);
}
if (doCheckOffsets)
{
Console.WriteLine(" offsetCheckChance=" + offsetCheckChance);
}
}
while (expected.Upto <= stopAt)
{
if (expected.Upto == stopAt)
{
if (stopAt == expected.DocFreq)
{
Assert.AreEqual(DocsEnum.NO_MORE_DOCS, docsEnum.NextDoc(), "DocsEnum should have ended but didn't");
// Common bug is to forget to set this.Doc=NO_MORE_DOCS in the enum!:
Assert.AreEqual(DocsEnum.NO_MORE_DOCS, docsEnum.DocID, "DocsEnum should have ended but didn't");
}
break;
}
if (options.Contains(Option.SKIPPING) && (doAllSkipping || Random.NextDouble() <= skipChance))
{
int targetDocID = -1;
if (expected.Upto < stopAt && Random.NextBoolean())
{
// Pick target we know exists:
int skipCount = TestUtil.NextInt32(Random, 1, skipInc);
for (int skip = 0; skip < skipCount; skip++)
{
if (expected.NextDoc() == DocsEnum.NO_MORE_DOCS)
{
break;
}
}
}
else
{
// Pick random target (might not exist):
int skipDocIDs = TestUtil.NextInt32(Random, 1, skipDocInc);
if (skipDocIDs > 0)
{
targetDocID = expected.DocID + skipDocIDs;
expected.Advance(targetDocID);
}
}
if (expected.Upto >= stopAt)
{
int target = Random.NextBoolean() ? maxDoc : DocsEnum.NO_MORE_DOCS;
if (Verbose)
{
Console.WriteLine(" now advance to end (target=" + target + ")");
}
Assert.AreEqual(DocsEnum.NO_MORE_DOCS, docsEnum.Advance(target), "DocsEnum should have ended but didn't");
break;
}
else
{
if (Verbose)
{
if (targetDocID != -1)
{
Console.WriteLine(" now advance to random target=" + targetDocID + " (" + expected.Upto + " of " + stopAt + ") current=" + docsEnum.DocID);
}
else
{
Console.WriteLine(" now advance to known-exists target=" + expected.DocID + " (" + expected.Upto + " of " + stopAt + ") current=" + docsEnum.DocID);
}
}
int docID = docsEnum.Advance(targetDocID != -1 ? targetDocID : expected.DocID);
Assert.AreEqual(expected.DocID, docID, "docID is wrong");
}
}
else
{
expected.NextDoc();
if (Verbose)
{
Console.WriteLine(" now nextDoc to " + expected.DocID + " (" + expected.Upto + " of " + stopAt + ")");
}
int docID = docsEnum.NextDoc();
Assert.AreEqual(expected.DocID, docID, "docID is wrong");
if (docID == DocsEnum.NO_MORE_DOCS)
{
break;
}
}
if (doCheckFreqs && Random.NextDouble() <= freqAskChance)
{
if (Verbose)
{
Console.WriteLine(" now freq()=" + expected.Freq);
}
int freq = docsEnum.Freq;
Assert.AreEqual(expected.Freq, freq, "freq is wrong");
}
if (doCheckPositions)
{
int freq = docsEnum.Freq;
int numPosToConsume;
if (!alwaysTestMax && options.Contains(Option.PARTIAL_POS_CONSUME) && Random.Next(5) == 1)
{
numPosToConsume = Random.Next(freq);
}
else
{
numPosToConsume = freq;
}
for (int i = 0; i < numPosToConsume; i++)
{
int pos = expected.NextPosition();
if (Verbose)
{
Console.WriteLine(" now nextPosition to " + pos);
}
Assert.AreEqual(pos, docsAndPositionsEnum.NextPosition(), "position is wrong");
if (doCheckPayloads)
{
BytesRef expectedPayload = expected.GetPayload();
if (Random.NextDouble() <= payloadCheckChance)
{
if (Verbose)
{
Console.WriteLine(" now check expectedPayload length=" + (expectedPayload is null ? 0 : expectedPayload.Length));
}
if (expectedPayload is null || expectedPayload.Length == 0)
{
Assert.IsNull(docsAndPositionsEnum.GetPayload(), "should not have payload");
}
else
{
BytesRef payload = docsAndPositionsEnum.GetPayload();
Assert.IsNotNull(payload, "should have payload but doesn't");
Assert.AreEqual(expectedPayload.Length, payload.Length, "payload length is wrong");
for (int byteUpto = 0; byteUpto < expectedPayload.Length; byteUpto++)
{
Assert.AreEqual(expectedPayload.Bytes[expectedPayload.Offset + byteUpto], payload.Bytes[payload.Offset + byteUpto], "payload bytes are wrong");
}
// make a deep copy
payload = BytesRef.DeepCopyOf(payload);
Assert.AreEqual(payload, docsAndPositionsEnum.GetPayload(), "2nd call to getPayload returns something different!");
}
}
else
{
if (Verbose)
{
Console.WriteLine(" skip check payload length=" + (expectedPayload is null ? 0 : expectedPayload.Length));
}
}
}
if (doCheckOffsets)
{
if (Random.NextDouble() <= offsetCheckChance)
{
if (Verbose)
{
Console.WriteLine(" now check offsets: startOff=" + expected.StartOffset + " endOffset=" + expected.EndOffset);
}
Assert.AreEqual(expected.StartOffset, docsAndPositionsEnum.StartOffset, "startOffset is wrong");
Assert.AreEqual(expected.EndOffset, docsAndPositionsEnum.EndOffset, "endOffset is wrong");
}
else
{
if (Verbose)
{
Console.WriteLine(" skip check offsets");
}
}
}
// LUCENENET specific - to avoid boxing, changed from CompareTo() to IndexOptionsComparer.Compare()
else if (IndexOptionsComparer.Default.Compare(fieldInfo.IndexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) < 0)
{
if (Verbose)
{
Console.WriteLine(" now check offsets are -1");
}
Assert.AreEqual(-1, docsAndPositionsEnum.StartOffset, "startOffset isn't -1");
Assert.AreEqual(-1, docsAndPositionsEnum.EndOffset, "endOffset isn't -1");
}
}
}
}
}