diff --git a/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs b/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs index 9ba96af..e277dde 100644 --- a/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs +++ b/binding/csharp/IP2Region.Net/Internal/Abstractions/AbstractCacheStrategy.cs @@ -10,11 +10,21 @@ namespace IP2Region.Net.Internal.Abstractions; internal abstract class AbstractCacheStrategy(string xdbPath) { - private const int BufferSize = 4096; + private const int BufferSize = 64 * 1024; - internal int IoCount { get; private set; } + public int IoCount { get; private set; } - internal virtual ReadOnlyMemory GetData(int offset, int length) + public void ResetIoCount() + { + IoCount = 0; + } + + public virtual ReadOnlyMemory GetVectorIndexStartPos(int offset) + { + return GetData(256 + offset, 8); + } + + public virtual ReadOnlyMemory GetData(int offset, int length) { byte[] buffer = ArrayPool.Shared.Rent(length); int totalBytesRead = 0; diff --git a/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs b/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs index 0ef7251..94e7f51 100644 --- a/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs +++ b/binding/csharp/IP2Region.Net/Internal/ContentCacheStrategy.cs @@ -10,9 +10,9 @@ namespace IP2Region.Net.Internal; class ContentCacheStrategy(string xdbPath) : AbstractCacheStrategy(xdbPath) { - ReadOnlyMemory _cacheData = ReadOnlyMemory.Empty; + ReadOnlyMemory _cacheData = default; - internal override ReadOnlyMemory GetData(int offset, int length) + public override ReadOnlyMemory GetData(int offset, int length) { if (_cacheData.IsEmpty) { diff --git a/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs b/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs index e9eb40a..4dea3fe 100644 --- a/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs +++ b/binding/csharp/IP2Region.Net/Internal/VectorIndexCacheStrategy.cs @@ -8,18 +8,16 @@ using IP2Region.Net.Internal.Abstractions; namespace IP2Region.Net.Internal; -internal class VectorIndexCacheStrategy : AbstractCacheStrategy +internal class VectorIndexCacheStrategy(string xdbPath) : AbstractCacheStrategy(xdbPath) { - const int HeaderInfoLength = 256; - const int VectorIndexRows = 256; - const int VectorIndexCols = 256; - const int VectorIndexSize = 8; + ReadOnlyMemory _vectorCahe = default; - readonly ReadOnlyMemory _vectorIndex; - - public VectorIndexCacheStrategy(string xdbPath) : base(xdbPath) + public override ReadOnlyMemory GetVectorIndexStartPos(int offset) { - var vectorLength = VectorIndexRows * VectorIndexCols * VectorIndexSize; - _vectorIndex = base.GetData(HeaderInfoLength, vectorLength); + if (_vectorCahe.IsEmpty) + { + _vectorCahe = base.GetData(256, 256 * 256 * 8); + } + return _vectorCahe.Slice(offset, 8); } } diff --git a/binding/csharp/IP2Region.Net/XDB/Searcher.cs b/binding/csharp/IP2Region.Net/XDB/Searcher.cs index 5fcbf30..1aa7fc6 100644 --- a/binding/csharp/IP2Region.Net/XDB/Searcher.cs +++ b/binding/csharp/IP2Region.Net/XDB/Searcher.cs @@ -40,7 +40,7 @@ public class Searcher : ISearcher public string? Search(string ipStr) { var ipAddress = IPAddress.Parse(ipStr); - return Search(ipAddress); + return SearchCore(ipAddress.GetAddressBytes()); } /// @@ -63,6 +63,9 @@ public class Searcher : ISearcher string? SearchCore(byte[] ipBytes) { + // 重置 IO 计数器 + _cacheStrategy.ResetIoCount(); + // 每个 vector 索引项的字节数 var vectorIndexSize = 8; @@ -74,7 +77,7 @@ public class Searcher : ISearcher var il1 = ipBytes[1]; var idx = il0 * vectorIndexCols * vectorIndexSize + il1 * vectorIndexSize; - var data = _cacheStrategy.GetData(256 + idx, vectorIndexSize); + var data = _cacheStrategy.GetVectorIndexStartPos(idx); var sPtr = BinaryPrimitives.ReadUInt32LittleEndian(data.Span); var ePtr = BinaryPrimitives.ReadUInt32LittleEndian(data.Span.Slice(4));