Implement checkpoint modes with docs/tests and reorganize project file layout
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
using ZB.MOM.WW.CBDD.Core;
|
||||
using ZB.MOM.WW.CBDD.Core.Storage;
|
||||
using ZB.MOM.WW.CBDD.Core.Transactions;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests.Benchmark;
|
||||
|
||||
internal sealed class BenchmarkTransactionHolder : ITransactionHolder, IDisposable
|
||||
{
|
||||
private readonly StorageEngine _storage;
|
||||
private readonly object _sync = new();
|
||||
private ITransaction? _currentTransaction;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BenchmarkTransactionHolder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="storage">The storage engine used to create transactions.</param>
|
||||
public BenchmarkTransactionHolder(StorageEngine storage)
|
||||
{
|
||||
_storage = storage ?? throw new ArgumentNullException(nameof(storage));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current active transaction or starts a new one.
|
||||
/// </summary>
|
||||
/// <returns>The current active transaction.</returns>
|
||||
public ITransaction GetCurrentTransactionOrStart()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
if (_currentTransaction == null || _currentTransaction.State != TransactionState.Active)
|
||||
{
|
||||
_currentTransaction = _storage.BeginTransaction();
|
||||
}
|
||||
|
||||
return _currentTransaction;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current active transaction or starts a new one asynchronously.
|
||||
/// </summary>
|
||||
/// <returns>A task that returns the current active transaction.</returns>
|
||||
public Task<ITransaction> GetCurrentTransactionOrStartAsync()
|
||||
{
|
||||
return Task.FromResult(GetCurrentTransactionOrStart());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commits the current transaction when active and clears the holder.
|
||||
/// </summary>
|
||||
public void CommitAndReset()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
if (_currentTransaction == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentTransaction.State == TransactionState.Active ||
|
||||
_currentTransaction.State == TransactionState.Preparing)
|
||||
{
|
||||
_currentTransaction.Commit();
|
||||
}
|
||||
|
||||
_currentTransaction.Dispose();
|
||||
_currentTransaction = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back the current transaction when active and clears the holder.
|
||||
/// </summary>
|
||||
public void RollbackAndReset()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
if (_currentTransaction == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentTransaction.State == TransactionState.Active ||
|
||||
_currentTransaction.State == TransactionState.Preparing)
|
||||
{
|
||||
_currentTransaction.Rollback();
|
||||
}
|
||||
|
||||
_currentTransaction.Dispose();
|
||||
_currentTransaction = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this holder and rolls back any outstanding transaction.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
RollbackAndReset();
|
||||
}
|
||||
}
|
||||
38
tests/CBDD.Tests.Benchmark/Infrastructure/Logging.cs
Normal file
38
tests/CBDD.Tests.Benchmark/Infrastructure/Logging.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests.Benchmark;
|
||||
|
||||
internal static class Logging
|
||||
{
|
||||
private static readonly Lazy<ILoggerFactory> LoggerFactoryInstance = new(CreateFactory);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the shared logger factory for benchmarks.
|
||||
/// </summary>
|
||||
public static ILoggerFactory LoggerFactory => LoggerFactoryInstance.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a logger for the specified category type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The logger category type.</typeparam>
|
||||
/// <returns>A logger for <typeparamref name="T"/>.</returns>
|
||||
public static Microsoft.Extensions.Logging.ILogger CreateLogger<T>()
|
||||
{
|
||||
return LoggerFactory.CreateLogger<T>();
|
||||
}
|
||||
|
||||
private static ILoggerFactory CreateFactory()
|
||||
{
|
||||
var serilogLogger = new LoggerConfiguration()
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
return Microsoft.Extensions.Logging.LoggerFactory.Create(builder =>
|
||||
{
|
||||
builder.ClearProviders();
|
||||
builder.AddSerilog(serilogLogger, dispose: true);
|
||||
});
|
||||
}
|
||||
}
|
||||
89
tests/CBDD.Tests.Benchmark/Infrastructure/Program.cs
Executable file
89
tests/CBDD.Tests.Benchmark/Infrastructure/Program.cs
Executable file
@@ -0,0 +1,89 @@
|
||||
using BenchmarkDotNet.Columns;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Exporters;
|
||||
using BenchmarkDotNet.Reports;
|
||||
using BenchmarkDotNet.Running;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog.Context;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests.Benchmark;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var logger = Logging.CreateLogger<Program>();
|
||||
var mode = args.Length > 0 ? args[0].Trim().ToLowerInvariant() : string.Empty;
|
||||
|
||||
if (mode == "manual")
|
||||
{
|
||||
using var _ = LogContext.PushProperty("Mode", "Manual");
|
||||
ManualBenchmark.Run(logger);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == "size")
|
||||
{
|
||||
using var _ = LogContext.PushProperty("Mode", "SizeBenchmark");
|
||||
DatabaseSizeBenchmark.Run(logger);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == "compression")
|
||||
{
|
||||
using var _ = LogContext.PushProperty("Mode", "CompressionBenchmarks");
|
||||
BenchmarkRunner.Run<CompressionBenchmarks>(CreateConfig());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == "compaction")
|
||||
{
|
||||
using var _ = LogContext.PushProperty("Mode", "CompactionBenchmarks");
|
||||
BenchmarkRunner.Run<CompactionBenchmarks>(CreateConfig());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == "mixed")
|
||||
{
|
||||
using var _ = LogContext.PushProperty("Mode", "MixedWorkloadBenchmarks");
|
||||
BenchmarkRunner.Run<MixedWorkloadBenchmarks>(CreateConfig());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == "gate")
|
||||
{
|
||||
using var _ = LogContext.PushProperty("Mode", "PerformanceGateSmoke");
|
||||
PerformanceGateSmoke.Run(logger);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == "all")
|
||||
{
|
||||
using var _ = LogContext.PushProperty("Mode", "AllBenchmarks");
|
||||
var config = CreateConfig();
|
||||
BenchmarkRunner.Run<InsertBenchmarks>(config);
|
||||
BenchmarkRunner.Run<ReadBenchmarks>(config);
|
||||
BenchmarkRunner.Run<SerializationBenchmarks>(config);
|
||||
BenchmarkRunner.Run<CompressionBenchmarks>(config);
|
||||
BenchmarkRunner.Run<CompactionBenchmarks>(config);
|
||||
BenchmarkRunner.Run<MixedWorkloadBenchmarks>(config);
|
||||
return;
|
||||
}
|
||||
|
||||
using var __ = LogContext.PushProperty("Mode", "BenchmarkDotNet");
|
||||
var defaultConfig = CreateConfig();
|
||||
|
||||
BenchmarkRunner.Run<InsertBenchmarks>(defaultConfig);
|
||||
BenchmarkRunner.Run<ReadBenchmarks>(defaultConfig);
|
||||
BenchmarkRunner.Run<SerializationBenchmarks>(defaultConfig);
|
||||
}
|
||||
|
||||
private static IConfig CreateConfig()
|
||||
{
|
||||
return DefaultConfig.Instance
|
||||
.AddExporter(HtmlExporter.Default)
|
||||
.WithSummaryStyle(SummaryStyle.Default
|
||||
.WithRatioStyle(RatioStyle.Trend)
|
||||
.WithTimeUnit(Perfolizer.Horology.TimeUnit.Microsecond));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user