88 lines
3.4 KiB
C#
88 lines
3.4 KiB
C#
using System.Globalization;
|
|
|
|
namespace StellaOps.Bench.LinkNotMerge.Vex.Baseline;
|
|
|
|
internal static class BaselineLoader
|
|
{
|
|
public static async Task<IReadOnlyDictionary<string, BaselineEntry>> LoadAsync(string path, CancellationToken cancellationToken)
|
|
{
|
|
ArgumentException.ThrowIfNullOrWhiteSpace(path);
|
|
|
|
var resolved = Path.GetFullPath(path);
|
|
if (!File.Exists(resolved))
|
|
{
|
|
return new Dictionary<string, BaselineEntry>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
var result = new Dictionary<string, BaselineEntry>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
await using var stream = new FileStream(resolved, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
using var reader = new StreamReader(stream);
|
|
|
|
var lineNumber = 0;
|
|
while (true)
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
var line = await reader.ReadLineAsync().ConfigureAwait(false);
|
|
if (line is null)
|
|
{
|
|
break;
|
|
}
|
|
|
|
lineNumber++;
|
|
if (lineNumber == 1 || string.IsNullOrWhiteSpace(line))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var parts = line.Split(',', StringSplitOptions.TrimEntries);
|
|
if (parts.Length < 15)
|
|
{
|
|
throw new InvalidOperationException($"Baseline '{resolved}' line {lineNumber} is invalid (expected 15 columns, found {parts.Length}).");
|
|
}
|
|
|
|
var entry = new BaselineEntry(
|
|
ScenarioId: parts[0],
|
|
Iterations: ParseInt(parts[1], resolved, lineNumber),
|
|
Observations: ParseInt(parts[2], resolved, lineNumber),
|
|
Statements: ParseInt(parts[3], resolved, lineNumber),
|
|
Events: ParseInt(parts[4], resolved, lineNumber),
|
|
MeanTotalMs: ParseDouble(parts[5], resolved, lineNumber),
|
|
P95TotalMs: ParseDouble(parts[6], resolved, lineNumber),
|
|
MaxTotalMs: ParseDouble(parts[7], resolved, lineNumber),
|
|
MeanInsertMs: ParseDouble(parts[8], resolved, lineNumber),
|
|
MeanCorrelationMs: ParseDouble(parts[9], resolved, lineNumber),
|
|
MeanObservationThroughputPerSecond: ParseDouble(parts[10], resolved, lineNumber),
|
|
MinObservationThroughputPerSecond: ParseDouble(parts[11], resolved, lineNumber),
|
|
MeanEventThroughputPerSecond: ParseDouble(parts[12], resolved, lineNumber),
|
|
MinEventThroughputPerSecond: ParseDouble(parts[13], resolved, lineNumber),
|
|
MaxAllocatedMb: ParseDouble(parts[14], resolved, lineNumber));
|
|
|
|
result[entry.ScenarioId] = entry;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static int ParseInt(string value, string file, int line)
|
|
{
|
|
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed))
|
|
{
|
|
return parsed;
|
|
}
|
|
|
|
throw new InvalidOperationException($"Baseline '{file}' line {line} contains an invalid integer '{value}'.");
|
|
}
|
|
|
|
private static double ParseDouble(string value, string file, int line)
|
|
{
|
|
if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed))
|
|
{
|
|
return parsed;
|
|
}
|
|
|
|
throw new InvalidOperationException($"Baseline '{file}' line {line} contains an invalid number '{value}'.");
|
|
}
|
|
}
|