Skip to content

Commit dbdae9f

Browse files
author
Kester Maddock
committed
Use a dictionary lookup file filename to improve performance with large solutions
1 parent 27e448b commit dbdae9f

File tree

10 files changed

+41
-29
lines changed

10 files changed

+41
-29
lines changed

FineCodeCoverageTests/FCCEngine_Tests.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ private void VerifyLogsReloadCoverageStatus(ReloadCoverageStatus reloadCoverageS
333333
mocker.Verify<ILogger>(l => l.Log(fccEngine.GetLogReloadCoverageStatusMessage(reloadCoverageStatus)));
334334
}
335335

336-
private async Task<(string reportGeneratedHtmlContent, List<CoverageLine> updatedCoverageLines)> RunToCompletion(bool noCoverageProjects)
336+
private async Task<(string reportGeneratedHtmlContent, Dictionary<string, List<CoverageLine>> updatedCoverageLines)> RunToCompletion(bool noCoverageProjects)
337337
{
338338
var coverageProject = CreateSuitableProject().Object;
339339
var mockReportGenerator = mocker.GetMock<IReportGeneratorUtil>();
@@ -352,7 +352,10 @@ private void VerifyLogsReloadCoverageStatus(ReloadCoverageStatus reloadCoverageS
352352

353353
var reportGeneratedHtmlContent = "<somehtml/>";
354354
mockReportGenerator.Setup(rg => rg.ProcessUnifiedHtml("Unified", It.IsAny<string>())).Returns(reportGeneratedHtmlContent);
355-
List<CoverageLine> coverageLines = new List<CoverageLine>() { new CoverageLine() };
355+
Dictionary<string, List<CoverageLine>> coverageLines = new Dictionary<string, List<CoverageLine>>()
356+
{
357+
{ "test", new List<CoverageLine>() { new CoverageLine() } }
358+
};
356359
mocker.GetMock<ICoberturaUtil>().Setup(coberturaUtil => coberturaUtil.ProcessCoberturaXml(It.IsAny<string>())).Returns(coverageLines);
357360
if (noCoverageProjects)
358361
{
@@ -384,8 +387,10 @@ private async Task ThrowReadingReportHtml()
384387
}
385388
);
386389

387-
388-
List<CoverageLine> coverageLines = new List<CoverageLine>() { new CoverageLine() };
390+
Dictionary<string, List<CoverageLine>> coverageLines = new Dictionary<string, List<CoverageLine>>()
391+
{
392+
{ "test", new List<CoverageLine>() { new CoverageLine() } }
393+
};
389394
mocker.GetMock<ICoberturaUtil>().Setup(coberturaUtil => coberturaUtil.ProcessCoberturaXml(It.IsAny<string>())).Returns(coverageLines);
390395

391396
await ReloadInitializedCoverage(passedProject.Object);

SharedProject/Core/Cobertura/CoberturaUtil.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using FineCodeCoverage.Engine.Model;
66
using System.ComponentModel.Composition;
77
using System.IO;
8+
using System.Windows.Documents;
9+
using System;
810

911
namespace FineCodeCoverage.Engine.Cobertura
1012
{
@@ -67,19 +69,25 @@ private CoverageReport LoadReport(string xmlFile)
6769
// return jsonText;
6870
//}
6971

70-
public List<CoverageLine> ProcessCoberturaXml(string xmlFile)
72+
public Dictionary<string, List<CoverageLine>> ProcessCoberturaXml(string xmlFile)
7173
{
72-
var coverageLines = new List<CoverageLine>();
74+
var coverageLines = new Dictionary<string, List<CoverageLine>>(StringComparer.OrdinalIgnoreCase);
7375

7476
coverageReport = LoadReport(xmlFile);
7577

7678
foreach (var package in coverageReport.Packages.Package)
7779
{
7880
foreach (var classs in package.Classes.Class)
7981
{
80-
foreach (var line in classs.Lines.Line)
82+
if (!coverageLines.TryGetValue(classs.Filename, out var classCoverageLines))
8183
{
82-
coverageLines.Add(new CoverageLine
84+
classCoverageLines = new List<CoverageLine>();
85+
coverageLines.Add(string.Intern(classs.Filename), classCoverageLines);
86+
}
87+
88+
foreach (var line in classs.Lines.Line)
89+
{
90+
classCoverageLines.Add(new CoverageLine
8391
{
8492
Package = package,
8593
Class = classs,

SharedProject/Core/Cobertura/ICoberturaUtil.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace FineCodeCoverage.Engine.Cobertura
55
{
66
interface ICoberturaUtil
77
{
8-
List<CoverageLine> ProcessCoberturaXml(string xmlFile);
8+
Dictionary<string, List<CoverageLine>> ProcessCoberturaXml(string xmlFile);
99
string[] GetSourceFiles(string assemblyName, string qualifiedClassName, int file);
1010
}
1111
}

SharedProject/Core/FCCEngine.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal enum ReloadCoverageStatus { Start, Done, Cancelled, Error, Initializing
1919

2020
internal class NewCoverageLinesMessage
2121
{
22-
public List<CoverageLine> CoverageLines { get; set; }
22+
public Dictionary<string, List<CoverageLine>> CoverageLines { get; set; }
2323
}
2424

2525
internal class DisplayCoverageResultState
@@ -202,12 +202,12 @@ private void ClearCoverageLines()
202202
RaiseCoverageLines(null);
203203
}
204204

205-
private void RaiseCoverageLines(List<CoverageLine> coverageLines)
205+
private void RaiseCoverageLines(Dictionary<string, List<CoverageLine>> coverageLines)
206206
{
207207
eventAggregator.SendMessage(new NewCoverageLinesMessage { CoverageLines = coverageLines});
208208
}
209209

210-
private void UpdateUI(List<CoverageLine> coverageLines, string reportHtml)
210+
private void UpdateUI(Dictionary<string, List<CoverageLine>> coverageLines, string reportHtml)
211211
{
212212
RaiseCoverageLines(coverageLines);
213213
if (reportHtml == null)
@@ -217,18 +217,18 @@ private void UpdateUI(List<CoverageLine> coverageLines, string reportHtml)
217217
RaiseUpdateOutputWindow(reportHtml);
218218
}
219219

220-
private async System.Threading.Tasks.Task<(List<CoverageLine> coverageLines,string reportFilePath)> RunAndProcessReportAsync(string[] coverOutputFiles, CancellationToken vsShutdownLinkedCancellationToken)
220+
private async System.Threading.Tasks.Task<(Dictionary<string, List<CoverageLine>> coverageLines,string reportFilePath)> RunAndProcessReportAsync(string[] coverOutputFiles, CancellationToken vsShutdownLinkedCancellationToken)
221221
{
222222
var reportOutputFolder = coverageOutputManager.GetReportOutputFolder();
223223
vsShutdownLinkedCancellationToken.ThrowIfCancellationRequested();
224224
var result = await reportGeneratorUtil.GenerateAsync(coverOutputFiles,reportOutputFolder,vsShutdownLinkedCancellationToken);
225225

226226
vsShutdownLinkedCancellationToken.ThrowIfCancellationRequested();
227-
logger.Log("Processing cobertura");
227+
logger.Log($"Processing cobertura");
228228
var coverageLines = coberturaUtil.ProcessCoberturaXml(result.UnifiedXmlFile);
229229

230230
vsShutdownLinkedCancellationToken.ThrowIfCancellationRequested();
231-
logger.Log("Processing report");
231+
logger.Log($"Processing report");
232232
string processedReport = reportGeneratorUtil.ProcessUnifiedHtml(result.UnifiedHtml, reportOutputFolder);
233233
return (coverageLines, processedReport);
234234
}
@@ -262,7 +262,7 @@ private async System.Threading.Tasks.Task PrepareCoverageProjectsAsync(List<ICov
262262
}
263263
}
264264

265-
private void DisplayCoverageResult(System.Threading.Tasks.Task<(List<CoverageLine> coverageLines, string reportHtml)> t, object state)
265+
private void DisplayCoverageResult(System.Threading.Tasks.Task<(Dictionary<string, List<CoverageLine>> coverageLines, string reportHtml)> t, object state)
266266
{
267267
var displayCoverageResultState = (DisplayCoverageResultState)state;
268268
if (!IsVsShutdown)
@@ -321,7 +321,7 @@ public void RunAndProcessReport(string[] coberturaFiles, Action cleanUp = null)
321321
{
322322
RunCancellableCoverageTask(async (vsShutdownLinkedCancellationToken) =>
323323
{
324-
List<CoverageLine> coverageLines = null;
324+
Dictionary<string, List<CoverageLine>> coverageLines = null;
325325
string reportHtml = null;
326326

327327
if (coberturaFiles.Any())
@@ -333,7 +333,7 @@ public void RunAndProcessReport(string[] coberturaFiles, Action cleanUp = null)
333333
}
334334

335335
private void RunCancellableCoverageTask(
336-
Func<CancellationToken,System.Threading.Tasks.Task<(List<CoverageLine>, string)>> taskCreator, Action cleanUp)
336+
Func<CancellationToken,System.Threading.Tasks.Task<(Dictionary<string, List<CoverageLine>>, string)>> taskCreator, Action cleanUp)
337337
{
338338
var vsLinkedCancellationTokenSource = Reset();
339339
var vsShutdownLinkedCancellationToken = vsLinkedCancellationTokenSource.Token;
@@ -355,7 +355,7 @@ public void ReloadCoverage(Func<System.Threading.Tasks.Task<List<ICoverageProjec
355355
{
356356
RunCancellableCoverageTask(async (vsShutdownLinkedCancellationToken) =>
357357
{
358-
List<CoverageLine> coverageLines = null;
358+
Dictionary<string, List<CoverageLine>> coverageLines = null;
359359
string reportHtml = null;
360360

361361
await PollInitializedStatusAsync(vsShutdownLinkedCancellationToken);

SharedProject/Impl/CoverageColour/GlyphMargin/CoverageLineGlyphTagger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace FineCodeCoverage.Impl
88
{
99
internal class CoverageLineGlyphTagger : CoverageLineTaggerBase<CoverageLineGlyphTag>, IListener<RefreshCoverageGlyphsMessage>
1010
{
11-
public CoverageLineGlyphTagger(ITextBuffer textBuffer, List<CoverageLine> lastCoverageLines) : base(textBuffer, lastCoverageLines)
11+
public CoverageLineGlyphTagger(ITextBuffer textBuffer, Dictionary<string, List<CoverageLine>> lastCoverageLines) : base(textBuffer, lastCoverageLines)
1212
{
1313
}
1414

SharedProject/Impl/CoverageColour/GlyphMargin/CoverageLineGlyphTaggerProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ protected override void NewCoverageLinesMessageReceived()
4141
});
4242
}
4343

44-
protected override CoverageLineGlyphTagger CreateTagger(ITextBuffer textBuffer, List<CoverageLine> lastCoverageLines)
44+
protected override CoverageLineGlyphTagger CreateTagger(ITextBuffer textBuffer, Dictionary<string, List<CoverageLine>> lastCoverageLines)
4545
{
4646
return new CoverageLineGlyphTagger(textBuffer, lastCoverageLines);
4747
}

SharedProject/Impl/CoverageColour/MarginBase/CoverageLineTaggerBase.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ namespace FineCodeCoverage.Impl
1111
internal abstract class CoverageLineTaggerBase<TTag> : ICoverageLineTagger<TTag> where TTag : ITag
1212
{
1313
private readonly ITextBuffer _textBuffer;
14-
private List<CoverageLine> coverageLines;
14+
private Dictionary<string, List<CoverageLine>> coverageLines;
1515

1616
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
1717

18-
public CoverageLineTaggerBase(ITextBuffer textBuffer, List<CoverageLine> lastCoverageLines)
18+
public CoverageLineTaggerBase(ITextBuffer textBuffer, Dictionary<string, List<CoverageLine>> lastCoverageLines)
1919
{
2020
_textBuffer = textBuffer;
2121
coverageLines = lastCoverageLines;
@@ -34,9 +34,8 @@ protected virtual void RaiseTagsChanged()
3434

3535
private IEnumerable<CoverageLine> GetApplicableLines(string filePath, int startLineNumber, int endLineNumber)
3636
{
37-
return coverageLines
37+
return coverageLines[filePath]
3838
.AsParallel()
39-
.Where(x => x.Class.Filename.Equals(filePath, StringComparison.OrdinalIgnoreCase))
4039
.Where(x => x.Line.Number >= startLineNumber && x.Line.Number <= endLineNumber)
4140
.ToArray();
4241
}

SharedProject/Impl/CoverageColour/MarginBase/CoverageLineTaggerProviderBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal abstract class CoverageLineTaggerProviderBase<TTaggerListener, TTag> :
1212
where TTag : ITag
1313
{
1414
protected readonly IEventAggregator eventAggregator;
15-
private List<CoverageLine> lastCoverageLines;
15+
private Dictionary<string, List<CoverageLine>> lastCoverageLines;
1616

1717
public CoverageLineTaggerProviderBase(
1818
IEventAggregator eventAggregator
@@ -29,7 +29,7 @@ public ITagger<T> CreateTagger<T>(ITextBuffer textBuffer) where T : ITag
2929
return tagger as ITagger<T>;
3030
}
3131

32-
protected abstract TTaggerListener CreateTagger(ITextBuffer textBuffer, List<CoverageLine> lastCoverageLines);
32+
protected abstract TTaggerListener CreateTagger(ITextBuffer textBuffer, Dictionary<string, List<CoverageLine>> lastCoverageLines);
3333

3434
public void Handle(NewCoverageLinesMessage message)
3535
{

SharedProject/Impl/CoverageColour/OverviewMargin/CoverageLineMarkTagger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace FineCodeCoverage.Impl
99
internal class CoverageLineMarkTagger : CoverageLineTaggerBase<OverviewMarkTag>, IListener<CoverageMarginOptionsChangedMessage>
1010
{
1111
private ICoverageMarginOptions coverageMarginOptions;
12-
public CoverageLineMarkTagger(ITextBuffer textBuffer, List<CoverageLine> lastCoverageLines, ICoverageMarginOptions coverageMarginOptions) :
12+
public CoverageLineMarkTagger(ITextBuffer textBuffer, Dictionary<string, List<CoverageLine>> lastCoverageLines, ICoverageMarginOptions coverageMarginOptions) :
1313
base(textBuffer, lastCoverageLines)
1414
{
1515
this.coverageMarginOptions = coverageMarginOptions;

SharedProject/Impl/CoverageColour/OverviewMargin/CoverageLineMarkTaggerProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ private void AppOptionsProvider_OptionsChanged(IAppOptions appOptions)
3737
}
3838
}
3939

40-
protected override CoverageLineMarkTagger CreateTagger(ITextBuffer textBuffer, List<CoverageLine> lastCoverageLines)
40+
protected override CoverageLineMarkTagger CreateTagger(ITextBuffer textBuffer, Dictionary<string, List<CoverageLine>> lastCoverageLines)
4141
{
4242
return new CoverageLineMarkTagger(textBuffer, lastCoverageLines, coverageMarginOptions);
4343
}

0 commit comments

Comments
 (0)