From 9b85ae821a2c7005ce083fb383957b0e43b5a6ba Mon Sep 17 00:00:00 2001 From: ayflying Date: Thu, 18 Sep 2025 17:54:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9F=A5=E7=9C=8Bipv6?= =?UTF-8?q?=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/logic/ip2region/ip2region.go | 98 +++++++++++++++++++-------- service/ip_2_region.go | 6 +- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/internal/logic/ip2region/ip2region.go b/internal/logic/ip2region/ip2region.go index 046ea1e..0c0fd5c 100644 --- a/internal/logic/ip2region/ip2region.go +++ b/internal/logic/ip2region/ip2region.go @@ -2,6 +2,7 @@ package ip2region import ( "net" + "path" "strings" "github.com/ayflying/utility_go/service" @@ -16,14 +17,14 @@ var ( wait = false ) -const IpDbPath = "runtime/library/ip2region.xdb" +const IpDbPath = "runtime/library" type sIp2region struct { - searcher *xdb.Searcher + //searcher *xdb.Searcher + searchers map[string]*xdb.Searcher } func New() *sIp2region { - return &sIp2region{} } @@ -35,20 +36,35 @@ func init() { //}) } +//func (s *sIp2region) New() *xdb.Searcher { +// +// return nil +//} + // Load 加载到内存中 // // @Description: 加载ip2region数据库到内存中。 // @receiver s *sIp2region: sIp2region的实例。 -func (s *sIp2region) Load() { +func (s *sIp2region) Load(t *xdb.Version) { var err error - + var url string //var dbPath = "runtime/library/ip2region.xdb" - var url = "https://github.com/ayflying/resource/raw/refs/heads/master/attachment/ip2region.xdb" + switch t { + case xdb.IPv4: + //url = "https://github.com/ayflying/resource/raw/refs/heads/master/attachment/ip2region_v4.xdb" + url = "https://github.com/lionsoul2014/ip2region/raw/refs/heads/master/data/ip2region_v4.xdb" + case xdb.IPv6: + url = "https://github.com/lionsoul2014/ip2region/raw/refs/heads/master/data/ip2region_v6.xdb" + } + if wait { return } - if gfile.IsEmpty(IpDbPath) { + filename := gfile.Basename(url) + var IpDbFile = path.Join(IpDbPath, filename) + g.Log().Debugf(ctx, "加载ip库文件:%v", filename) + if gfile.IsEmpty(IpDbFile) { wait = true defer func() { wait = false @@ -59,44 +75,68 @@ func (s *sIp2region) Load() { if err2 != nil { return } - err = gfile.PutBytes(IpDbPath, putData.ReadAll()) + err = gfile.PutBytes(IpDbFile, putData.ReadAll()) } - cBuff := gfile.GetBytes(IpDbPath) - /* - var cBuff []byte - if gres.Contains(dbPath) { - cBuff = gres.GetContent(dbPath) - } else { - cBuff = gfile.GetBytes(dbPath) - } - */ - // 基于读取的内容,创建查询对象 - s.searcher, err = xdb.NewWithBuffer(xdb.IPv4, cBuff) + err = xdb.VerifyFromFile(IpDbFile) if err != nil { - g.Log().Errorf(ctx, "无法创建内容为的搜索器: %s", err) + // err 包含的验证的错误 + gfile.RemoveFile(IpDbFile) + g.Log().Errorf(ctx, "ip库xdb file verify: %v", err) return } + // 1、从 dbPath 加载 VectorIndex 缓存,把下述 vIndex 变量全局到内存里面。 + vIndex, err := xdb.LoadVectorIndexFromFile(IpDbFile) + if err != nil { + g.Log().Errorf(ctx, "failed to load vector index from `%s`: %s\n", IpDbFile, err) + return + } + // 2、用全局的 vIndex 创建带 VectorIndex 缓存的查询对象。 + if s.searchers == nil { + s.searchers = make(map[string]*xdb.Searcher) + } + s.searchers[t.Name], err = xdb.NewWithVectorIndex(t, IpDbFile, vIndex) + if err != nil { + g.Log().Errorf(ctx, "failed to create searcher with vector index: %s\n", err) + return + } + + //cBuff := gfile.GetBytes(IpDbFile) + //// 基于读取的内容,创建查询对象 + //s.searchers[t.Name], err = xdb.NewWithBuffer(t, cBuff) + //if err != nil { + // g.Log().Errorf(ctx, "无法创建内容为的搜索器: %s", err) + // return + //} + } func (s *sIp2region) GetIp(ip string) (res []string) { //初始化加载 - if s.searcher == nil { - s.Load() + //if s.searcher == nil { + // s.Load(xdb.IPv6) + //} + var searchers *xdb.Searcher + //区分ipv6与ipv4 + if s.isIPv6(ip) { + if s.searchers[xdb.IPv6.Name] == nil { + s.Load(xdb.IPv6) + } + searchers = s.searchers[xdb.IPv6.Name] + } else { + if s.searchers[xdb.IPv4.Name] == nil { + s.Load(xdb.IPv4) + } + searchers = s.searchers[xdb.IPv4.Name] } res = make([]string, 5) - if s.searcher == nil { + if searchers == nil { return } - //如果是ipv6直接跳过 - if s.isIPv6(ip) { - return - } - - region, err := s.searcher.SearchByStr(ip) + region, err := searchers.SearchByStr(ip) if err != nil { return } diff --git a/service/ip_2_region.go b/service/ip_2_region.go index 31b2260..b229056 100644 --- a/service/ip_2_region.go +++ b/service/ip_2_region.go @@ -5,10 +5,14 @@ package service +import ( + "github.com/lionsoul2014/ip2region/binding/golang/xdb" +) + type ( IIp2Region interface { // @receiver s *sIp2region: sIp2region的实例。 - Load() + Load(t *xdb.Version) GetIp(ip string) (res []string) } )