public virtual void TestLucene1516Bug() { Directory dir1 = new MockRAMDirectory(); TestIndexReaderReopen.CreateIndex(dir1, false); IndexReader r1 = IndexReader.Open(dir1, false); r1.IncRef(); IndexReader r2 = r1.Clone(false); r1.DeleteDocument(5); r1.DecRef(); r1.IncRef(); r2.Close(); r1.DecRef(); r1.Close(); dir1.Close(); }
/// <summary> Tries to reopen the subreaders. /// <br> /// If one or more subreaders could be re-opened (i. e. subReader.reopen() /// returned a new instance != subReader), then a new ParallelReader instance /// is returned, otherwise this instance is returned. /// <p> /// A re-opened instance might share one or more subreaders with the old /// instance. Index modification operations result in undefined behavior /// when performed before the old instance is closed. /// (see {@link IndexReader#Reopen()}). /// <p> /// If subreaders are shared, then the reference count of those /// readers is increased to ensure that the subreaders remain open /// until the last referring reader is closed. /// /// </summary> /// <throws> CorruptIndexException if the index is corrupt </throws> /// <throws> IOException if there is a low-level IO error </throws> public override IndexReader Reopen() { EnsureOpen(); bool reopened = false; System.Collections.IList newReaders = new System.Collections.ArrayList(); System.Collections.IList newDecrefOnClose = new System.Collections.ArrayList(); bool success = false; try { for (int i = 0; i < readers.Count; i++) { IndexReader oldReader = (IndexReader)readers[i]; IndexReader newReader = oldReader.Reopen(); newReaders.Add(newReader); // if at least one of the subreaders was updated we remember that // and return a new MultiReader if (newReader != oldReader) { reopened = true; } } if (reopened) { ParallelReader pr = new ParallelReader(); for (int i = 0; i < readers.Count; i++) { IndexReader oldReader = (IndexReader)readers[i]; IndexReader newReader = (IndexReader)newReaders[i]; if (newReader == oldReader) { newDecrefOnClose.Add(true); newReader.IncRef(); } else { // this is a new subreader instance, so on close() we don't // decRef but close it newDecrefOnClose.Add(false); } pr.Add(newReader, !storedFieldReaders.Contains(oldReader)); } pr.decrefOnClose = newDecrefOnClose; pr.incRefReaders = incRefReaders; success = true; return(pr); } else { success = true; // No subreader was refreshed return(this); } } finally { if (!success && reopened) { for (int i = 0; i < newReaders.Count; i++) { IndexReader r = (IndexReader)newReaders[i]; if (r != null) { try { if (((System.Boolean)newDecrefOnClose[i])) { r.DecRef(); } else { r.Close(); } } catch (System.IO.IOException ignore) { // keep going - we want to clean up as much as possible } } } } } }