blob: b2be765c06b6d16647213a21560c42b2a3242392 [file] [log] [blame]
using System.IO;
using System.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Lucene.Net.Codecs
{
/*
* 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 BinaryDocValues = Lucene.Net.Index.BinaryDocValues;
using Bits = Lucene.Net.Util.Bits;
using BytesRef = Lucene.Net.Util.BytesRef;
using FieldInfo = Lucene.Net.Index.FieldInfo;
using FilteredTermsEnum = Lucene.Net.Index.FilteredTermsEnum;
using LongBitSet = Lucene.Net.Util.LongBitSet;
using MergeState = Lucene.Net.Index.MergeState;
using NumericDocValues = Lucene.Net.Index.NumericDocValues;
using OrdinalMap = Lucene.Net.Index.MultiDocValues.OrdinalMap;
using SortedDocValues = Lucene.Net.Index.SortedDocValues;
using SortedSetDocValues = Lucene.Net.Index.SortedSetDocValues;
using TermsEnum = Lucene.Net.Index.TermsEnum;
using ArrayUtil = Lucene.Net.Util.ArrayUtil;
/// <summary>
/// Abstract API that consumes numeric, binary and
/// sorted docvalues. Concrete implementations of this
/// actually do "something" with the docvalues (write it into
/// the index in a specific format).
/// <p>
/// The lifecycle is:
/// <ol>
/// <li>DocValuesConsumer is created by
/// <seealso cref="DocValuesFormat#fieldsConsumer(SegmentWriteState)"/> or
/// <seealso cref="NormsFormat#normsConsumer(SegmentWriteState)"/>.
/// <li><seealso cref="#addNumericField"/>, <seealso cref="#addBinaryField"/>,
/// or <seealso cref="#addSortedField"/> are called for each Numeric,
/// Binary, or Sorted docvalues field. The API is a "pull" rather
/// than "push", and the implementation is free to iterate over the
/// values multiple times (<seealso cref="Iterable#iterator()"/>).
/// <li>After all fields are added, the consumer is <seealso cref="#close"/>d.
/// </ol>
///
/// @lucene.experimental
/// </summary>
public abstract class DocValuesConsumer : IDisposable
{
/// <summary>
/// Sole constructor. (For invocation by subclass
/// constructors, typically implicit.)
/// </summary>
protected internal DocValuesConsumer()
{
}
/// <summary>
/// Writes numeric docvalues for a field. </summary>
/// <param name="field"> field information </param>
/// <param name="values"> Iterable of numeric values (one for each document). {@code null} indicates
/// a missing value. </param>
/// <exception cref="IOException"> if an I/O error occurred. </exception>
public abstract void AddNumericField(FieldInfo field, IEnumerable<long?> values);
/// <summary>
/// Writes binary docvalues for a field. </summary>
/// <param name="field"> field information </param>
/// <param name="values"> Iterable of binary values (one for each document). {@code null} indicates
/// a missing value. </param>
/// <exception cref="IOException"> if an I/O error occurred. </exception>
public abstract void AddBinaryField(FieldInfo field, IEnumerable<BytesRef> values);
/// <summary>
/// Writes pre-sorted binary docvalues for a field. </summary>
/// <param name="field"> field information </param>
/// <param name="values"> Iterable of binary values in sorted order (deduplicated). </param>
/// <param name="docToOrd"> Iterable of ordinals (one for each document). {@code -1} indicates
/// a missing value. </param>
/// <exception cref="IOException"> if an I/O error occurred. </exception>
public abstract void AddSortedField(FieldInfo field, IEnumerable<BytesRef> values, IEnumerable<long?> docToOrd);
/// <summary>
/// Writes pre-sorted set docvalues for a field </summary>
/// <param name="field"> field information </param>
/// <param name="values"> Iterable of binary values in sorted order (deduplicated). </param>
/// <param name="docToOrdCount"> Iterable of the number of values for each document. A zero ordinal
/// count indicates a missing value. </param>
/// <param name="ords"> Iterable of ordinal occurrences (docToOrdCount*maxDoc total). </param>
/// <exception cref="IOException"> if an I/O error occurred. </exception>
public abstract void AddSortedSetField(FieldInfo field, IEnumerable<BytesRef> values, IEnumerable<long?> docToOrdCount, IEnumerable<long?> ords);
/// <summary>
/// Merges the numeric docvalues from <code>toMerge</code>.
/// <p>
/// The default implementation calls <seealso cref="#addNumericField"/>, passing
/// an Iterable that merges and filters deleted documents on the fly.</p>
/// </summary>
public virtual void MergeNumericField(FieldInfo fieldInfo, MergeState mergeState, IList<NumericDocValues> toMerge, IList<Bits> docsWithField)
{
AddNumericField(fieldInfo, GetMergeNumericFieldEnumerable(fieldInfo, mergeState, toMerge, docsWithField));
}
private IEnumerable<long?> GetMergeNumericFieldEnumerable(FieldInfo fieldinfo, MergeState mergeState, IList<NumericDocValues> toMerge, IList<Bits> docsWithField)
{
int readerUpto = -1;
int docIDUpto = 0;
AtomicReader currentReader = null;
NumericDocValues currentValues = null;
Bits currentLiveDocs = null;
Bits currentDocsWithField = null;
while (true)
{
if (readerUpto == toMerge.Count)
{
yield break;
}
if (currentReader == null || docIDUpto == currentReader.MaxDoc)
{
readerUpto++;
if (readerUpto < toMerge.Count)
{
currentReader = mergeState.Readers[readerUpto];
currentValues = toMerge[readerUpto];
currentDocsWithField = docsWithField[readerUpto];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpto = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.Get(docIDUpto))
{
long? nextValue;
if (currentDocsWithField.Get(docIDUpto))
{
nextValue = currentValues.Get(docIDUpto);
}
else
{
nextValue = null;
}
docIDUpto++;
yield return nextValue;
continue;
}
docIDUpto++;
}
}
/// <summary>
/// Merges the binary docvalues from <code>toMerge</code>.
/// <p>
/// The default implementation calls <seealso cref="#addBinaryField"/>, passing
/// an Iterable that merges and filters deleted documents on the fly.
/// </summary>
public void MergeBinaryField(FieldInfo fieldInfo, MergeState mergeState, IList<BinaryDocValues> toMerge, IList<Bits> docsWithField)
{
AddBinaryField(fieldInfo, GetMergeBinaryFieldEnumerable(fieldInfo, mergeState, toMerge, docsWithField));
}
private IEnumerable<BytesRef> GetMergeBinaryFieldEnumerable(FieldInfo fieldInfo, MergeState mergeState, IList<BinaryDocValues> toMerge, IList<Bits> docsWithField)
{
int readerUpto = -1;
int docIDUpto = 0;
AtomicReader currentReader = null;
BinaryDocValues currentValues = null;
Bits currentLiveDocs = null;
Bits currentDocsWithField = null;
while (true)
{
if (readerUpto == toMerge.Count)
{
yield break;
}
if (currentReader == null || docIDUpto == currentReader.MaxDoc)
{
readerUpto++;
if (readerUpto < toMerge.Count)
{
currentReader = mergeState.Readers[readerUpto];
currentValues = toMerge[readerUpto];
currentDocsWithField = docsWithField[readerUpto];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpto = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.Get(docIDUpto))
{
var nextValue = new BytesRef();
if (currentDocsWithField.Get(docIDUpto))
{
currentValues.Get(docIDUpto, nextValue);
}
else
{
nextValue = null;
}
docIDUpto++;
yield return nextValue;
continue;
}
docIDUpto++;
}
}
/// <summary>
/// Merges the sorted docvalues from <code>toMerge</code>.
/// <p>
/// The default implementation calls <seealso cref="#addSortedField"/>, passing
/// an Iterable that merges ordinals and values and filters deleted documents.</p>
/// </summary>
public virtual void MergeSortedField(FieldInfo fieldInfo, MergeState mergeState, IList<SortedDocValues> toMerge)
{
AtomicReader[] readers = mergeState.Readers.ToArray();
SortedDocValues[] dvs = toMerge.ToArray();
// step 1: iterate thru each sub and mark terms still in use
var liveTerms = new TermsEnum[dvs.Length];
for (int sub = 0; sub < liveTerms.Length; sub++)
{
AtomicReader reader = readers[sub];
SortedDocValues dv = dvs[sub];
Bits liveDocs = reader.LiveDocs;
if (liveDocs == null)
{
liveTerms[sub] = dv.TermsEnum();
}
else
{
var bitset = new LongBitSet(dv.ValueCount);
for (int i = 0; i < reader.MaxDoc; i++)
{
if (liveDocs.Get(i))
{
int ord = dv.GetOrd(i);
if (ord >= 0)
{
bitset.Set(ord);
}
}
}
liveTerms[sub] = new BitsFilteredTermsEnum(dv.TermsEnum(), bitset);
}
}
// step 2: create ordinal map (this conceptually does the "merging")
var map = new OrdinalMap(this, liveTerms);
// step 3: add field
AddSortedField(fieldInfo, GetMergeSortValuesEnumerable(map, dvs),
// doc -> ord
GetMergeSortedFieldDocToOrdEnumerable(readers, dvs, map)
);
}
private IEnumerable<BytesRef> GetMergeSortValuesEnumerable(OrdinalMap map, SortedDocValues[] dvs)
{
int currentOrd = 0;
while (currentOrd < map.ValueCount)
{
var scratch = new BytesRef();
int segmentNumber = map.GetFirstSegmentNumber(currentOrd);
var segmentOrd = (int)map.GetFirstSegmentOrd(currentOrd);
dvs[segmentNumber].LookupOrd(segmentOrd, scratch);
currentOrd++;
yield return scratch;
}
}
private IEnumerable<long?> GetMergeSortedFieldDocToOrdEnumerable(AtomicReader[] readers, SortedDocValues[] dvs, OrdinalMap map)
{
int readerUpTo = -1;
int docIDUpTo = 0;
AtomicReader currentReader = null;
Bits currentLiveDocs = null;
while (true)
{
if (readerUpTo == readers.Length)
{
yield break;
}
if (currentReader == null || docIDUpTo == currentReader.MaxDoc)
{
readerUpTo++;
if (readerUpTo < readers.Length)
{
currentReader = readers[readerUpTo];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpTo = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.Get(docIDUpTo))
{
int segOrd = dvs[readerUpTo].GetOrd(docIDUpTo);
docIDUpTo++;
yield return segOrd == -1 ? -1 : map.GetGlobalOrd(readerUpTo, segOrd);
continue;
}
docIDUpTo++;
}
}
/*
private class IterableAnonymousInnerClassHelper3 : IEnumerable<BytesRef>
{
private readonly DocValuesConsumer OuterInstance;
private SortedDocValues[] Dvs;
private OrdinalMap Map;
public IterableAnonymousInnerClassHelper3(DocValuesConsumer outerInstance, SortedDocValues[] dvs, OrdinalMap map)
{
this.OuterInstance = outerInstance;
this.Dvs = dvs;
this.Map = map;
}
// ord -> value
public virtual IEnumerator<BytesRef> GetEnumerator()
{
return new IteratorAnonymousInnerClassHelper3(this);
}
private class IteratorAnonymousInnerClassHelper3 : IEnumerator<BytesRef>
{
private readonly IterableAnonymousInnerClassHelper3 OuterInstance;
public IteratorAnonymousInnerClassHelper3(IterableAnonymousInnerClassHelper3 outerInstance)
{
this.OuterInstance = outerInstance;
scratch = new BytesRef();
}
internal readonly BytesRef scratch;
internal int currentOrd;
public virtual bool HasNext()
{
return currentOrd < OuterInstance.Map.ValueCount;
}
public virtual BytesRef Next()
{
if (!HasNext())
{
throw new Exception();
}
int segmentNumber = OuterInstance.Map.GetFirstSegmentNumber(currentOrd);
int segmentOrd = (int)OuterInstance.Map.GetFirstSegmentOrd(currentOrd);
OuterInstance.Dvs[segmentNumber].LookupOrd(segmentOrd, scratch);
currentOrd++;
return scratch;
}
public virtual void Remove()
{
throw new System.NotSupportedException();
}
}
}
private class IterableAnonymousInnerClassHelper4 : IEnumerable<Number>
{
private readonly DocValuesConsumer OuterInstance;
private AtomicReader[] Readers;
private SortedDocValues[] Dvs;
private OrdinalMap Map;
public IterableAnonymousInnerClassHelper4(DocValuesConsumer outerInstance, AtomicReader[] readers, SortedDocValues[] dvs, OrdinalMap map)
{
this.OuterInstance = outerInstance;
this.Readers = readers;
this.Dvs = dvs;
this.Map = map;
}
public virtual IEnumerator<Number> GetEnumerator()
{
return new IteratorAnonymousInnerClassHelper4(this);
}
private class IteratorAnonymousInnerClassHelper4 : IEnumerator<Number>
{
private readonly IterableAnonymousInnerClassHelper4 OuterInstance;
public IteratorAnonymousInnerClassHelper4(IterableAnonymousInnerClassHelper4 outerInstance)
{
this.OuterInstance = outerInstance;
readerUpto = -1;
}
internal int readerUpto;
internal int docIDUpto;
internal int nextValue;
internal AtomicReader currentReader;
internal Bits currentLiveDocs;
internal bool nextIsSet;
public virtual bool HasNext()
{
return nextIsSet || SetNext();
}
public virtual void Remove()
{
throw new System.NotSupportedException();
}
public virtual Number Next()
{
if (!HasNext())
{
throw new NoSuchElementException();
}
Debug.Assert(nextIsSet);
nextIsSet = false;
// TODO make a mutable number
return nextValue;
}
private bool SetNext()
{
while (true)
{
if (readerUpto == OuterInstance.Readers.Length)
{
return false;
}
if (currentReader == null || docIDUpto == currentReader.MaxDoc)
{
readerUpto++;
if (readerUpto < OuterInstance.Readers.Length)
{
currentReader = OuterInstance.Readers[readerUpto];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpto = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.get(docIDUpto))
{
nextIsSet = true;
int segOrd = OuterInstance.Dvs[readerUpto].GetOrd(docIDUpto);
nextValue = segOrd == -1 ? - 1 : (int) OuterInstance.Map.GetGlobalOrd(readerUpto, segOrd);
docIDUpto++;
return true;
}
docIDUpto++;
}
}
}
}*/
/// <summary>
/// Merges the sortedset docvalues from <code>toMerge</code>.
/// <p>
/// The default implementation calls <seealso cref="#addSortedSetField"/>, passing
/// an Iterable that merges ordinals and values and filters deleted documents .
/// </summary>
public virtual void MergeSortedSetField(FieldInfo fieldInfo, MergeState mergeState, IList<SortedSetDocValues> toMerge)
{
var readers = mergeState.Readers.ToArray();
var dvs = toMerge.ToArray();
// step 1: iterate thru each sub and mark terms still in use
var liveTerms = new TermsEnum[dvs.Length];
for (int sub = 0; sub < liveTerms.Length; sub++)
{
var reader = readers[sub];
var dv = dvs[sub];
var liveDocs = reader.LiveDocs;
if (liveDocs == null)
{
liveTerms[sub] = dv.TermsEnum();
}
else
{
var bitset = new LongBitSet(dv.ValueCount);
for (int i = 0; i < reader.MaxDoc; i++)
{
if (liveDocs.Get(i))
{
dv.Document = i;
long ord;
while ((ord = dv.NextOrd()) != SortedSetDocValues.NO_MORE_ORDS)
{
bitset.Set(ord);
}
}
}
liveTerms[sub] = new BitsFilteredTermsEnum(dv.TermsEnum(), bitset);
}
}
// step 2: create ordinal map (this conceptually does the "merging")
var map = new OrdinalMap(this, liveTerms);
// step 3: add field
AddSortedSetField(fieldInfo, GetMergeSortedSetValuesEnumerable(map, dvs),
// doc -> ord count
GetMergeSortedSetDocToOrdCountEnumerable(readers, dvs),
// ords
GetMergeSortedSetOrdsEnumerable(readers, dvs, map)
);
}
private IEnumerable<BytesRef> GetMergeSortedSetValuesEnumerable(OrdinalMap map, SortedSetDocValues[] dvs)
{
long currentOrd = 0;
while (currentOrd < map.ValueCount)
{
int segmentNumber = map.GetFirstSegmentNumber(currentOrd);
long segmentOrd = map.GetFirstSegmentOrd(currentOrd);
var scratch = new BytesRef();
dvs[segmentNumber].LookupOrd(segmentOrd, scratch);
currentOrd++;
yield return scratch;
}
}
private IEnumerable<long?> GetMergeSortedSetDocToOrdCountEnumerable(AtomicReader[] readers, SortedSetDocValues[] dvs)
{
int readerUpto = -1;
int docIDUpto = 0;
AtomicReader currentReader = null;
Bits currentLiveDocs = null;
while (true)
{
if (readerUpto == readers.Length)
{
yield break;
}
if (currentReader == null || docIDUpto == currentReader.MaxDoc)
{
readerUpto++;
if (readerUpto < readers.Length)
{
currentReader = readers[readerUpto];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpto = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.Get(docIDUpto))
{
SortedSetDocValues dv = dvs[readerUpto];
dv.Document = docIDUpto;
long value = 0;
while (dv.NextOrd() != SortedSetDocValues.NO_MORE_ORDS)
{
value++;
}
docIDUpto++;
yield return value;
continue;
}
docIDUpto++;
}
}
private IEnumerable<long?> GetMergeSortedSetOrdsEnumerable(AtomicReader[] readers, SortedSetDocValues[] dvs, OrdinalMap map)
{
int readerUpto = -1;
int docIDUpto = 0;
AtomicReader currentReader = null;
Bits currentLiveDocs = null;
var ords = new long[8];
int ordUpto = 0;
int ordLength = 0;
while (true)
{
if (readerUpto == readers.Length)
{
yield break;
}
if (ordUpto < ordLength)
{
var value = ords[ordUpto];
ordUpto++;
yield return value;
continue;
}
if (currentReader == null || docIDUpto == currentReader.MaxDoc)
{
readerUpto++;
if (readerUpto < readers.Length)
{
currentReader = readers[readerUpto];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpto = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.Get(docIDUpto))
{
Debug.Assert(docIDUpto < currentReader.MaxDoc);
SortedSetDocValues dv = dvs[readerUpto];
dv.Document = docIDUpto;
ordUpto = ordLength = 0;
long ord;
while ((ord = dv.NextOrd()) != SortedSetDocValues.NO_MORE_ORDS)
{
if (ordLength == ords.Length)
{
ords = ArrayUtil.Grow(ords, ordLength + 1);
}
ords[ordLength] = map.GetGlobalOrd(readerUpto, ord);
ordLength++;
}
docIDUpto++;
continue;
}
docIDUpto++;
}
}
/*
private class IterableAnonymousInnerClassHelper5 : IEnumerable<BytesRef>
{
private readonly DocValuesConsumer OuterInstance;
private SortedSetDocValues[] Dvs;
private OrdinalMap Map;
public IterableAnonymousInnerClassHelper5(DocValuesConsumer outerInstance, SortedSetDocValues[] dvs, OrdinalMap map)
{
this.OuterInstance = outerInstance;
this.Dvs = dvs;
this.Map = map;
}
// ord -> value
public virtual IEnumerator<BytesRef> GetEnumerator()
{
return new IteratorAnonymousInnerClassHelper5(this);
}
private class IteratorAnonymousInnerClassHelper5 : IEnumerator<BytesRef>
{
private readonly IterableAnonymousInnerClassHelper5 OuterInstance;
public IteratorAnonymousInnerClassHelper5(IterableAnonymousInnerClassHelper5 outerInstance)
{
this.OuterInstance = outerInstance;
scratch = new BytesRef();
}
internal readonly BytesRef scratch;
internal long currentOrd;
public virtual bool HasNext()
{
return currentOrd < OuterInstance.Map.ValueCount;
}
public virtual BytesRef Next()
{
if (!HasNext())
{
throw new Exception();
}
int segmentNumber = OuterInstance.Map.GetFirstSegmentNumber(currentOrd);
long segmentOrd = OuterInstance.Map.GetFirstSegmentOrd(currentOrd);
OuterInstance.Dvs[segmentNumber].LookupOrd(segmentOrd, scratch);
currentOrd++;
return scratch;
}
public virtual void Remove()
{
throw new System.NotSupportedException();
}
}
}
private class IterableAnonymousInnerClassHelper6 : IEnumerable<Number>
{
private readonly DocValuesConsumer OuterInstance;
private AtomicReader[] Readers;
private SortedSetDocValues[] Dvs;
public IterableAnonymousInnerClassHelper6(DocValuesConsumer outerInstance, AtomicReader[] readers, SortedSetDocValues[] dvs)
{
this.OuterInstance = outerInstance;
this.Readers = readers;
this.Dvs = dvs;
}
public virtual IEnumerator<Number> GetEnumerator()
{
return new IteratorAnonymousInnerClassHelper6(this);
}
private class IteratorAnonymousInnerClassHelper6 : IEnumerator<Number>
{
private readonly IterableAnonymousInnerClassHelper6 OuterInstance;
public IteratorAnonymousInnerClassHelper6(IterableAnonymousInnerClassHelper6 outerInstance)
{
this.OuterInstance = outerInstance;
readerUpto = -1;
}
internal int readerUpto;
internal int docIDUpto;
internal int nextValue;
internal AtomicReader currentReader;
internal Bits currentLiveDocs;
internal bool nextIsSet;
public virtual bool HasNext()
{
return nextIsSet || SetNext();
}
public virtual void Remove()
{
throw new System.NotSupportedException();
}
public virtual Number Next()
{
if (!HasNext())
{
throw new Exception();
}
Debug.Assert(nextIsSet);
nextIsSet = false;
// TODO make a mutable number
return nextValue;
}
private bool SetNext()
{
while (true)
{
if (readerUpto == OuterInstance.Readers.Length)
{
return false;
}
if (currentReader == null || docIDUpto == currentReader.MaxDoc)
{
readerUpto++;
if (readerUpto < OuterInstance.Readers.Length)
{
currentReader = OuterInstance.Readers[readerUpto];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpto = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.Get(docIDUpto))
{
nextIsSet = true;
SortedSetDocValues dv = OuterInstance.Dvs[readerUpto];
dv.Document = docIDUpto;
nextValue = 0;
while (dv.NextOrd() != SortedSetDocValues.NO_MORE_ORDS)
{
nextValue++;
}
docIDUpto++;
return true;
}
docIDUpto++;
}
}
}
}
private class IterableAnonymousInnerClassHelper7 : IEnumerable<Number>
{
private readonly DocValuesConsumer OuterInstance;
private AtomicReader[] Readers;
private SortedSetDocValues[] Dvs;
private OrdinalMap Map;
public IterableAnonymousInnerClassHelper7(DocValuesConsumer outerInstance, AtomicReader[] readers, SortedSetDocValues[] dvs, OrdinalMap map)
{
this.OuterInstance = outerInstance;
this.Readers = readers;
this.Dvs = dvs;
this.Map = map;
}
public virtual IEnumerator<Number> GetEnumerator()
{
return new IteratorAnonymousInnerClassHelper7(this);
}
private class IteratorAnonymousInnerClassHelper7 : IEnumerator<Number>
{
private readonly IterableAnonymousInnerClassHelper7 OuterInstance;
public IteratorAnonymousInnerClassHelper7(IterableAnonymousInnerClassHelper7 outerInstance)
{
this.OuterInstance = outerInstance;
readerUpto = -1;
ords = new long[8];
}
internal int readerUpto;
internal int docIDUpto;
internal long nextValue;
internal AtomicReader currentReader;
internal Bits currentLiveDocs;
internal bool nextIsSet;
internal long[] ords;
internal int ordUpto;
internal int ordLength;
public virtual bool HasNext()
{
return nextIsSet || SetNext();
}
public virtual void Remove()
{
throw new System.NotSupportedException();
}
public virtual Number Next()
{
if (!HasNext())
{
throw new Exception();
}
Debug.Assert(nextIsSet);
nextIsSet = false;
// TODO make a mutable number
return nextValue;
}
private bool SetNext()
{
while (true)
{
if (readerUpto == OuterInstance.Readers.Length)
{
return false;
}
if (ordUpto < ordLength)
{
nextValue = ords[ordUpto];
ordUpto++;
nextIsSet = true;
return true;
}
if (currentReader == null || docIDUpto == currentReader.MaxDoc)
{
readerUpto++;
if (readerUpto < OuterInstance.Readers.Length)
{
currentReader = OuterInstance.Readers[readerUpto];
currentLiveDocs = currentReader.LiveDocs;
}
docIDUpto = 0;
continue;
}
if (currentLiveDocs == null || currentLiveDocs.Get(docIDUpto))
{
Debug.Assert(docIDUpto < currentReader.MaxDoc);
SortedSetDocValues dv = OuterInstance.Dvs[readerUpto];
dv.Document = docIDUpto;
ordUpto = ordLength = 0;
long ord;
while ((ord = dv.NextOrd()) != SortedSetDocValues.NO_MORE_ORDS)
{
if (ordLength == ords.Length)
{
ords = ArrayUtil.Grow(ords, ordLength + 1);
}
ords[ordLength] = OuterInstance.Map.GetGlobalOrd(readerUpto, ord);
ordLength++;
}
docIDUpto++;
continue;
}
docIDUpto++;
}
}
}
}*/
// TODO: seek-by-ord to nextSetBit
internal class BitsFilteredTermsEnum : FilteredTermsEnum
{
internal readonly LongBitSet LiveTerms;
internal BitsFilteredTermsEnum(TermsEnum @in, LongBitSet liveTerms)
: base(@in, false)
{
Debug.Assert(liveTerms != null);
LiveTerms = liveTerms;
}
protected internal override AcceptStatus Accept(BytesRef term)
{
return LiveTerms.Get(Ord()) ? AcceptStatus.YES : AcceptStatus.NO;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void Dispose(bool disposing);
}
}