refactor: 重构代码
This commit is contained in:
parent
14d2332483
commit
426038b3fe
|
|
@ -14,37 +14,37 @@ public class Benchmarks
|
|||
{
|
||||
private static readonly string XdbPathV4 = Path.Combine(AppContext.BaseDirectory, "IP2Region", "ip2region_v4.xdb");
|
||||
private static readonly string XdbPathV6 = Path.Combine(AppContext.BaseDirectory, "IP2Region", "ip2region_v6.xdb");
|
||||
private static readonly Searcher _contentV4Searcher = new Searcher(CachePolicy.Content, XdbPathV4);
|
||||
private static readonly Searcher _vectorV4Searcher = new Searcher(CachePolicy.VectorIndex, XdbPathV4);
|
||||
private static readonly Searcher _fileV4Searcher = new Searcher(CachePolicy.File, XdbPathV4);
|
||||
private static readonly Searcher _contentV6Searcher = new Searcher(CachePolicy.Content, XdbPathV6);
|
||||
private static readonly Searcher _vectorV6Searcher = new Searcher(CachePolicy.VectorIndex, XdbPathV6);
|
||||
private static readonly Searcher _fileV6Searcher = new Searcher(CachePolicy.File, XdbPathV6);
|
||||
private static readonly Searcher _contentV4Searcher = new(CachePolicy.Content, XdbPathV4);
|
||||
private static readonly Searcher _vectorV4Searcher = new(CachePolicy.VectorIndex, XdbPathV4);
|
||||
private static readonly Searcher _fileV4Searcher = new(CachePolicy.File, XdbPathV4);
|
||||
private static readonly Searcher _contentV6Searcher = new(CachePolicy.Content, XdbPathV6);
|
||||
private static readonly Searcher _vectorV6Searcher = new(CachePolicy.VectorIndex, XdbPathV6);
|
||||
private static readonly Searcher _fileV6Searcher = new(CachePolicy.File, XdbPathV6);
|
||||
|
||||
private readonly string _testIpV4Address = "114.114.114.114";
|
||||
private readonly string _testIpV6Address = "240e:3b7:3272:d8d0:db09:c067:8d59:539e";
|
||||
private readonly string _testIPv4Address = "114.114.114.114";
|
||||
private readonly string _testIPv6Address = "240e:3b7:3272:d8d0:db09:c067:8d59:539e";
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory(nameof(CachePolicy.Content))]
|
||||
public void ContentIpV4() => _contentV4Searcher.Search(_testIpV4Address);
|
||||
|
||||
//[Benchmark]
|
||||
[BenchmarkCategory(nameof(CachePolicy.VectorIndex))]
|
||||
public void VectorIndexIpV4() => _vectorV4Searcher.Search(_testIpV4Address);
|
||||
[BenchmarkCategory("IPv4")]
|
||||
public void ContentIPv4() => _contentV4Searcher.Search(_testIPv4Address);
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory(nameof(CachePolicy.File))]
|
||||
public void FileIpV4() => _fileV4Searcher.Search(_testIpV4Address);
|
||||
[BenchmarkCategory("IPv4")]
|
||||
public void VectorIPv4() => _vectorV4Searcher.Search(_testIPv4Address);
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory(nameof(CachePolicy.Content))]
|
||||
public void ContentIpV6() => _contentV6Searcher.Search(_testIpV6Address);
|
||||
[BenchmarkCategory("IPv4")]
|
||||
public void FileIPv4() => _fileV4Searcher.Search(_testIPv4Address);
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory(nameof(CachePolicy.VectorIndex))]
|
||||
public void VectorIndexIpV6() => _vectorV6Searcher.Search(_testIpV6Address);
|
||||
[BenchmarkCategory("IPv6")]
|
||||
public void ContentIPv6() => _contentV6Searcher.Search(_testIPv6Address);
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory(nameof(CachePolicy.File))]
|
||||
public void FileIpV6() => _fileV6Searcher.Search(_testIpV6Address);
|
||||
[BenchmarkCategory("IPv6")]
|
||||
public void VectorIPv6() => _vectorV6Searcher.Search(_testIPv6Address);
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("IPv6")]
|
||||
public void FileIPv6() => _fileV6Searcher.Search(_testIPv6Address);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,17 +80,6 @@ public class SearcherTest
|
|||
Assert.Equal(3, searcher.IoCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IoCount_Content_Ok()
|
||||
{
|
||||
var searcher = new Searcher(CachePolicy.Content, _xdbPathV4);
|
||||
searcher.Search("58.251.27.201");
|
||||
Assert.Equal(0, searcher.IoCount);
|
||||
|
||||
searcher.Search("58.251.27.201");
|
||||
Assert.Equal(0, searcher.IoCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IoCount_Vector_Ok()
|
||||
{
|
||||
|
|
@ -102,6 +91,17 @@ public class SearcherTest
|
|||
Assert.Equal(2, searcher.IoCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IoCount_Content_Ok()
|
||||
{
|
||||
var searcher = new Searcher(CachePolicy.Content, _xdbPathV4);
|
||||
searcher.Search("58.251.27.201");
|
||||
Assert.Equal(0, searcher.IoCount);
|
||||
|
||||
searcher.Search("58.251.27.201");
|
||||
Assert.Equal(0, searcher.IoCount);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("58.251.255.255", "中国|广东省|深圳市|联通")]
|
||||
public void Search_Ip_Ok(string ipStr, string expected)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@ namespace IP2Region.Net.Internal.Abstractions;
|
|||
|
||||
internal abstract class AbstractCacheStrategy(string xdbPath)
|
||||
{
|
||||
protected const int HeaderInfoLength = 256;
|
||||
protected const int VectorIndexSize = 8;
|
||||
|
||||
private const int BufferSize = 64 * 1024;
|
||||
private readonly FileStream _xdbFileStream = new(xdbPath, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize, FileOptions.RandomAccess);
|
||||
|
||||
public int IoCount { get; private set; }
|
||||
|
||||
|
|
@ -20,25 +24,26 @@ internal abstract class AbstractCacheStrategy(string xdbPath)
|
|||
IoCount = 0;
|
||||
}
|
||||
|
||||
public virtual ReadOnlyMemory<byte> GetVectorIndexStartPos(int offset)
|
||||
{
|
||||
return GetData(256 + offset, 8);
|
||||
}
|
||||
public virtual ReadOnlyMemory<byte> GetVectorIndex(int offset) => GetData(HeaderInfoLength + offset, VectorIndexSize);
|
||||
|
||||
public virtual ReadOnlyMemory<byte> GetData(int offset, int length)
|
||||
public virtual ReadOnlyMemory<byte> GetData(int offset = 0, int length = 0)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
length = (int)_xdbFileStream.Length;
|
||||
}
|
||||
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(length);
|
||||
int totalBytesRead = 0;
|
||||
try
|
||||
{
|
||||
var stream = GetXdbFileStream();
|
||||
stream.Seek(offset, SeekOrigin.Begin);
|
||||
_xdbFileStream.Seek(offset, SeekOrigin.Begin);
|
||||
|
||||
int bytesRead;
|
||||
while (totalBytesRead < length)
|
||||
{
|
||||
int bytesToRead = Math.Min(BufferSize, length - totalBytesRead);
|
||||
bytesRead = stream.Read(buffer, totalBytesRead, bytesToRead);
|
||||
bytesRead = _xdbFileStream.Read(buffer, totalBytesRead, bytesToRead);
|
||||
totalBytesRead += bytesRead;
|
||||
|
||||
IoCount++;
|
||||
|
|
@ -51,15 +56,4 @@ internal abstract class AbstractCacheStrategy(string xdbPath)
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using IP2Region.Net.XDB;
|
|||
|
||||
namespace IP2Region.Net.Internal;
|
||||
|
||||
internal class CacheStrategyFactory(string xdbPath)
|
||||
class CacheStrategyFactory(string xdbPath)
|
||||
{
|
||||
public AbstractCacheStrategy CreateCacheStrategy(CachePolicy cachePolicy) => cachePolicy switch
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,16 +11,12 @@ namespace IP2Region.Net.Internal;
|
|||
|
||||
class ContentCacheStrategy : AbstractCacheStrategy
|
||||
{
|
||||
readonly ReadOnlyMemory<byte> _cacheData = default;
|
||||
private readonly ReadOnlyMemory<byte> _cacheData;
|
||||
|
||||
public ContentCacheStrategy(string xdbPath) : base(xdbPath)
|
||||
{
|
||||
using var reader = base.GetXdbFileStream();
|
||||
_cacheData = base.GetData(0, (int)reader.Length);
|
||||
_cacheData = base.GetData();
|
||||
}
|
||||
|
||||
public override ReadOnlyMemory<byte> GetData(int offset, int length)
|
||||
{
|
||||
return _cacheData.Slice(offset, length);
|
||||
}
|
||||
public override ReadOnlyMemory<byte> GetData(int offset = 0, int length = 0) => _cacheData.Slice(offset, length);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,14 +9,17 @@ using IP2Region.Net.Internal.Abstractions;
|
|||
|
||||
namespace IP2Region.Net.Internal;
|
||||
|
||||
internal class VectorIndexCacheStrategy : AbstractCacheStrategy
|
||||
class VectorIndexCacheStrategy : AbstractCacheStrategy
|
||||
{
|
||||
readonly ReadOnlyMemory<byte> _vectorCache = default;
|
||||
private const int VectorIndexRows = 256;
|
||||
private const int VectorIndexCols = 256;
|
||||
|
||||
private readonly ReadOnlyMemory<byte> _vectorCache;
|
||||
|
||||
public VectorIndexCacheStrategy(string xdbPath) : base(xdbPath)
|
||||
{
|
||||
_vectorCache = base.GetData(256, 256 * 256 * 8);
|
||||
_vectorCache = GetData(HeaderInfoLength, VectorIndexRows * VectorIndexCols * VectorIndexSize);
|
||||
}
|
||||
|
||||
public override ReadOnlyMemory<byte> GetVectorIndexStartPos(int offset) => _vectorCache.Slice(offset, 8);
|
||||
public override ReadOnlyMemory<byte> GetVectorIndex(int offset) => _vectorCache.Slice(offset, VectorIndexSize);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,9 +78,9 @@ public class Searcher : ISearcher
|
|||
var il1 = ipBytes[1];
|
||||
var idx = il0 * vectorIndexCols * vectorIndexSize + il1 * vectorIndexSize;
|
||||
|
||||
var data = _cacheStrategy.GetVectorIndexStartPos(idx);
|
||||
var sPtr = BinaryPrimitives.ReadUInt32LittleEndian(data.Span);
|
||||
var ePtr = BinaryPrimitives.ReadUInt32LittleEndian(data.Span.Slice(4));
|
||||
var vector = _cacheStrategy.GetVectorIndex(idx);
|
||||
var sPtr = BinaryPrimitives.ReadUInt32LittleEndian(vector.Span);
|
||||
var ePtr = BinaryPrimitives.ReadUInt32LittleEndian(vector.Span.Slice(4));
|
||||
|
||||
var length = ipBytes.Length;
|
||||
var indexSize = length * 2 + 6;
|
||||
|
|
@ -125,11 +125,12 @@ public class Searcher : ISearcher
|
|||
var ret = 0;
|
||||
for (int i = 0; i < ip1.Length; i++)
|
||||
{
|
||||
if (ip1[i] < ip2[ip1.Length - 1 - i])
|
||||
var ip2Index = ip1.Length - 1 - i;
|
||||
if (ip1[i] < ip2[ip2Index])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (ip1[i] > ip2[ip1.Length - 1 - i])
|
||||
else if (ip1[i] > ip2[ip2Index])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue