perf(saves): simplify FileBufferWriter staging

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kamron Batman 2026-07-16 11:52:19 -07:00
parent 9cc25fab24
commit 1fb2c0a0d2
No known key found for this signature in database
GPG key ID: 7D81DF26D9A5D94A
2 changed files with 6 additions and 20 deletions

View file

@ -297,7 +297,7 @@ public class BufferWriter : IGenericWriter
public void Write(Serial serial) => Write(serial.Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual void Write(Type type)
public void Write(Type type)
{
if (type == null)
{

View file

@ -14,6 +14,8 @@
*************************************************************************/
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using Microsoft.Win32.SafeHandles;
@ -37,7 +39,6 @@ public class FileBufferWriter : BufferWriter, IDisposable
private const int MaxStagingSize = 1024 * 1024; // 1MB write granularity for large files
private readonly SafeFileHandle _handle;
private readonly HashSet<Type> _typeSet;
private readonly byte[] _rentedStaging;
private long _fileOffset; // file position where the staging block begins
private long _fileHighWater; // logical end of file across seeks
@ -52,32 +53,17 @@ public class FileBufferWriter : BufferWriter, IDisposable
/// a large-object allocation per file per save.
/// </param>
public FileBufferWriter(string filePath, HashSet<Type> typeSet = null, long expectedSize = MaxStagingSize)
: base(RentStaging(expectedSize), true)
: base(RentStaging(expectedSize), true, typeSet != null ? new ConcurrentQueue<Type>(typeSet) : null)
{
_rentedStaging = Buffer;
_typeSet = typeSet;
_handle = File.OpenHandle(filePath, FileMode.Create, FileAccess.Write, FileShare.None, FileOptions.SequentialScan);
}
private static byte[] RentStaging(long expectedSize) =>
System.Buffers.ArrayPool<byte>.Shared.Rent((int)Math.Clamp(expectedSize, MinStagingSize, MaxStagingSize));
ArrayPool<byte>.Shared.Rent((int)Math.Clamp(expectedSize, MinStagingSize, MaxStagingSize));
public override long Position => _fileOffset + Index;
public override void Write(Type type)
{
if (type == null)
{
Write((byte)0);
}
else
{
Write((byte)0x2); // xxHash3 64bit
Write(AssemblyHandler.GetTypeHash(type));
_typeSet?.Add(type);
}
}
public override void Flush()
{
if (Index > 0)
@ -149,7 +135,7 @@ public class FileBufferWriter : BufferWriter, IDisposable
// Safe even if an oversized item grew the staging block: growth replaced the
// base buffer with a fresh array, so the rented one is no longer referenced.
System.Buffers.ArrayPool<byte>.Shared.Return(_rentedStaging);
ArrayPool<byte>.Shared.Return(_rentedStaging);
}
}