You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2022/11/07 12:12:30 UTC

[lucenenet] branch master updated: BREAKING: Lucene.Net.Index.IndexWriter: Fixed Dispose() overloads so there is no method signature conflict between the public Dispose(waitForMerges) method and the protected Dispose(disposing) method that can be overridden and called from a finalizer. See #265.

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git


The following commit(s) were added to refs/heads/master by this push:
     new 649e178ef BREAKING: Lucene.Net.Index.IndexWriter: Fixed Dispose() overloads so there is no method signature conflict between the public Dispose(waitForMerges) method and the protected Dispose(disposing) method that can be overridden and called from a finalizer. See #265.
649e178ef is described below

commit 649e178ef64de11f6bcb0705fd1aed33bd84bc68
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Mon Nov 7 16:00:09 2022 +0700

    BREAKING: Lucene.Net.Index.IndexWriter: Fixed Dispose() overloads so there is no method signature conflict between the public Dispose(waitForMerges) method and the protected Dispose(disposing) method that can be overridden and called from a finalizer. See #265.
---
 .../Index/RandomIndexWriter.cs                     |  2 +-
 src/Lucene.Net/Index/IndexWriter.cs                | 77 +++++++++++++++++++---
 2 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/src/Lucene.Net.TestFramework/Index/RandomIndexWriter.cs b/src/Lucene.Net.TestFramework/Index/RandomIndexWriter.cs
index c665e8c70..daa030d0c 100644
--- a/src/Lucene.Net.TestFramework/Index/RandomIndexWriter.cs
+++ b/src/Lucene.Net.TestFramework/Index/RandomIndexWriter.cs
@@ -443,7 +443,7 @@ namespace Lucene.Net.Index
 
         /// <summary>
         /// Dispose this writer. </summary>
-        /// <seealso cref="IndexWriter.Dispose(bool)"/>
+        /// <seealso cref="IndexWriter.Dispose()"/>
         protected virtual void Dispose(bool disposing)
         {
             if (disposing)
diff --git a/src/Lucene.Net/Index/IndexWriter.cs b/src/Lucene.Net/Index/IndexWriter.cs
index 70e735241..941095fb7 100644
--- a/src/Lucene.Net/Index/IndexWriter.cs
+++ b/src/Lucene.Net/Index/IndexWriter.cs
@@ -1,6 +1,4 @@
 using J2N;
-using J2N.Text;
-using J2N.Threading;
 using J2N.Threading.Atomic;
 using Lucene.Net.Diagnostics;
 using Lucene.Net.Support;
@@ -8,6 +6,7 @@ using Lucene.Net.Support.Threading;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.IO;
 using System.Runtime.CompilerServices;
@@ -1090,34 +1089,96 @@ namespace Lucene.Net.Index
         [MethodImpl(MethodImplOptions.NoInlining)]
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true, waitForMerges: true);
             GC.SuppressFinalize(this);
         }
 
         /// <summary>
-        /// Closes the index with or without waiting for currently
+        /// Disposes the index with or without waiting for currently
         /// running merges to finish.  This is only meaningful when
         /// using a <see cref="MergeScheduler"/> that runs merges in background
         /// threads.
         ///
-        /// <para><b>NOTE</b>: if this method hits an <see cref="OutOfMemoryException"/>
+        /// <para><b>NOTE</b>: If this method hits an <see cref="OutOfMemoryException"/>
         /// you should immediately dispose the writer, again.  See 
         /// <see cref="IndexWriter"/> for details.</para>
         ///
-        /// <para><b>NOTE</b>: it is dangerous to always call
+        /// <para><b>NOTE</b>: It is dangerous to always call
         /// <c>Dispose(false)</c>, especially when <see cref="IndexWriter"/> is not open
         /// for very long, because this can result in "merge
         /// starvation" whereby long merges will never have a
         /// chance to finish.  This will cause too many segments in
         /// your index over time.</para>
+        ///
+        /// <para><b>NOTE</b>: This overload should not be called when implementing a finalizer.
+        /// Instead, call <see cref="Dispose(bool, bool)"/> with <c>disposing</c> set to
+        /// <c>false</c> and <c>waitForMerges</c> set to <c>true</c>.</para>
+        /// </summary>
+        /// <param name="waitForMerges"> If <c>true</c>, this call will block
+        /// until all merges complete; else, it will ask all
+        /// running merges to abort, wait until those merges have
+        /// finished (which should be at most a few seconds), and
+        /// then return. </param>
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        [SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "This is Lucene's alternate path to Dispose() and we must suppress the finalizer here.")]
+        public void Dispose(bool waitForMerges)
+        {
+            Dispose(disposing: true, waitForMerges);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Disposes the index with or without waiting for currently
+        /// running merges to finish.  This is only meaningful when
+        /// using a <see cref="MergeScheduler"/> that runs merges in background
+        /// threads.
+        ///
+        /// <para>This call will block
+        /// until all merges complete; else, it will ask all
+        /// running merges to abort, wait until those merges have
+        /// finished (which should be at most a few seconds), and
+        /// then return.
+        /// </para>
+        ///
+        /// <para><b>NOTE</b>: Always be sure to call <c>base.Dispose(disposing, waitForMerges)</c>
+        /// when overriding this method.</para>
+        ///
+        /// <para><b>NOTE</b>: When implementing a finalizer in a subclass, this overload should be called
+        /// with <paramref name="disposing"/> set to <c>false</c> and <paramref name="waitForMerges"/>
+        /// set to <c>true</c>.</para>
+        ///
+        /// <para><b>NOTE</b>: If this method hits an <see cref="OutOfMemoryException"/>
+        /// you should immediately dispose the writer, again.  See 
+        /// <see cref="IndexWriter"/> for details.</para>
+        ///
+        /// <para><b>NOTE</b>: It is dangerous to always call
+        /// with <paramref name="waitForMerges"/> set to <c>false</c>,
+        /// especially when <see cref="IndexWriter"/> is not open
+        /// for very long, because this can result in "merge
+        /// starvation" whereby long merges will never have a
+        /// chance to finish.  This will cause too many segments in
+        /// your index over time.</para>
         /// </summary>
-        /// <param name="waitForMerges"> if <c>true</c>, this call will block
+        /// <param name="waitForMerges"> If <c>true</c>, this call will block
         /// until all merges complete; else, it will ask all
         /// running merges to abort, wait until those merges have
         /// finished (which should be at most a few seconds), and
         /// then return. </param>
+        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
+        /// <c>false</c> to release only unmanaged resources. </param>
+        // LUCENENET specific - Added this overload to allow subclasses to dispose resoruces
+        // in one place without also having to override Dispose(bool).
         [MethodImpl(MethodImplOptions.NoInlining)]
-        public virtual void Dispose(bool waitForMerges) // LUCENENET TODO: API - mark protected
+        protected virtual void Dispose(bool disposing, bool waitForMerges)
+        {
+            if (disposing)
+            {
+                Close(waitForMerges);
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private void Close(bool waitForMerges)
         {
             // Ensure that only one thread actually gets to do the
             // closing, and make sure no commit is also in progress: