// Delete by query private static long ApplyQueryDeletes(IEnumerable <QueryAndLimit> queriesIter, ReadersAndUpdates rld, SegmentReader reader) { long delCount = 0; AtomicReaderContext readerContext = reader.AtomicContext; bool any = false; foreach (QueryAndLimit ent in queriesIter) { Query query = ent.Query; int limit = ent.Limit; DocIdSet docs = (new QueryWrapperFilter(query)).GetDocIdSet(readerContext, reader.LiveDocs); if (docs != null) { DocIdSetIterator it = docs.GetIterator(); if (it != null) { while (true) { int doc = it.NextDoc(); if (doc >= limit) { break; } if (!any) { rld.InitWritableLiveDocs(); any = true; } if (rld.Delete(doc)) { delCount++; } } } } } return(delCount); }
// Delete by Term private long ApplyTermDeletes(IEnumerable <Term> termsIter, ReadersAndUpdates rld, SegmentReader reader) { UninterruptableMonitor.Enter(this); try { long delCount = 0; Fields fields = reader.Fields; if (fields is null) { // this reader has no postings return(0); } TermsEnum termsEnum = null; string currentField = null; DocsEnum docs = null; if (Debugging.AssertsEnabled) { Debugging.Assert(CheckDeleteTerm(null)); } bool any = false; //System.out.println(Thread.currentThread().getName() + " del terms reader=" + reader); foreach (Term term in termsIter) { // Since we visit terms sorted, we gain performance // by re-using the same TermsEnum and seeking only // forwards if (!string.Equals(term.Field, currentField, StringComparison.Ordinal)) { if (Debugging.AssertsEnabled) { Debugging.Assert(currentField is null || currentField.CompareToOrdinal(term.Field) < 0); } currentField = term.Field; Terms terms = fields.GetTerms(currentField); if (terms != null) { termsEnum = terms.GetEnumerator(termsEnum); } else { termsEnum = null; } } if (termsEnum is null) { continue; } if (Debugging.AssertsEnabled) { Debugging.Assert(CheckDeleteTerm(term)); } // System.out.println(" term=" + term); if (termsEnum.SeekExact(term.Bytes)) { // we don't need term frequencies for this DocsEnum docsEnum = termsEnum.Docs(rld.LiveDocs, docs, DocsFlags.NONE); //System.out.println("BDS: got docsEnum=" + docsEnum); if (docsEnum != null) { while (true) { int docID = docsEnum.NextDoc(); //System.out.println(Thread.currentThread().getName() + " del term=" + term + " doc=" + docID); if (docID == DocIdSetIterator.NO_MORE_DOCS) { break; } if (!any) { rld.InitWritableLiveDocs(); any = true; } // NOTE: there is no limit check on the docID // when deleting by Term (unlike by Query) // because on flush we apply all Term deletes to // each segment. So all Term deleting here is // against prior segments: if (rld.Delete(docID)) { delCount++; } } } } } return(delCount); } finally { UninterruptableMonitor.Exit(this); } }