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 Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,19 +4,18 @@
|
|||
// @Author Alan Lee <lzh.shap@gmail.com>
|
||||
// @Date 2023/07/23
|
||||
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using IP2Region.Net.Abstractions;
|
||||
using IP2Region.Net.Internal;
|
||||
using IP2Region.Net.Internal.Abstractions;
|
||||
using System.Buffers.Binary;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace IP2Region.Net.XDB;
|
||||
|
||||
public class Searcher : ISearcher
|
||||
{
|
||||
const int SegmentIndexSize = 14;
|
||||
|
||||
private readonly AbstractCacheStrategy _cacheStrategy;
|
||||
public int IoCount => _cacheStrategy.IoCount;
|
||||
|
||||
|
|
@ -40,36 +39,34 @@ public class Searcher : ISearcher
|
|||
|
||||
public string? Search(uint ip)
|
||||
{
|
||||
var version = new Version() { Length = 4, IndexSize = 14 };
|
||||
var index = _cacheStrategy.GetVectorIndex(ip);
|
||||
uint sPtr = MemoryMarshal.Read<uint>(index.Span);
|
||||
uint ePtr = MemoryMarshal.Read<uint>(index.Span.Slice(4));
|
||||
|
||||
var dataLen = 0;
|
||||
uint dataLen = 0;
|
||||
uint dataPtr = 0;
|
||||
uint l = 0;
|
||||
uint h = (ePtr -sPtr) / SegmentIndexSize;
|
||||
uint h = (ePtr - sPtr) / (uint)version.IndexSize;
|
||||
|
||||
while (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);
|
||||
uint sip = MemoryMarshal.Read<uint>(buffer.Span);
|
||||
uint eip = MemoryMarshal.Read<uint>(buffer.Span.Slice(4));
|
||||
|
||||
if (ip < sip)
|
||||
if (ip < version.GetVectorIndexStartPos(buffer))
|
||||
{
|
||||
h = mid - 1;
|
||||
}
|
||||
else if (ip > eip)
|
||||
else if (ip > version.GetVectorIndexEndPos(buffer))
|
||||
{
|
||||
l = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataLen = MemoryMarshal.Read<ushort>(buffer.Span.Slice(8));
|
||||
dataPtr = MemoryMarshal.Read<uint>(buffer.Span.Slice(10));
|
||||
dataLen = BinaryPrimitives.ReadUInt16LittleEndian(buffer.Span.Slice(8));
|
||||
dataPtr = BinaryPrimitives.ReadUInt32LittleEndian(buffer.Span.Slice(10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +76,7 @@ public class Searcher : ISearcher
|
|||
return default;
|
||||
}
|
||||
|
||||
var regionBuff = _cacheStrategy.GetData((int)dataPtr,dataLen);
|
||||
var regionBuff = _cacheStrategy.GetData((int)dataPtr, (int)dataLen);
|
||||
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