Initialize CBDD solution and add a .NET-focused gitignore for generated artifacts.
This commit is contained in:
23
src/CBDD.CheckpointTest/DocumentDb.CheckpointTest.csproj
Executable file
23
src/CBDD.CheckpointTest/DocumentDb.CheckpointTest.csproj
Executable file
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<AssemblyName>ZB.MOM.WW.CBDD.CheckpointTest</AssemblyName>
|
||||
<RootNamespace>ZB.MOM.WW.CBDD.CheckpointTest</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>14.0</LangVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
|
||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<ProjectReference Include="..\CBDD.Core\ZB.MOM.WW.CBDD.Core.csproj" />
|
||||
<ProjectReference Include="..\CBDD.Bson\ZB.MOM.WW.CBDD.Bson.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
149
src/CBDD.CheckpointTest/Program.cs
Executable file
149
src/CBDD.CheckpointTest/Program.cs
Executable file
@@ -0,0 +1,149 @@
|
||||
using ZB.MOM.WW.CBDD.Core.Storage;
|
||||
using ZB.MOM.WW.CBDD.Core.Transactions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog;
|
||||
using Serilog.Context;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.CheckpointTest;
|
||||
|
||||
/// <summary>
|
||||
/// Quick test to verify checkpoint functionality and performance improvement
|
||||
/// </summary>
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var serilogLogger = new LoggerConfiguration()
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
using var loggerFactory = LoggerFactory.Create(builder =>
|
||||
{
|
||||
builder.ClearProviders();
|
||||
builder.AddSerilog(serilogLogger, dispose: true);
|
||||
});
|
||||
|
||||
var logger = loggerFactory.CreateLogger<Program>();
|
||||
logger.LogInformation("=== DocumentDb Checkpoint Performance Test ===");
|
||||
|
||||
var dbPath = "test_checkpoint.db";
|
||||
var walPath = "test_checkpoint.wal";
|
||||
|
||||
using var _ = LogContext.PushProperty("DatabasePath", dbPath);
|
||||
using var __ = LogContext.PushProperty("WalPath", walPath);
|
||||
|
||||
if (File.Exists(dbPath))
|
||||
{
|
||||
File.Delete(dbPath);
|
||||
}
|
||||
|
||||
if (File.Exists(walPath))
|
||||
{
|
||||
File.Delete(walPath);
|
||||
}
|
||||
|
||||
using var storage = new StorageEngine(dbPath, PageFileConfig.Default);
|
||||
|
||||
logger.LogInformation("1. Testing Single Inserts ({TransactionCount} transactions)...", 500);
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
using (LogContext.PushProperty("Phase", "SingleInserts"))
|
||||
{
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
using var txn = storage.BeginTransaction();
|
||||
|
||||
// Simulate a write
|
||||
var pageId = storage.AllocatePage();
|
||||
var data = new byte[storage.PageSize];
|
||||
new Random().NextBytes(data);
|
||||
|
||||
// Write directly to storage
|
||||
// Old: txn.AddWrite(...)
|
||||
storage.WritePage(pageId, txn.TransactionId, data);
|
||||
|
||||
storage.CommitTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
logger.LogInformation("Completed {TransactionCount} inserts in {ElapsedMs}ms", 500, sw.ElapsedMilliseconds);
|
||||
logger.LogInformation("Average: {InsertsPerSecond:F0} inserts/sec", 500.0 / sw.Elapsed.TotalSeconds);
|
||||
|
||||
var walSize = new FileInfo(walPath).Length;
|
||||
logger.LogInformation("WAL size: {WalSizeKb:F1} KB", walSize / 1024.0);
|
||||
|
||||
logger.LogInformation("2. Performing Manual Checkpoint...");
|
||||
sw.Restart();
|
||||
storage.Checkpoint();
|
||||
sw.Stop();
|
||||
|
||||
logger.LogInformation("Checkpoint completed in {ElapsedMs}ms", sw.ElapsedMilliseconds);
|
||||
|
||||
var dbSize = new FileInfo(dbPath).Length;
|
||||
var walSizeAfter = new FileInfo(walPath).Length;
|
||||
logger.LogInformation("DB size: {DbSizeKb:F1} KB", dbSize / 1024.0);
|
||||
logger.LogInformation("WAL size after checkpoint: {WalSizeKb:F1} KB", walSizeAfter / 1024.0);
|
||||
|
||||
logger.LogInformation("3. Testing Checkpoint with Truncate (Integrated)...");
|
||||
storage.Checkpoint();
|
||||
|
||||
walSizeAfter = new FileInfo(walPath).Length;
|
||||
logger.LogInformation("WAL size after truncate: {WalSizeKb:F1} KB", walSizeAfter / 1024.0);
|
||||
|
||||
logger.LogInformation("4. Testing Batch Inserts ({TransactionCount} transactions)...", 1000);
|
||||
sw.Restart();
|
||||
|
||||
using (LogContext.PushProperty("Phase", "BatchInserts"))
|
||||
{
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
using var txn = storage.BeginTransaction();
|
||||
|
||||
var pageId = storage.AllocatePage();
|
||||
var data = new byte[storage.PageSize];
|
||||
new Random().NextBytes(data);
|
||||
|
||||
storage.WritePage(pageId, txn.TransactionId, data);
|
||||
|
||||
storage.CommitTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
logger.LogInformation("Completed {TransactionCount} inserts in {ElapsedMs}ms", 1000, sw.ElapsedMilliseconds);
|
||||
logger.LogInformation("Average: {InsertsPerSecond:F0} inserts/sec", 1000.0 / sw.Elapsed.TotalSeconds);
|
||||
|
||||
walSize = new FileInfo(walPath).Length;
|
||||
logger.LogInformation("WAL size: {WalSizeKb:F1} KB", walSize / 1024.0);
|
||||
|
||||
logger.LogInformation("5. Final checkpoint and cleanup...");
|
||||
storage.Checkpoint();
|
||||
|
||||
dbSize = new FileInfo(dbPath).Length;
|
||||
walSizeAfter = new FileInfo(walPath).Length;
|
||||
logger.LogInformation("Final DB size: {DbSizeKb:F1} KB", dbSize / 1024.0);
|
||||
logger.LogInformation("Final WAL size: {WalSizeKb:F1} KB", walSizeAfter / 1024.0);
|
||||
|
||||
logger.LogInformation("=== Test Completed Successfully! ===");
|
||||
logger.LogInformation("Key Observations:");
|
||||
logger.LogInformation("- Commits are fast (only WAL writes)");
|
||||
logger.LogInformation("- Checkpoint consolidates changes to DB");
|
||||
logger.LogInformation("- Truncate reclaims WAL space");
|
||||
logger.LogInformation("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
|
||||
// Cleanup
|
||||
try
|
||||
{
|
||||
if (File.Exists(dbPath)) File.Delete(dbPath);
|
||||
if (File.Exists(walPath)) File.Delete(walPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogWarning(ex, "Cleanup after checkpoint test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user