You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by la...@apache.org on 2023/04/13 19:45:18 UTC

[lucenenet] branch master updated: Lucene.Net.Benchmark workarounds for virtual methods called from constructors (#821)

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

laimis 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 5332e1f26 Lucene.Net.Benchmark workarounds for virtual methods called from constructors (#821)
5332e1f26 is described below

commit 5332e1f26ee7cedd60ffa467ec7a7d60fdfc2fb0
Author: Laimonas Simutis <la...@gmail.com>
AuthorDate: Thu Apr 13 12:45:11 2023 -0700

    Lucene.Net.Benchmark workarounds for virtual methods called from constructors (#821)
---
 src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs     | 25 ++++++++++++++++++----
 src/Lucene.Net.Benchmark/ByTask/Tasks/ReadTask.cs  | 16 ++++++++++++--
 .../ByTask/Tasks/WriteLineDocTask.cs               | 24 +++++++++++++++------
 3 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs b/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
index 01eb37688..a06949cce 100644
--- a/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
@@ -11,6 +11,7 @@ using Lucene.Net.Support.Threading;
 using Lucene.Net.Util;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.IO;
 using Console = Lucene.Net.Util.SystemConsole;
@@ -98,9 +99,22 @@ namespace Lucene.Net.Benchmarks.ByTask
         private readonly IDictionary<string, object> perfObjects = new Dictionary<string, object>();
 
         // constructor
-        public PerfRunData(Config config)
+        public PerfRunData(Config config) : this(
+            config,
+            performReinit: true,
+            logQueries: string.Equals(config?.Get("log.queries", "false") ?? "false", "true", StringComparison.OrdinalIgnoreCase))
+        {    
+        }
+
+        // LUCENENET specific - added performReinit parameter to allow subclasses to skip reinit
+        // since it's a virtual method. Also added logQueries parameter to allow to skip calling
+        // virtual GetQueryMarker. Subclass can call these methods itself if needed.
+        [SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", Justification = "This is a SonarCloud issue")]
+        [SuppressMessage("CodeQuality", "S1699:Constructors should only call non-overridable methods", Justification = "Required for continuity with Lucene's design")]
+        protected PerfRunData(Config config, bool performReinit, bool logQueries)
         {
-            this.config = config;
+            this.config = config ?? throw new ArgumentNullException(nameof(config));
+            
             // analyzer (default is standard analyzer)
             analyzer = NewAnalyzerTask.CreateAnalyzer(config.Get("analyzer",
                 typeof(Lucene.Net.Analysis.Standard.StandardAnalyzer).AssemblyQualifiedName));
@@ -122,12 +136,15 @@ namespace Lucene.Net.Benchmarks.ByTask
             qmkrClass = Type.GetType(config.Get("query.maker", typeof(SimpleQueryMaker).AssemblyQualifiedName));
 
             // index stuff
-            Reinit(false);
+            if (performReinit)
+            {
+                Reinit(false);
+            }
 
             // statistic points
             points = new Points(config);
 
-            if (bool.Parse(config.Get("log.queries", "false")))
+            if (logQueries)
             {
                 Console.WriteLine("------------> queries:");
                 Console.WriteLine(GetQueryMaker(new SearchTask(this)).PrintQueries());
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ReadTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReadTask.cs
index 21540eb9c..446c11313 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/ReadTask.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReadTask.cs
@@ -9,6 +9,7 @@ using System;
 using System.Collections.Generic;
 using JCG = J2N.Collections.Generic;
 using Console = Lucene.Net.Util.SystemConsole;
+using System.Diagnostics.CodeAnalysis;
 
 namespace Lucene.Net.Benchmarks.ByTask.Tasks
 {
@@ -46,10 +47,13 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
     /// </remarks>
     public abstract class ReadTask : PerfTask
     {
-        private readonly IQueryMaker queryMaker;
+        #nullable enable
+        private readonly IQueryMaker? queryMaker;
 
+        [SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", Justification = "This is a SonarCloud issue")]
+        [SuppressMessage("CodeQuality", "S1699:Constructors should only call non-overridable methods", Justification = "Required for continuity with Lucene's design")]    
         protected ReadTask(PerfRunData runData) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
-            : base(runData)
+            : this(runData, queryMaker: null)
         {
             if (WithSearch)
             {
@@ -60,6 +64,14 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
                 queryMaker = null;
             }
         }
+        // LUCENENET specific - added this constructor to allow subclasses to initialize it
+        // without having to call constructor that makes a virtual method call
+        protected ReadTask(PerfRunData runData, IQueryMaker? queryMaker)
+            : base(runData)
+        {
+            this.queryMaker = queryMaker;
+        }
+        #nullable restore
 
         public override int DoLogic()
         {
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs
index cd52cb99b..d724cfc51 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/WriteLineDocTask.cs
@@ -7,6 +7,7 @@ using Lucene.Net.Support.Threading;
 using Lucene.Net.Util;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.IO;
 using System.Text;
@@ -82,7 +83,9 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
 
         private int docSize = 0;
         protected readonly string m_fname;
-        private readonly TextWriter lineFileOut;
+        // LUCENENET specific - changed to protected to allow subclass access in case
+        // it needs to be used in WriteHeader from the subclass's constructor
+        protected readonly TextWriter m_lineFileOut;
         private readonly DocMaker docMaker;
         private readonly DisposableThreadLocal<StringBuilder> threadBuffer = new DisposableThreadLocal<StringBuilder>();
         private readonly DisposableThreadLocal<Regex> threadNormalizer = new DisposableThreadLocal<Regex>();
@@ -92,8 +95,14 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
 
         private readonly object lineFileLock = new object(); // LUCENENET specific - lock to ensure writes don't collide for this instance
 
-
         public WriteLineDocTask(PerfRunData runData)
+            : this(runData, performWriteHeader: true)
+        {
+        }
+
+        [SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", Justification = "This is a SonarCloud issue")]
+        [SuppressMessage("CodeQuality", "S1699:Constructors should only call non-overridable methods", Justification = "Required for continuity with Lucene's design")]
+        public WriteLineDocTask(PerfRunData runData, bool performWriteHeader)
             : base(runData)
         {
             Config config = runData.Config;
@@ -103,7 +112,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
                 throw new ArgumentException("line.file.out must be set");
             }
             Stream @out = StreamUtils.GetOutputStream(new FileInfo(m_fname));
-            lineFileOut = new StreamWriter(@out, Encoding.UTF8);
+            m_lineFileOut = new StreamWriter(@out, Encoding.UTF8);
             docMaker = runData.DocMaker;
 
             // init fields 
@@ -141,7 +150,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
                 }
             }
 
-            WriteHeader(lineFileOut);
+            if (performWriteHeader)
+            {
+                WriteHeader(m_lineFileOut);
+            }
         }
 
         /// <summary>
@@ -228,7 +240,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
         /// </summary>
         protected virtual TextWriter LineFileOut(Document doc)
         {
-            return lineFileOut;
+            return m_lineFileOut;
         }
 
         protected override void Dispose(bool disposing)
@@ -237,7 +249,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
             {
                 threadBuffer.Dispose(); // LUCENENET specific: ThreadLocal is disposable
                 threadNormalizer.Dispose(); // LUCENENET specific: ThreadLocal is disposable
-                lineFileOut.Dispose();
+                m_lineFileOut.Dispose();
             }
             base.Dispose(disposing);
         }