perf: 提高 Content 缓存模式性能
This commit is contained in:
parent
002c482db3
commit
87b69e6b5f
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue