perf: 提高 Content 缓存模式性能
This commit is contained in:
parent
002c482db3
commit
87b69e6b5f
|
|
@ -8,32 +8,26 @@ using System.Buffers;
|
|||
|
||||
namespace IP2Region.Net.Internal.Abstractions;
|
||||
|
||||
internal abstract class AbstractCacheStrategy
|
||||
internal abstract class AbstractCacheStrategy(string xdbPath)
|
||||
{
|
||||
protected readonly FileStream XdbFileStream;
|
||||
private const int BufferSize = 4096;
|
||||
|
||||
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)
|
||||
{
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(length);
|
||||
int totalBytesRead = 0;
|
||||
try
|
||||
{
|
||||
XdbFileStream.Seek(offset, SeekOrigin.Begin);
|
||||
var stream = GetXdbFileStream();
|
||||
stream.Seek(offset, SeekOrigin.Begin);
|
||||
|
||||
int bytesRead;
|
||||
while (totalBytesRead < length)
|
||||
{
|
||||
int bytesToRead = Math.Min(BufferSize, length - totalBytesRead);
|
||||
bytesRead = XdbFileStream.Read(buffer, totalBytesRead, bytesToRead);
|
||||
bytesRead = stream.Read(buffer, totalBytesRead, bytesToRead);
|
||||
totalBytesRead += bytesRead;
|
||||
|
||||
IoCount++;
|
||||
|
|
@ -46,4 +40,15 @@ internal abstract class AbstractCacheStrategy
|
|||
|
||||
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;
|
||||
|
||||
class ContentCacheStrategy : AbstractCacheStrategy
|
||||
class ContentCacheStrategy(string xdbPath) : AbstractCacheStrategy(xdbPath)
|
||||
{
|
||||
readonly ReadOnlyMemory<byte> _cacheData;
|
||||
|
||||
public ContentCacheStrategy(string xdbPath) : base(xdbPath)
|
||||
{
|
||||
_cacheData = base.GetData(0, (int)XdbFileStream.Length);
|
||||
XdbFileStream.Close();
|
||||
XdbFileStream.Dispose();
|
||||
}
|
||||
ReadOnlyMemory<byte> _cacheData = ReadOnlyMemory<byte>.Empty;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,8 +38,13 @@ public static class Util
|
|||
throw new FileNotFoundException("xdb file not fould.", dbPath);
|
||||
}
|
||||
|
||||
XdbVersion ret = default;
|
||||
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);
|
||||
|
||||
try
|
||||
|
|
|
|||
Loading…
Reference in New Issue