From 8573f2f04e729a8de8e776abaae3470ad08ab9bc Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 4 Nov 2025 15:45:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20Version=20?= =?UTF-8?q?=E9=80=82=E9=85=8D=20ipV6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/ServiceCollectionExtensions.cs | 8 ++++- binding/csharp/IP2Region.Net/XDB/Searcher.cs | 31 +++++++++---------- binding/csharp/IP2Region.Net/XDB/Version.cs | 20 ++++++++++++ 3 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 binding/csharp/IP2Region.Net/XDB/Version.cs diff --git a/binding/csharp/IP2Region.Net/Extensions/ServiceCollectionExtensions.cs b/binding/csharp/IP2Region.Net/Extensions/ServiceCollectionExtensions.cs index 980243a..b12278d 100644 --- a/binding/csharp/IP2Region.Net/Extensions/ServiceCollectionExtensions.cs +++ b/binding/csharp/IP2Region.Net/Extensions/ServiceCollectionExtensions.cs @@ -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 +// @Date 2023/07/25 + +using IP2Region.Net.Abstractions; using IP2Region.Net.XDB; using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/binding/csharp/IP2Region.Net/XDB/Searcher.cs b/binding/csharp/IP2Region.Net/XDB/Searcher.cs index de29dc9..d684387 100644 --- a/binding/csharp/IP2Region.Net/XDB/Searcher.cs +++ b/binding/csharp/IP2Region.Net/XDB/Searcher.cs @@ -4,19 +4,18 @@ // @Author Alan Lee // @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(index.Span); uint ePtr = MemoryMarshal.Read(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(buffer.Span); - uint eip = MemoryMarshal.Read(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(buffer.Span.Slice(8)); - dataPtr = MemoryMarshal.Read(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()); } } \ No newline at end of file diff --git a/binding/csharp/IP2Region.Net/XDB/Version.cs b/binding/csharp/IP2Region.Net/XDB/Version.cs new file mode 100644 index 0000000..8a4e014 --- /dev/null +++ b/binding/csharp/IP2Region.Net/XDB/Version.cs @@ -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 buffer) + { + return BinaryPrimitives.ReadUInt32LittleEndian(buffer.Span); + } + + public uint GetVectorIndexEndPos(ReadOnlyMemory buffer) + { + return BinaryPrimitives.ReadUInt32LittleEndian(buffer.Slice(Length).Span); + } +}