perf: 提高 Content 缓存模式性能

This commit is contained in:
Argo Zhang 2025-11-21 09:42:59 +08:00
parent 002c482db3
commit 87b69e6b5f
3 changed files with 29 additions and 20 deletions

View File

@ -8,32 +8,26 @@ using System.Buffers;
namespace IP2Region.Net.Internal.Abstractions; namespace IP2Region.Net.Internal.Abstractions;
internal abstract class AbstractCacheStrategy internal abstract class AbstractCacheStrategy(string xdbPath)
{ {
protected readonly FileStream XdbFileStream;
private const int BufferSize = 4096; private const int BufferSize = 4096;
internal int IoCount { get; private set; } internal int IoCount { get; private set; }
protected AbstractCacheStrategy(string xdbPath)
{
XdbFileStream = new FileStream(xdbPath, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize,
useAsync: true);
}
internal virtual ReadOnlyMemory<byte> GetData(int offset, int length) internal virtual ReadOnlyMemory<byte> GetData(int offset, int length)
{ {
byte[] buffer = ArrayPool<byte>.Shared.Rent(length); byte[] buffer = ArrayPool<byte>.Shared.Rent(length);
int totalBytesRead = 0; int totalBytesRead = 0;
try try
{ {
XdbFileStream.Seek(offset, SeekOrigin.Begin); var stream = GetXdbFileStream();
stream.Seek(offset, SeekOrigin.Begin);
int bytesRead; int bytesRead;
while (totalBytesRead < length) while (totalBytesRead < length)
{ {
int bytesToRead = Math.Min(BufferSize, length - totalBytesRead); int bytesToRead = Math.Min(BufferSize, length - totalBytesRead);
bytesRead = XdbFileStream.Read(buffer, totalBytesRead, bytesToRead); bytesRead = stream.Read(buffer, totalBytesRead, bytesToRead);
totalBytesRead += bytesRead; totalBytesRead += bytesRead;
IoCount++; IoCount++;
@ -46,4 +40,15 @@ internal abstract class AbstractCacheStrategy
return new ReadOnlyMemory<byte>(buffer, 0, totalBytesRead); return new ReadOnlyMemory<byte>(buffer, 0, totalBytesRead);
} }
FileStream? _xdbFileStream;
protected FileStream GetXdbFileStream()
{
if (_xdbFileStream == null)
{
_xdbFileStream = new FileStream(xdbPath, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize, FileOptions.RandomAccess);
}
return _xdbFileStream;
}
} }

View File

@ -8,19 +8,18 @@ using IP2Region.Net.Internal.Abstractions;
namespace IP2Region.Net.Internal; namespace IP2Region.Net.Internal;
class ContentCacheStrategy : AbstractCacheStrategy class ContentCacheStrategy(string xdbPath) : AbstractCacheStrategy(xdbPath)
{ {
readonly ReadOnlyMemory<byte> _cacheData; ReadOnlyMemory<byte> _cacheData = ReadOnlyMemory<byte>.Empty;
public ContentCacheStrategy(string xdbPath) : base(xdbPath)
{
_cacheData = base.GetData(0, (int)XdbFileStream.Length);
XdbFileStream.Close();
XdbFileStream.Dispose();
}
internal override ReadOnlyMemory<byte> GetData(int offset, int length) internal override ReadOnlyMemory<byte> GetData(int offset, int length)
{ {
if (_cacheData.IsEmpty)
{
using var reader = base.GetXdbFileStream();
_cacheData = base.GetData(0, (int)reader.Length);
}
return _cacheData.Slice(offset, length); return _cacheData.Slice(offset, length);
} }
} }

View File

@ -38,8 +38,13 @@ public static class Util
throw new FileNotFoundException("xdb file not fould.", dbPath); throw new FileNotFoundException("xdb file not fould.", dbPath);
} }
XdbVersion ret = default;
using var reader = File.OpenRead(dbPath); using var reader = File.OpenRead(dbPath);
return await GetVersionAsync(reader, token);
}
internal static async Task<XdbVersion> GetVersionAsync(FileStream reader, CancellationToken token = default)
{
XdbVersion ret = default;
var buffer = ArrayPool<byte>.Shared.Rent(256); var buffer = ArrayPool<byte>.Shared.Rent(256);
try try