Skip to content

Commit 2df50ad

Browse files
authored
fix: duplicated config items issue (#2954)
1 parent db0546d commit 2df50ad

File tree

5 files changed

+74
-37
lines changed

5 files changed

+74
-37
lines changed
Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
using JetBrains.Annotations;
2+
using System;
23

34
namespace BenchmarkDotNet.Columns
45
{
56
[PublicAPI]
6-
public class ColumnHidingByIdRule: IColumnHidingRule
7+
public sealed class ColumnHidingByIdRule : IColumnHidingRule, IEquatable<ColumnHidingByIdRule>
78
{
89
public string Id { get; }
910

1011
public ColumnHidingByIdRule(IColumn column) => Id = column.Id;
1112

1213
public bool NeedToHide(IColumn column) => column.Id == Id;
14+
15+
public bool Equals(ColumnHidingByIdRule? other)
16+
{
17+
if (ReferenceEquals(null, other))
18+
return false;
19+
if (ReferenceEquals(this, other))
20+
return true;
21+
return Id == other.Id;
22+
}
23+
24+
public override bool Equals(object? obj)
25+
=> Equals(obj as ColumnHidingByIdRule);
26+
27+
public override int GetHashCode()
28+
=> HashCode.Combine(Id);
1329
}
14-
}
30+
}
Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,31 @@
11
using JetBrains.Annotations;
2+
using System;
23

34
namespace BenchmarkDotNet.Columns
45
{
56
[PublicAPI]
6-
public class ColumnHidingByNameRule: IColumnHidingRule
7+
public sealed class ColumnHidingByNameRule : IColumnHidingRule, IEquatable<ColumnHidingByNameRule>
78
{
89
public string Name { get; }
910

1011
public ColumnHidingByNameRule(string name) => Name = name;
1112

1213
public bool NeedToHide(IColumn column) => column.ColumnName == Name;
14+
15+
public bool Equals(ColumnHidingByNameRule? other)
16+
{
17+
if (ReferenceEquals(null, other))
18+
return false;
19+
if (ReferenceEquals(this, other))
20+
return true;
21+
22+
return Name == other.Name;
23+
}
24+
25+
public override bool Equals(object? obj)
26+
=> Equals(obj as ColumnHidingByNameRule);
27+
28+
public override int GetHashCode()
29+
=> HashCode.Combine(Name);
1330
}
14-
}
31+
}

src/BenchmarkDotNet/Configs/ManualConfig.cs

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.ComponentModel;
43
using System.Globalization;
54
using System.Linq;
65
using BenchmarkDotNet.Analysers;
@@ -118,49 +117,49 @@ public ManualConfig WithWakeLock(WakeLockType wakeLockType)
118117

119118
public ManualConfig AddColumn(params IColumn[] newColumns)
120119
{
121-
columnProviders.AddRange(newColumns.Select(c => c.ToProvider()));
120+
columnProviders.AddRangeDistinct(newColumns.Select(c => c.ToProvider()));
122121
return this;
123122
}
124123

125124
public ManualConfig AddColumnProvider(params IColumnProvider[] newColumnProviders)
126125
{
127-
columnProviders.AddRange(newColumnProviders);
126+
columnProviders.AddRangeDistinct(newColumnProviders);
128127
return this;
129128
}
130129

131130
public ManualConfig AddExporter(params IExporter[] newExporters)
132131
{
133-
exporters.AddRange(newExporters);
132+
exporters.AddRangeDistinct(newExporters);
134133
return this;
135134
}
136135

137136
public ManualConfig AddLogger(params ILogger[] newLoggers)
138137
{
139-
loggers.AddRange(newLoggers);
138+
loggers.AddRangeDistinct(newLoggers);
140139
return this;
141140
}
142141

143142
public ManualConfig AddDiagnoser(params IDiagnoser[] newDiagnosers)
144143
{
145-
diagnosers.AddRange(newDiagnosers);
144+
diagnosers.AddRangeDistinct(newDiagnosers);
146145
return this;
147146
}
148147

149148
public ManualConfig AddAnalyser(params IAnalyser[] newAnalysers)
150149
{
151-
analysers.AddRange(newAnalysers);
150+
analysers.AddRangeDistinct(newAnalysers);
152151
return this;
153152
}
154153

155154
public ManualConfig AddValidator(params IValidator[] newValidators)
156155
{
157-
validators.AddRange(newValidators);
156+
validators.AddRangeDistinct(newValidators);
158157
return this;
159158
}
160159

161160
public ManualConfig AddJob(params Job[] newJobs)
162161
{
163-
jobs.AddRange(newJobs.Select(j => j.Freeze())); // DONTTOUCH: please DO NOT remove .Freeze() call.
162+
jobs.AddRangeDistinct(newJobs.Select(j => j.Freeze())); // DONTTOUCH: please DO NOT remove .Freeze() call.
164163
return this;
165164
}
166165

@@ -172,68 +171,63 @@ public ManualConfig AddHardwareCounters(params HardwareCounter[] newHardwareCoun
172171

173172
public ManualConfig AddFilter(params IFilter[] newFilters)
174173
{
175-
filters.AddRange(newFilters);
174+
filters.AddRangeDistinct(newFilters);
176175
return this;
177176
}
178177

179178
public ManualConfig AddLogicalGroupRules(params BenchmarkLogicalGroupRule[] rules)
180179
{
181-
foreach (var rule in rules)
182-
{
183-
if (logicalGroupRules.Contains(rule))
184-
logicalGroupRules.Remove(rule);
185-
logicalGroupRules.Add(rule);
186-
}
180+
logicalGroupRules.AddRangeDistinct(rules);
187181
return this;
188182
}
189183

190184
public ManualConfig AddEventProcessor(params EventProcessor[] newEventProcessors)
191185
{
192-
this.eventProcessors.AddRange(newEventProcessors);
186+
eventProcessors.AddRangeDistinct(newEventProcessors);
193187
return this;
194188
}
195189

196190
[PublicAPI]
197191
public ManualConfig HideColumns(params string[] columnNames)
198192
{
199-
columnHidingRules.AddRange(columnNames.Select(c => new ColumnHidingByNameRule(c)));
193+
columnHidingRules.AddRangeDistinct(columnNames.Select(c => new ColumnHidingByNameRule(c)));
200194
return this;
201195
}
202196

203197
[PublicAPI]
204198
public ManualConfig HideColumns(params IColumn[] columns)
205199
{
206-
columnHidingRules.AddRange(columns.Select(c => new ColumnHidingByIdRule(c)));
200+
columnHidingRules.AddRangeDistinct(columns.Select(c => new ColumnHidingByIdRule(c)));
207201
return this;
208202
}
209203

210204
[PublicAPI]
211205
public ManualConfig HideColumns(params IColumnHidingRule[] rules)
212206
{
213-
columnHidingRules.AddRange(rules);
207+
columnHidingRules.AddRangeDistinct(rules);
214208
return this;
215209
}
216210

217211
[PublicAPI]
218212
public void Add(IConfig config)
219213
{
220-
columnProviders.AddRange(config.GetColumnProviders());
221-
exporters.AddRange(config.GetExporters());
222-
loggers.AddRange(config.GetLoggers());
223-
diagnosers.AddRange(config.GetDiagnosers());
224-
analysers.AddRange(config.GetAnalysers());
225-
jobs.AddRange(config.GetJobs());
226-
validators.AddRange(config.GetValidators());
214+
columnProviders.AddRangeDistinct(config.GetColumnProviders());
215+
exporters.AddRangeDistinct(config.GetExporters());
216+
loggers.AddRangeDistinct(config.GetLoggers());
217+
diagnosers.AddRangeDistinct(config.GetDiagnosers());
218+
analysers.AddRangeDistinct(config.GetAnalysers());
219+
jobs.AddRangeDistinct(config.GetJobs());
220+
validators.AddRangeDistinct(config.GetValidators());
227221
hardwareCounters.AddRange(config.GetHardwareCounters());
228-
filters.AddRange(config.GetFilters());
229-
eventProcessors.AddRange(config.GetEventProcessors());
222+
filters.AddRangeDistinct(config.GetFilters());
223+
eventProcessors.AddRangeDistinct(config.GetEventProcessors());
230224
Orderer = config.Orderer ?? Orderer;
231225
CategoryDiscoverer = config.CategoryDiscoverer ?? CategoryDiscoverer;
232226
ArtifactsPath = config.ArtifactsPath ?? ArtifactsPath;
233227
CultureInfo = config.CultureInfo ?? CultureInfo;
234228
SummaryStyle = config.SummaryStyle ?? SummaryStyle;
235-
logicalGroupRules.AddRange(config.GetLogicalGroupRules());
236-
columnHidingRules.AddRange(config.GetColumnHidingRules());
229+
logicalGroupRules.AddRangeDistinct(config.GetLogicalGroupRules());
230+
columnHidingRules.AddRangeDistinct(config.GetColumnHidingRules());
237231
Options |= config.Options;
238232
BuildTimeout = GetBuildTimeout(BuildTimeout, config.BuildTimeout);
239233
WakeLock = GetWakeLock(WakeLock, config.WakeLock);

src/BenchmarkDotNet/Extensions/CommonExtensions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ public static void AddRange<T>(this HashSet<T> hashSet, IEnumerable<T> collectio
4545
hashSet.Add(item);
4646
}
4747

48+
public static void AddRangeDistinct<T>(this List<T> list, IEnumerable<T> items, IEqualityComparer<T>? comparer = null)
49+
{
50+
var hashSet = new HashSet<T>(list, comparer);
51+
foreach (var item in items)
52+
{
53+
if (hashSet.Add(item))
54+
list.Add(item);
55+
}
56+
}
57+
4858
#if NETSTANDARD2_0
4959
public static TValue? GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
5060
=> dictionary.TryGetValue(key, out var value) ? value : default;

src/BenchmarkDotNet/Order/DefaultOrderer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics.CodeAnalysis;
55
using System.Linq;
66
using BenchmarkDotNet.Configs;
7+
using BenchmarkDotNet.Extensions;
78
using BenchmarkDotNet.Jobs;
89
using BenchmarkDotNet.Parameters;
910
using BenchmarkDotNet.Reports;
@@ -110,8 +111,7 @@ public string GetLogicalGroupKey(ImmutableArray<BenchmarkCase> allBenchmarksCase
110111
}
111112

112113
var rules = new List<BenchmarkLogicalGroupRule>(explicitRules);
113-
foreach (var rule in implicitRules.Where(rule => !rules.Contains(rule)))
114-
rules.Add(rule);
114+
rules.AddRangeDistinct(implicitRules);
115115

116116
var keys = new List<string>();
117117
foreach (var rule in rules)

0 commit comments

Comments
 (0)