Initialize CBDD solution and add a .NET-focused gitignore for generated artifacts.

This commit is contained in:
Joseph Doherty
2026-02-20 12:54:07 -05:00
commit b8ed5ec500
214 changed files with 101452 additions and 0 deletions

View 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>

View 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");
}
}
}