private FixedBitSet FastBits(AtomicReader reader, Bits acceptDocs) { FixedBitSet bits = new FixedBitSet(reader.MaxDoc); bits.Set(0, reader.MaxDoc); //assume all are valid Terms terms = reader.Fields.Terms(fieldName); if (terms == null) { return bits; } TermsEnum termsEnum = terms.Iterator(null); DocsEnum docs = null; while (true) { BytesRef currTerm = termsEnum.Next(); if (currTerm == null) { break; } else { if (termsEnum.DocFreq() > 1) { // unset potential duplicates docs = termsEnum.Docs(acceptDocs, docs, DocsEnum.FLAG_NONE); int doc = docs.NextDoc(); if (doc != DocIdSetIterator.NO_MORE_DOCS) { if (keepMode == KeepMode.KM_USE_FIRST_OCCURRENCE) { doc = docs.NextDoc(); } } int lastDoc = -1; while (true) { lastDoc = doc; bits.Clear(lastDoc); doc = docs.NextDoc(); if (doc == DocIdSetIterator.NO_MORE_DOCS) { break; } } if (keepMode == KeepMode.KM_USE_LAST_OCCURRENCE) { // restore the last bit bits.Set(lastDoc); } } } } return bits; }
public DocumentFilteredAtomicIndexReader(AtomicReaderContext context, Filter preserveFilter, bool negateFilter) : base(context.AtomicReader) { int maxDoc = @in.MaxDoc; FixedBitSet bits = new FixedBitSet(maxDoc); // ignore livedocs here, as we filter them later: DocIdSet docs = preserveFilter.GetDocIdSet(context, null); if (docs != null) { DocIdSetIterator it = docs.GetIterator(); if (it != null) { bits.Or(it); } } if (negateFilter) { bits.Flip(0, maxDoc); } if (@in.HasDeletions) { Bits oldLiveDocs = @in.LiveDocs; Debug.Assert(oldLiveDocs != null); DocIdSetIterator it = bits.GetIterator(); for (int i = it.NextDoc(); i < maxDoc; i = it.NextDoc()) { if (!oldLiveDocs.Get(i)) { // we can safely modify the current bit, as the iterator already stepped over it: bits.Clear(i); } } } this.liveDocs = bits; this.numDocs_Renamed = bits.Cardinality(); }