feat: 增加 Version 适配 ipV6

This commit is contained in:
Argo Zhang 2025-11-04 15:45:38 +08:00
parent ef7ac3c088
commit 8573f2f04e
3 changed files with 41 additions and 18 deletions

View File

@ -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;

View File

@ -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());
} }
} }

View File

@ -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);
}
}