feat: 增加 Version 适配 ipV6
This commit is contained in:
parent
ef7ac3c088
commit
8573f2f04e
|
|
@ -1,4 +1,10 @@
|
||||||
using IP2Region.Net.Abstractions;
|
// Copyright 2023 The Ip2Region Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a Apache2.0-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
// @Author Alan <lzh.shap@gmail.com>
|
||||||
|
// @Date 2023/07/25
|
||||||
|
|
||||||
|
using IP2Region.Net.Abstractions;
|
||||||
using IP2Region.Net.XDB;
|
using IP2Region.Net.XDB;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,18 @@
|
||||||
// @Author Alan Lee <lzh.shap@gmail.com>
|
// @Author Alan Lee <lzh.shap@gmail.com>
|
||||||
// @Date 2023/07/23
|
// @Date 2023/07/23
|
||||||
|
|
||||||
using System.Net;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
using IP2Region.Net.Abstractions;
|
using IP2Region.Net.Abstractions;
|
||||||
using IP2Region.Net.Internal;
|
using IP2Region.Net.Internal;
|
||||||
using IP2Region.Net.Internal.Abstractions;
|
using IP2Region.Net.Internal.Abstractions;
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Net;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace IP2Region.Net.XDB;
|
namespace IP2Region.Net.XDB;
|
||||||
|
|
||||||
public class Searcher : ISearcher
|
public class Searcher : ISearcher
|
||||||
{
|
{
|
||||||
const int SegmentIndexSize = 14;
|
|
||||||
|
|
||||||
private readonly AbstractCacheStrategy _cacheStrategy;
|
private readonly AbstractCacheStrategy _cacheStrategy;
|
||||||
public int IoCount => _cacheStrategy.IoCount;
|
public int IoCount => _cacheStrategy.IoCount;
|
||||||
|
|
||||||
|
|
@ -40,36 +39,34 @@ public class Searcher : ISearcher
|
||||||
|
|
||||||
public string? Search(uint ip)
|
public string? Search(uint ip)
|
||||||
{
|
{
|
||||||
|
var version = new Version() { Length = 4, IndexSize = 14 };
|
||||||
var index = _cacheStrategy.GetVectorIndex(ip);
|
var index = _cacheStrategy.GetVectorIndex(ip);
|
||||||
uint sPtr = MemoryMarshal.Read<uint>(index.Span);
|
uint sPtr = MemoryMarshal.Read<uint>(index.Span);
|
||||||
uint ePtr = MemoryMarshal.Read<uint>(index.Span.Slice(4));
|
uint ePtr = MemoryMarshal.Read<uint>(index.Span.Slice(4));
|
||||||
|
|
||||||
var dataLen = 0;
|
uint dataLen = 0;
|
||||||
uint dataPtr = 0;
|
uint dataPtr = 0;
|
||||||
uint l = 0;
|
uint l = 0;
|
||||||
uint h = (ePtr -sPtr) / SegmentIndexSize;
|
uint h = (ePtr - sPtr) / (uint)version.IndexSize;
|
||||||
|
|
||||||
while (l <= h)
|
while (l <= h)
|
||||||
{
|
{
|
||||||
var mid = Util.GetMidIp(l, h);
|
var mid = Util.GetMidIp(l, h);
|
||||||
var pos = sPtr + mid * SegmentIndexSize;
|
var pos = sPtr + mid * version.IndexSize;
|
||||||
|
var buffer = _cacheStrategy.GetData((int)pos, version.IndexSize);
|
||||||
|
|
||||||
var buffer = _cacheStrategy.GetData((int)pos, SegmentIndexSize);
|
if (ip < version.GetVectorIndexStartPos(buffer))
|
||||||
uint sip = MemoryMarshal.Read<uint>(buffer.Span);
|
|
||||||
uint eip = MemoryMarshal.Read<uint>(buffer.Span.Slice(4));
|
|
||||||
|
|
||||||
if (ip < sip)
|
|
||||||
{
|
{
|
||||||
h = mid - 1;
|
h = mid - 1;
|
||||||
}
|
}
|
||||||
else if (ip > eip)
|
else if (ip > version.GetVectorIndexEndPos(buffer))
|
||||||
{
|
{
|
||||||
l = mid + 1;
|
l = mid + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataLen = MemoryMarshal.Read<ushort>(buffer.Span.Slice(8));
|
dataLen = BinaryPrimitives.ReadUInt16LittleEndian(buffer.Span.Slice(8));
|
||||||
dataPtr = MemoryMarshal.Read<uint>(buffer.Span.Slice(10));
|
dataPtr = BinaryPrimitives.ReadUInt32LittleEndian(buffer.Span.Slice(10));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +76,7 @@ public class Searcher : ISearcher
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
var regionBuff = _cacheStrategy.GetData((int)dataPtr,dataLen);
|
var regionBuff = _cacheStrategy.GetData((int)dataPtr, (int)dataLen);
|
||||||
return Encoding.UTF8.GetString(regionBuff.Span.ToArray());
|
return Encoding.UTF8.GetString(regionBuff.Span.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
|
||||||
|
namespace IP2Region.Net.XDB;
|
||||||
|
|
||||||
|
public struct Version
|
||||||
|
{
|
||||||
|
public int IndexSize { get; set; }
|
||||||
|
|
||||||
|
public int Length { get; set; }
|
||||||
|
|
||||||
|
public uint GetVectorIndexStartPos(ReadOnlyMemory<byte> buffer)
|
||||||
|
{
|
||||||
|
return BinaryPrimitives.ReadUInt32LittleEndian(buffer.Span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetVectorIndexEndPos(ReadOnlyMemory<byte> buffer)
|
||||||
|
{
|
||||||
|
return BinaryPrimitives.ReadUInt32LittleEndian(buffer.Slice(Length).Span);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue