blob: d84ed24ad74c0c63099b38e7bf827e9a2511a5a3 [file] [log] [blame]
using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Support;
using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using Lucene.Net.Util.Fst;
using System;
using System.Collections.Generic;
using System.Text;
using JCG = J2N.Collections.Generic;
using Int64 = J2N.Numerics.Int64;
namespace Lucene.Net.Codecs.SimpleText
{
/*
* 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 ArrayUtil = Util.ArrayUtil;
using BufferedChecksumIndexInput = Store.BufferedChecksumIndexInput;
using BytesRef = Util.BytesRef;
using CharsRef = Util.CharsRef;
using ChecksumIndexInput = Store.ChecksumIndexInput;
using DocsAndPositionsEnum = Index.DocsAndPositionsEnum;
using DocsEnum = Index.DocsEnum;
using FieldInfo = Index.FieldInfo;
using FieldInfos = Index.FieldInfos;
using FixedBitSet = Util.FixedBitSet;
using FST = Util.Fst.FST;
using IBits = Util.IBits;
using IndexInput = Store.IndexInput;
using IndexOptions = Index.IndexOptions;
using Int32sRef = Util.Int32sRef;
using IOUtils = Util.IOUtils;
using PositiveInt32Outputs = Util.Fst.PositiveInt32Outputs;
using SegmentReadState = Index.SegmentReadState;
using StringHelper = Util.StringHelper;
using Terms = Index.Terms;
using TermsEnum = Index.TermsEnum;
using UnicodeUtil = Util.UnicodeUtil;
using Util = Util.Fst.Util;
internal class SimpleTextFieldsReader : FieldsProducer
{
private readonly JCG.SortedDictionary<string, long> fields;
private readonly IndexInput input;
private readonly FieldInfos fieldInfos;
private readonly int maxDoc;
public SimpleTextFieldsReader(SegmentReadState state)
{
this.maxDoc = state.SegmentInfo.DocCount;
fieldInfos = state.FieldInfos;
input = state.Directory.OpenInput(SimpleTextPostingsFormat.GetPostingsFileName(state.SegmentInfo.Name, state.SegmentSuffix), state.Context);
bool success = false;
try
{
fields = ReadFields((IndexInput)input.Clone());
success = true;
}
finally
{
if (!success)
{
IOUtils.DisposeWhileHandlingException(this);
}
}
}
private static JCG.SortedDictionary<string, long> ReadFields(IndexInput @in) // LUCENENET specific - marked static
{
ChecksumIndexInput input = new BufferedChecksumIndexInput(@in);
BytesRef scratch = new BytesRef(10);
// LUCENENET specific: Use StringComparer.Ordinal to get the same ordering as Java
var fields = new JCG.SortedDictionary<string, long>(StringComparer.Ordinal);
while (true)
{
SimpleTextUtil.ReadLine(input, scratch);
if (scratch.Equals(SimpleTextFieldsWriter.END))
{
SimpleTextUtil.CheckFooter(input);
return fields;
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.FIELD))
{
string fieldName = Encoding.UTF8.GetString(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.FIELD.Length, scratch.Length - SimpleTextFieldsWriter.FIELD.Length);
fields[fieldName] = input.Position; // LUCENENET specific: Renamed from getFilePointer() to match FileStream
}
}
}
private class SimpleTextTermsEnum : TermsEnum
{
private readonly SimpleTextFieldsReader outerInstance;
private readonly IndexOptions indexOptions;
private int docFreq;
private long totalTermFreq;
private long docsStart;
//private bool ended; // LUCENENET: Never read
private readonly BytesRefFSTEnum<PairOutputs<Int64, PairOutputs<Int64, Int64>.Pair>.Pair> fstEnum;
public SimpleTextTermsEnum(SimpleTextFieldsReader outerInstance, FST<PairOutputs<Int64, PairOutputs<Int64, Int64>.Pair>.Pair> fst, IndexOptions indexOptions)
{
this.outerInstance = outerInstance;
this.indexOptions = indexOptions;
fstEnum = new BytesRefFSTEnum<PairOutputs<Int64, PairOutputs<Int64, Int64>.Pair>.Pair>(fst);
}
public override bool SeekExact(BytesRef text)
{
var result = fstEnum.SeekExact(text);
if (result != null)
{
var pair1 = result.Output;
var pair2 = pair1.Output2;
docsStart = pair1.Output1;
docFreq = (int)pair2.Output1;
totalTermFreq = pair2.Output2;
return true;
}
else
{
return false;
}
}
public override SeekStatus SeekCeil(BytesRef text)
{
//System.out.println("seek to text=" + text.utf8ToString());
var result = fstEnum.SeekCeil(text);
if (result is null)
{
//System.out.println(" end");
return SeekStatus.END;
}
else
{
//System.out.println(" got text=" + term.utf8ToString());
var pair1 = result.Output;
var pair2 = pair1.Output2;
docsStart = pair1.Output1;
docFreq = (int)pair2.Output1;
totalTermFreq = pair2.Output2;
if (result.Input.Equals(text))
{
//System.out.println(" match docsStart=" + docsStart);
return SeekStatus.FOUND;
}
else
{
//System.out.println(" not match docsStart=" + docsStart);
return SeekStatus.NOT_FOUND;
}
}
}
public override bool MoveNext()
{
//if (Debugging.AssertsEnabled) Debugging.Assert(!ended); // LUCENENET: Ended field is never set, so this can never fail
if (fstEnum.MoveNext())
{
var pair1 = fstEnum.Current.Output;
var pair2 = pair1.Output2;
docsStart = pair1.Output1;
docFreq = (int)pair2.Output1;
totalTermFreq = pair2.Output2;
return fstEnum.Current.Input != null;
}
else
{
return false;
}
}
[Obsolete("Use MoveNext() and Term instead. This method will be removed in 4.8.0 release candidate."), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public override BytesRef Next()
{
if (MoveNext())
return fstEnum.Current.Input;
return null;
}
public override BytesRef Term => fstEnum.Current.Input;
public override long Ord => throw UnsupportedOperationException.Create();
public override void SeekExact(long ord) => throw UnsupportedOperationException.Create();
public override int DocFreq => docFreq;
public override long TotalTermFreq => indexOptions == IndexOptions.DOCS_ONLY ? -1 : totalTermFreq;
public override DocsEnum Docs(IBits liveDocs, DocsEnum reuse, DocsFlags flags)
{
if (reuse is null || !(reuse is SimpleTextDocsEnum docsEnum) || !docsEnum.CanReuse(outerInstance.input))
docsEnum = new SimpleTextDocsEnum(outerInstance);
return docsEnum.Reset(docsStart, liveDocs, indexOptions == IndexOptions.DOCS_ONLY, docFreq);
}
public override DocsAndPositionsEnum DocsAndPositions(IBits liveDocs, DocsAndPositionsEnum reuse, DocsAndPositionsFlags flags)
{
// LUCENENET specific - to avoid boxing, changed from CompareTo() to IndexOptionsComparer.Compare()
if (IndexOptionsComparer.Default.Compare(indexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0)
{
// Positions were not indexed
return null;
}
if (reuse is null || !(reuse is SimpleTextDocsAndPositionsEnum docsAndPositionsEnum) || !docsAndPositionsEnum.CanReuse(outerInstance.input))
docsAndPositionsEnum = new SimpleTextDocsAndPositionsEnum(outerInstance);
return docsAndPositionsEnum.Reset(docsStart, liveDocs, indexOptions, docFreq);
}
public override IComparer<BytesRef> Comparer => BytesRef.UTF8SortedAsUnicodeComparer;
}
private class SimpleTextDocsEnum : DocsEnum
{
private readonly IndexInput inStart;
private readonly IndexInput input;
private bool omitTF;
private int docID = -1;
private int tf;
private IBits liveDocs;
private readonly BytesRef scratch = new BytesRef(10);
private readonly CharsRef scratchUTF16 = new CharsRef(10);
private int cost;
public SimpleTextDocsEnum(SimpleTextFieldsReader outerInstance)
{
this.inStart = outerInstance.input;
this.input = (IndexInput)this.inStart.Clone();
}
public virtual bool CanReuse(IndexInput @in)
{
return @in == inStart;
}
public virtual SimpleTextDocsEnum Reset(long fp, IBits liveDocs, bool omitTF, int docFreq)
{
this.liveDocs = liveDocs;
input.Seek(fp);
this.omitTF = omitTF;
docID = -1;
tf = 1;
cost = docFreq;
return this;
}
public override int DocID => docID;
public override int Freq => tf;
public override int NextDoc()
{
if (docID == NO_MORE_DOCS)
{
return docID;
}
bool first = true;
int termFreq = 0;
while (true)
{
long lineStart = input.Position;
SimpleTextUtil.ReadLine(input, scratch);
if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.DOC))
{
if (!first && (liveDocs is null || liveDocs.Get(docID)))
{
input.Seek(lineStart);
if (!omitTF)
{
tf = termFreq;
}
return docID;
}
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.DOC.Length, scratch.Length - SimpleTextFieldsWriter.DOC.Length, scratchUTF16);
docID = ArrayUtil.ParseInt32(scratchUTF16.Chars, 0, scratchUTF16.Length);
termFreq = 0;
first = false;
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.FREQ))
{
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.FREQ.Length, scratch.Length - SimpleTextFieldsWriter.FREQ.Length, scratchUTF16);
termFreq = ArrayUtil.ParseInt32(scratchUTF16.Chars, 0, scratchUTF16.Length);
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.POS))
{
// skip termFreq++;
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.START_OFFSET))
{
// skip
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.END_OFFSET))
{
// skip
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.PAYLOAD))
{
// skip
}
else
{
if (Debugging.AssertsEnabled) Debugging.Assert(
StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.TERM)
|| StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.FIELD)
|| StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.END),
"scratch={0}", new BytesRefFormatter(scratch, BytesRefFormat.UTF8));
if (!first && (liveDocs is null || liveDocs.Get(docID)))
{
input.Seek(lineStart);
if (!omitTF)
{
tf = termFreq;
}
return docID;
}
return docID = NO_MORE_DOCS;
}
}
}
public override int Advance(int target)
{
// Naive -- better to index skip data
return SlowAdvance(target);
}
public override long GetCost() => cost;
}
private class SimpleTextDocsAndPositionsEnum : DocsAndPositionsEnum
{
private readonly IndexInput inStart;
private readonly IndexInput input;
private int docID = -1;
private int tf;
private IBits liveDocs;
private readonly BytesRef scratch = new BytesRef(10);
private readonly BytesRef scratch2 = new BytesRef(10);
private readonly CharsRef scratchUTF16 = new CharsRef(10);
private readonly CharsRef scratchUTF16_2 = new CharsRef(10);
private BytesRef payload;
private long nextDocStart;
private bool readOffsets;
private bool readPositions;
private int startOffset;
private int endOffset;
private int cost;
public SimpleTextDocsAndPositionsEnum(SimpleTextFieldsReader outerInstance)
{
this.inStart = outerInstance.input;
this.input = (IndexInput)inStart.Clone();
}
public virtual bool CanReuse(IndexInput @in)
{
return @in == inStart;
}
public virtual SimpleTextDocsAndPositionsEnum Reset(long fp, IBits liveDocs, IndexOptions indexOptions, int docFreq)
{
this.liveDocs = liveDocs;
nextDocStart = fp;
docID = -1;
// LUCENENET specific - to avoid boxing, changed from CompareTo() to IndexOptionsComparer.Compare()
readPositions = IndexOptionsComparer.Default.Compare(indexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
readOffsets = IndexOptionsComparer.Default.Compare(indexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
if (!readOffsets)
{
startOffset = -1;
endOffset = -1;
}
cost = docFreq;
return this;
}
public override int DocID => docID;
public override int Freq => tf;
public override int NextDoc()
{
bool first = true;
input.Seek(nextDocStart);
long posStart = 0;
while (true)
{
long lineStart = input.Position; // LUCENENET specific: Renamed from getFilePointer() to match FileStream
SimpleTextUtil.ReadLine(input, scratch);
//System.out.println("NEXT DOC: " + scratch.utf8ToString());
if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.DOC))
{
if (!first && (liveDocs is null || liveDocs.Get(docID)))
{
nextDocStart = lineStart;
input.Seek(posStart);
return docID;
}
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.DOC.Length, scratch.Length - SimpleTextFieldsWriter.DOC.Length, scratchUTF16);
docID = ArrayUtil.ParseInt32(scratchUTF16.Chars, 0, scratchUTF16.Length);
tf = 0;
first = false;
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.FREQ))
{
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.FREQ.Length, scratch.Length - SimpleTextFieldsWriter.FREQ.Length, scratchUTF16);
tf = ArrayUtil.ParseInt32(scratchUTF16.Chars, 0, scratchUTF16.Length);
posStart = input.Position; // LUCENENET specific: Renamed from getFilePointer() to match FileStream
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.POS))
{
// skip
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.START_OFFSET))
{
// skip
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.END_OFFSET))
{
// skip
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.PAYLOAD))
{
// skip
}
else
{
if (Debugging.AssertsEnabled) Debugging.Assert(
StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.TERM)
|| StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.FIELD)
|| StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.END));
if (!first && (liveDocs is null || liveDocs.Get(docID)))
{
nextDocStart = lineStart;
input.Seek(posStart);
return docID;
}
return docID = NO_MORE_DOCS;
}
}
}
public override int Advance(int target)
{
// Naive -- better to index skip data
return SlowAdvance(target);
}
public override int NextPosition()
{
int pos;
if (readPositions)
{
SimpleTextUtil.ReadLine(input, scratch);
// LUCENENET specific - use wrapper BytesRefFormatter struct to defer building the string unless string.Format() is called
if (Debugging.AssertsEnabled) Debugging.Assert(StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.POS), "got line={0}", new BytesRefFormatter(scratch, BytesRefFormat.UTF8));
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.POS.Length, scratch.Length - SimpleTextFieldsWriter.POS.Length, scratchUTF16_2);
pos = ArrayUtil.ParseInt32(scratchUTF16_2.Chars, 0, scratchUTF16_2.Length);
}
else
{
pos = -1;
}
if (readOffsets)
{
SimpleTextUtil.ReadLine(input, scratch);
// LUCENENET specific - use wrapper BytesRefFormatter struct to defer building the string unless string.Format() is called
if (Debugging.AssertsEnabled) Debugging.Assert(StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.START_OFFSET), "got line={0}", new BytesRefFormatter(scratch, BytesRefFormat.UTF8));
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.START_OFFSET.Length, scratch.Length - SimpleTextFieldsWriter.START_OFFSET.Length, scratchUTF16_2);
startOffset = ArrayUtil.ParseInt32(scratchUTF16_2.Chars, 0, scratchUTF16_2.Length);
SimpleTextUtil.ReadLine(input, scratch);
// LUCENENET specific - use wrapper BytesRefFormatter struct to defer building the string unless string.Format() is called
if (Debugging.AssertsEnabled) Debugging.Assert(StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.END_OFFSET), "got line={0}", new BytesRefFormatter(scratch, BytesRefFormat.UTF8));
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.END_OFFSET.Length, scratch.Length - SimpleTextFieldsWriter.END_OFFSET.Length, scratchUTF16_2);
endOffset = ArrayUtil.ParseInt32(scratchUTF16_2.Chars, 0, scratchUTF16_2.Length);
}
long fp = input.Position; // LUCENENET specific: Renamed from getFilePointer() to match FileStream
SimpleTextUtil.ReadLine(input, scratch);
if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.PAYLOAD))
{
int len = scratch.Length - SimpleTextFieldsWriter.PAYLOAD.Length;
if (scratch2.Bytes.Length < len)
{
scratch2.Grow(len);
}
Arrays.Copy(scratch.Bytes, SimpleTextFieldsWriter.PAYLOAD.Length, scratch2.Bytes, 0, len);
scratch2.Length = len;
payload = scratch2;
}
else
{
payload = null;
input.Seek(fp);
}
return pos;
}
public override int StartOffset => startOffset;
public override int EndOffset => endOffset;
public override BytesRef GetPayload() => payload;
public override long GetCost() => cost;
}
internal class TermData
{
public long DocsStart { get; set; }
public int DocFreq { get; set; }
public TermData(long docsStart, int docFreq)
{
DocsStart = docsStart;
DocFreq = docFreq;
}
}
private class SimpleTextTerms : Terms
{
private readonly SimpleTextFieldsReader outerInstance;
private readonly long termsStart;
private readonly FieldInfo fieldInfo;
private readonly int maxDoc;
private long sumTotalTermFreq;
private long sumDocFreq;
private int docCount;
private FST<PairOutputs<Int64, PairOutputs<Int64, Int64>.Pair>.Pair> fst;
private int termCount;
private readonly BytesRef scratch = new BytesRef(10);
private readonly CharsRef scratchUTF16 = new CharsRef(10);
public SimpleTextTerms(SimpleTextFieldsReader outerInstance, string field, long termsStart, int maxDoc)
{
this.outerInstance = outerInstance;
this.maxDoc = maxDoc;
this.termsStart = termsStart;
fieldInfo = outerInstance.fieldInfos.FieldInfo(field);
LoadTerms();
}
private void LoadTerms()
{
PositiveInt32Outputs posIntOutputs = PositiveInt32Outputs.Singleton;
var outputsInner = new PairOutputs<Int64, Int64>(posIntOutputs, posIntOutputs);
var outputs = new PairOutputs<Int64, PairOutputs<Int64, Int64>.Pair>(posIntOutputs,
outputsInner);
var b = new Builder<PairOutputs<Int64, PairOutputs<Int64, Int64>.Pair>.Pair>(FST.INPUT_TYPE.BYTE1, outputs);
IndexInput @in = (IndexInput)outerInstance.input.Clone();
@in.Seek(termsStart);
BytesRef lastTerm = new BytesRef(10);
long lastDocsStart = -1;
int docFreq = 0;
long totalTermFreq = 0;
FixedBitSet visitedDocs = new FixedBitSet(maxDoc);
Int32sRef scratchIntsRef = new Int32sRef();
while (true)
{
SimpleTextUtil.ReadLine(@in, scratch);
if (scratch.Equals(SimpleTextFieldsWriter.END) || StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.FIELD))
{
if (lastDocsStart != -1)
{
b.Add(Util.ToInt32sRef(lastTerm, scratchIntsRef),
outputs.NewPair(lastDocsStart,
outputsInner.NewPair((long)docFreq, totalTermFreq)));
sumTotalTermFreq += totalTermFreq;
}
break;
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.DOC))
{
docFreq++;
sumDocFreq++;
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.DOC.Length, scratch.Length - SimpleTextFieldsWriter.DOC.Length, scratchUTF16);
int docID = ArrayUtil.ParseInt32(scratchUTF16.Chars, 0, scratchUTF16.Length);
visitedDocs.Set(docID);
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.FREQ))
{
UnicodeUtil.UTF8toUTF16(scratch.Bytes, scratch.Offset + SimpleTextFieldsWriter.FREQ.Length, scratch.Length - SimpleTextFieldsWriter.FREQ.Length, scratchUTF16);
totalTermFreq += ArrayUtil.ParseInt32(scratchUTF16.Chars, 0, scratchUTF16.Length);
}
else if (StringHelper.StartsWith(scratch, SimpleTextFieldsWriter.TERM))
{
if (lastDocsStart != -1)
{
b.Add(Util.ToInt32sRef(lastTerm, scratchIntsRef), outputs.NewPair(lastDocsStart,
outputsInner.NewPair((long)docFreq, totalTermFreq)));
}
lastDocsStart = @in.Position; // LUCENENET specific: Renamed from getFilePointer() to match FileStream
int len = scratch.Length - SimpleTextFieldsWriter.TERM.Length;
if (len > lastTerm.Length)
{
lastTerm.Grow(len);
}
Arrays.Copy(scratch.Bytes, SimpleTextFieldsWriter.TERM.Length, lastTerm.Bytes, 0, len);
lastTerm.Length = len;
docFreq = 0;
sumTotalTermFreq += totalTermFreq;
totalTermFreq = 0;
termCount++;
}
}
docCount = visitedDocs.Cardinality;
fst = b.Finish();
/*
PrintStream ps = new PrintStream("out.dot");
fst.toDot(ps);
ps.close();
System.out.println("SAVED out.dot");
*/
//System.out.println("FST " + fst.sizeInBytes());
}
/// <summary>Returns approximate RAM bytes used.</summary>
public virtual long RamBytesUsed()
{
return (fst != null) ? fst.GetSizeInBytes() : 0;
}
public override TermsEnum GetEnumerator()
{
if (fst != null)
{
return new SimpleTextTermsEnum(outerInstance, fst, fieldInfo.IndexOptions);
}
else
{
return TermsEnum.EMPTY;
}
}
public override IComparer<BytesRef> Comparer => BytesRef.UTF8SortedAsUnicodeComparer;
public override long Count => (long)termCount;
public override long SumTotalTermFreq => fieldInfo.IndexOptions == IndexOptions.DOCS_ONLY ? -1 : sumTotalTermFreq;
public override long SumDocFreq => sumDocFreq;
public override int DocCount => docCount;
// LUCENENET specific - to avoid boxing, changed from CompareTo() to IndexOptionsComparer.Compare()
public override bool HasFreqs => IndexOptionsComparer.Default.Compare(fieldInfo.IndexOptions, IndexOptions.DOCS_AND_FREQS) >= 0;
public override bool HasOffsets => IndexOptionsComparer.Default.Compare(fieldInfo.IndexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
public override bool HasPositions => IndexOptionsComparer.Default.Compare(fieldInfo.IndexOptions, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
public override bool HasPayloads => fieldInfo.HasPayloads;
}
public override IEnumerator<string> GetEnumerator()
{
return fields.Keys.GetEnumerator();
}
private readonly IDictionary<string, SimpleTextTerms> termsCache = new Dictionary<string, SimpleTextTerms>();
public override Terms GetTerms(string field)
{
UninterruptableMonitor.Enter(this);
try
{
if (!termsCache.TryGetValue(field, out SimpleTextTerms terms) || terms is null)
{
if (!fields.TryGetValue(field, out long fp))
{
return null;
}
else
{
terms = new SimpleTextTerms(this, field, fp, maxDoc);
termsCache[field] = terms;
}
}
return terms;
}
finally
{
UninterruptableMonitor.Exit(this);
}
}
public override int Count => -1;
protected override void Dispose(bool disposing)
{
if (disposing)
{
input?.Dispose();
}
}
public override long RamBytesUsed()
{
long sizeInBytes = 0;
foreach (SimpleTextTerms simpleTextTerms in termsCache.Values)
{
sizeInBytes += (simpleTextTerms != null) ? simpleTextTerms.RamBytesUsed() : 0;
}
return sizeInBytes;
}
public override void CheckIntegrity()
{
}
}
}