Skip to content

Commit b62b4f8

Browse files
author
MPCoreDeveloper
committed
fix(scdb): Phase 3 WalEntry SIZE fix (64→4096)
Removed duplicate WalHeader and WalEntry structs from WalManager.cs that had incorrect SIZE (64 bytes instead of 4096). Now using Scdb.WalHeader and Scdb.WalEntry from ScdbStructures.cs. This fixes ArgumentOutOfRangeException in SerializeWalEntry. 1/9 crash recovery tests now passing.
1 parent 50cfc1b commit b62b4f8

File tree

1 file changed

+32
-40
lines changed

1 file changed

+32
-40
lines changed

src/SharpCoreDB/Storage/WalManager.cs

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ private WalEntry ConvertToWalEntry(WalLogEntry logEntry)
335335
/// <summary>
336336
/// Serializes WalEntry to byte buffer with checksum.
337337
/// C# 14: Uses modern unsafe code patterns.
338+
/// Format: Lsn(8) + TxId(8) + Timestamp(8) + Op(2) + BlockIdx(2) + PageId(8) + DataLen(2) + Checksum(32) + Data(4000)
338339
/// </summary>
339340
private static unsafe void SerializeWalEntry(Span<byte> buffer, WalEntry entry)
340341
{
@@ -369,22 +370,45 @@ private static unsafe void SerializeWalEntry(Span<byte> buffer, WalEntry entry)
369370
BinaryPrimitives.WriteUInt16LittleEndian(buffer[offset..], entry.DataLength);
370371
offset += 2;
371372

372-
// Skip checksum for now (will calculate after)
373+
// Mark checksum offset (will write after computing hash)
373374
var checksumOffset = offset;
374375
offset += 32;
375376

377+
// Data payload comes after checksum (offset now at Data field)
378+
var dataOffset = offset;
379+
376380
// Write data payload (if any)
377-
if (entry.DataLength > 0)
381+
if (entry.DataLength > 0 && entry.DataLength <= WalEntry.MAX_DATA_LENGTH)
378382
{
379-
// In real implementation, copy from entry.Data
380-
// For now, zero-filled as Data field needs to be populated by caller
383+
// In real implementation: copy from entry.Data
384+
// For Phase 3: zero-filled (data writing is stub)
385+
// Data will be populated when actual operations are logged
381386
}
382387

383388
// Calculate and write SHA-256 checksum
389+
// Hash: header (before checksum) + data payload
384390
using var sha256 = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);
385-
sha256.AppendData(buffer[..checksumOffset]); // Header
386-
sha256.AppendData(buffer[offset..(offset + entry.DataLength)]); // Data
391+
sha256.AppendData(buffer[..checksumOffset]); // Header fields
392+
393+
if (entry.DataLength > 0 && entry.DataLength <= WalEntry.MAX_DATA_LENGTH)
394+
{
395+
sha256.AppendData(buffer.Slice(dataOffset, entry.DataLength)); // Data payload
396+
}
397+
387398
var checksum = sha256.GetHashAndReset();
399+
400+
// Validate checksum size and buffer space
401+
if (checksum.Length != 32)
402+
{
403+
throw new InvalidOperationException($"SHA256 checksum must be 32 bytes, got {checksum.Length}");
404+
}
405+
406+
if (checksumOffset + 32 > buffer.Length)
407+
{
408+
throw new ArgumentOutOfRangeException(nameof(buffer),
409+
$"Buffer too small for checksum at offset {checksumOffset}, buffer size {buffer.Length}");
410+
}
411+
388412
checksum.CopyTo(buffer.Slice(checksumOffset, 32));
389413
}
390414

@@ -647,37 +671,5 @@ internal enum WalOperation
647671
PageFree = 9
648672
}
649673

650-
internal struct WalHeader
651-
{
652-
public const uint MAGIC = 0x20230522;
653-
public const ushort CURRENT_VERSION = 1;
654-
public const int SIZE = 64;
655-
public const int DEFAULT_ENTRY_SIZE = 4096;
656-
657-
public uint Magic;
658-
public ushort Version;
659-
public ushort EntrySize;
660-
public uint MaxEntries;
661-
public ulong CurrentLsn;
662-
public ulong LastCheckpoint;
663-
public ulong HeadOffset;
664-
public ulong TailOffset;
665-
}
666-
667-
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
668-
internal struct WalEntry
669-
{
670-
public const int SIZE = 64;
671-
public const int MAX_DATA_LENGTH = 4000;
672-
673-
public ulong Lsn;
674-
public ulong TransactionId;
675-
public ulong Timestamp;
676-
public ushort Operation;
677-
public ushort BlockIndex;
678-
public ulong PageId;
679-
public ushort DataLength;
680-
public unsafe fixed byte BlockName[32];
681-
public unsafe fixed byte Checksum[32];
682-
}
683-
#pragma warning restore CS0649
674+
// ✅ PHASE 3 FIX: Using Scdb.WalHeader and Scdb.WalEntry from ScdbStructures.cs
675+
// Removed duplicate definitions that had incorrect SIZE (64 vs 4096)

0 commit comments

Comments
 (0)