Skip to content

Commit dafe671

Browse files
author
MPCoreDeveloper
committed
benchmark bug fix
1 parent 5c42073 commit dafe671

6 files changed

Lines changed: 48 additions & 5 deletions

File tree

Examples/EFDebugTest/EFDebugTest.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</ItemGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
15+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
1616
</ItemGroup>
1717

1818
</Project>

Examples/EFDebugTest/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.EntityFrameworkCore;
22
using Microsoft.Extensions.DependencyInjection;
3+
using SharpCoreDB.EntityFrameworkCore;
34
using System.ComponentModel.DataAnnotations;
45

56
var dbPath = "./test_debug.scdb";

src/SharpCoreDB/Storage/FreeSpaceManager.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,19 @@ private void LoadFsm()
473473
_totalPages = header.TotalPages;
474474
_freePages = header.FreePages;
475475

476+
// Extra defensive: re-mark all declared allocated pages in the in-memory bitmap.
477+
// This guarantees the metadata reservation (including BlockRegistry area) is respected
478+
// even if deserialize/trailing-bits logic or file visibility under Release+coverage+Linux
479+
// did not fully apply the initial bitmap written in InitializeNewFile.
480+
// Directly prevents the first AllocatePages from returning a registry page (the root of the BREG bytes read-back).
481+
if (_freePages == 0 && _totalPages > 0)
482+
{
483+
for (int i = 0; i < (int)_totalPages; i++)
484+
{
485+
_l1Bitmap.Set(i, true);
486+
}
487+
}
488+
476489
// Read L1 bitmap
477490
var bitmapSizeBytes = (int)((_totalPages + 7) / 8);
478491
var bitmapBuffer = ArrayPool<byte>.Shared.Rent(bitmapSizeBytes);

src/SharpCoreDB/Storage/SingleFileStorageProvider.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,17 @@ public async Task WriteBlockAsync(string blockName, ReadOnlyMemory<byte> data, C
408408
{
409409
// New block
410410
offset = _freeSpaceManager.AllocatePages(requiredPages);
411+
412+
// Defensive guard (addresses CI-only first-allocation collision with BlockRegistry area under Release+coverage+Linux).
413+
// If FSM (for any reason: load timing, bitmap deserialize edge, Release opts, coverage-induced slowdown of init writes)
414+
// returns an offset inside the registry, force the data to a safe location after the registry.
415+
// The registry area itself is now pre-initialized with a valid empty BREG header (see InitializeNewFile).
416+
var registryEnd = _header.BlockRegistryOffset + _header.BlockRegistryLength;
417+
if (offset < registryEnd)
418+
{
419+
offset = registryEnd;
420+
}
421+
411422
entry = new BlockEntry
412423
{
413424
BlockType = (uint)Scdb.BlockType.TableData,
@@ -1401,14 +1412,32 @@ static ulong AlignToPage(ulong value, int pageSize)
14011412
var headerBuffer = new byte[ScdbFileHeader.HEADER_SIZE];
14021413
header.WriteTo(headerBuffer);
14031414
fs.Write(headerBuffer);
1404-
1415+
1416+
// ✅ CRITICAL FIX 3: Write initial empty BlockRegistryHeader ("BREG") immediately.
1417+
// Mirrors CRITICAL FIX 2 for FSM. Ensures LoadRegistry on a brand-new file (or after
1418+
// crash before any user data) always sees a valid header with BlockCount=0 instead of
1419+
// uninitialized bytes. Prevents cases where the first registry flush races with data
1420+
// writes or where allocation collides with the registry area on reopen.
1421+
fs.Position = (long)header.BlockRegistryOffset;
1422+
var regHeader = new BlockRegistryHeader
1423+
{
1424+
Magic = BlockRegistryHeader.MAGIC,
1425+
Version = BlockRegistryHeader.CURRENT_VERSION,
1426+
BlockCount = 0,
1427+
TotalSize = BlockRegistryHeader.SIZE,
1428+
LastModified = (ulong)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() * 1000
1429+
};
1430+
Span<byte> regHeaderBuffer = stackalloc byte[BlockRegistryHeader.SIZE];
1431+
MemoryMarshal.Write(regHeaderBuffer, in regHeader);
1432+
fs.Write(regHeaderBuffer);
1433+
14051434
// ✅ CRITICAL FIX 2: Write FSM header marking metadata pages as allocated
14061435
// Without this, FreeSpaceManager starts with _totalPages=0 and AllocatePages
14071436
// returns offset 0 (the SCDB header page!). Data block writes then overwrite the
14081437
// file header with table data (e.g. "SFT1" magic), corrupting the file.
14091438
var reservedPages = (ulong)(totalMetadataSize / (ulong)options.PageSize);
14101439
header.AllocatedPages = reservedPages;
1411-
1440+
14121441
var fsmHeader = new FreeSpaceMapHeader
14131442
{
14141443
Magic = FreeSpaceMapHeader.MAGIC,

tests/SharpCoreDB.Functional.Dapper.Tests/SharpCoreDB.Functional.Dapper.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.5" />
13+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
1414
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
1515
<PackageReference Include="xunit.v3" Version="3.2.2" />
1616
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">

tests/benchmarks/SharpCoreDB.CQRS.Benchmarks/SharpCoreDB.CQRS.Benchmarks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
<ItemGroup>
2020
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
21-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.5" />
21+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
2222
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="10.0.203" />
2323
</ItemGroup>
2424

0 commit comments

Comments
 (0)