mirror of
https://github.com/lionsoul2014/ip2region.git
synced 2025-12-08 19:25:22 +00:00
search test driven by ip2region service
This commit is contained in:
parent
b44654230f
commit
6531f3970f
@ -178,39 +178,40 @@ make
|
||||
|
||||
# 查询测试
|
||||
|
||||
通过 `xdb_searcher search` 命令来测试 xdb 的查询:
|
||||
### 查询命令
|
||||
通过 `./xdb_searcher search` 命令来测试 xdb 的查询:
|
||||
```bash
|
||||
➜ golang git:(fr_xdb_ipv6) ✗ ./xdb_searcher search
|
||||
➜ golang git:(master) ✗ ./xdb_searcher search --help
|
||||
./xdb_searcher search [command options]
|
||||
options:
|
||||
--db string ip2region binary xdb file path
|
||||
--cache-policy string cache policy: file/vectorIndex/content
|
||||
--v4-db string ip2region v4 binary xdb file path
|
||||
--v4-cache-policy string v4 cache policy, default vectorIndex, options: file/vectorIndex/content
|
||||
--v6-db string ip2region v6 binary xdb file path
|
||||
--v6-cache-policy string v6 cache policy, default vectorIndex, options: file/vectorIndex/content
|
||||
--help print this help menu
|
||||
```
|
||||
|
||||
例如:使用默认的 data/ip2region_v4.xdb 进行 IPv4 的查询测试
|
||||
### 参数解析
|
||||
1. `v4-xdb`: IPv4 的 xdb 文件路径,默认为仓库中的 data/ip2region_v4.xdb
|
||||
2. `v6-xdb`: IPv6 的 xdb 文件路径,默认为仓库中的 data/ip2region_v6.xdb
|
||||
3. `v4-cache-policy`: v4 查询使用的缓存策略,默认为 `vectorIndex`,可选:file/vectorIndex/content
|
||||
4. `v6-cache-policy`: v6 查询使用的缓存策略,默认为 `vectorIndex`,可选:file/vectorIndex/content
|
||||
|
||||
### 测试 Demo
|
||||
例如:使用默认的 data/ip2region_v4.xdb 和 data/ip2region_v6.xdb 进行查询测试:
|
||||
```bash
|
||||
➜ golang git:(master) ./xdb_searcher search --db=../../data/ip2region_v4.xdb
|
||||
ip2region xdb searcher test program
|
||||
source xdb: ../../data/ip2region_v4.xdb (IPv4, vectorIndex)
|
||||
➜ golang git:(master) ✗ ./xdb_searcher search
|
||||
ip2region search service test program
|
||||
+-v4 db: /data01/code/c/ip2region/data/ip2region_v4.xdb (vectorIndex)
|
||||
+-v6 db: /data01/code/c/ip2region/data/ip2region_v6.xdb (vectorIndex)
|
||||
type 'quit' to exit
|
||||
ip2region>> 219.133.111.87
|
||||
{region: 中国|广东省|深圳市|电信, ioCount: 2, took: 19.005µs}
|
||||
ip2region>>
|
||||
ip2region>> 1.2.3.4
|
||||
{region: 美国|华盛顿|0|谷歌, took: 69.088µs}
|
||||
ip2region>> 240e:3b7:3272:d8d0:db09:c067:8d59:539e
|
||||
{region: 中国|广东省|深圳市|家庭宽带, took: 67.756µs}
|
||||
ip2region>>
|
||||
```
|
||||
|
||||
例如:使用默认的 data/ip2region_v6.xdb 进行 IPv6 的查询:
|
||||
```bash
|
||||
➜ golang git:(master) ✗ ./xdb_searcher search --db=../../data/ip2region_v6.xdb
|
||||
ip2region xdb searcher test program
|
||||
source xdb: ../../data/ip2region_v6.xdb (IPv6, vectorIndex)
|
||||
type 'quit' to exit
|
||||
ip2region>> ::
|
||||
{region: , ioCount: 1, took: 42.157µs}
|
||||
ip2region>> 240e:87c:892:ffff:ffff:ffff:ffff:ffff
|
||||
{region: 中国|北京市|北京市|专线用户, ioCount: 10, took: 88.769µs}
|
||||
```
|
||||
|
||||
输入对应版本的 ip 地址进行查询即可,输入 quit 退出测试程序。可以设置 `cache-policy` 为 file/vectorIndex/content 来测试不同的查询缓存机制。
|
||||
输入 v4 或者 v6 的 IP 地址即可进行查询测试,也可以分别设置 `cache-policy` 为 file/vectorIndex/content 来测试三种不同缓存实现的查询效果。
|
||||
|
||||
|
||||
# bench 测试
|
||||
|
||||
@ -13,13 +13,114 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/service"
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
func getXdbPath(fileName string) (string, error) {
|
||||
binPath, err := os.Executable()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get executale: %w", err)
|
||||
}
|
||||
|
||||
xdbPath := filepath.Join(filepath.Dir(filepath.Dir(filepath.Dir(binPath))), "/data/", fileName)
|
||||
_, err = os.Stat(xdbPath)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// fmt.Printf("xdbPath=%s\n", xdbPath)
|
||||
return xdbPath, nil
|
||||
}
|
||||
|
||||
func createService(v4XdbPath string, v4CachePolicy string, v6XdbPath string, v6CachePolicy string) (*service.Ip2Region, error) {
|
||||
// try to create v4 config
|
||||
v4CPolicy, err := service.CachePolicyFromName(v4CachePolicy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse v4 cache policy: %w", err)
|
||||
}
|
||||
|
||||
v4DbPath, err := homedir.Expand(v4XdbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Expand(`%s`): %s", v4XdbPath, err)
|
||||
}
|
||||
v4Config, err := service.NewV4Config(v4CPolicy, v4DbPath, 1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewV4Config: %w", err)
|
||||
}
|
||||
|
||||
// try to create v6 config
|
||||
v6Policy, err := service.CachePolicyFromName(v6CachePolicy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse v6 cache policy: %w", err)
|
||||
}
|
||||
|
||||
v6DbPath, err := homedir.Expand(v6XdbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Expand(`%s`): %s", v6XdbPath, err)
|
||||
}
|
||||
v6Config, err := service.NewV6Config(v6Policy, v6DbPath, 1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewV6Config: %w", err)
|
||||
}
|
||||
|
||||
return service.NewIp2Region(v4Config, v6Config)
|
||||
}
|
||||
|
||||
func createSearcher(dbPath string, cachePolicy string) (*xdb.Searcher, error) {
|
||||
handle, err := os.OpenFile(dbPath, os.O_RDONLY, 0600)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open xdb file `%s`: %w", dbPath, err)
|
||||
}
|
||||
|
||||
defer handle.Close()
|
||||
|
||||
// verify the xdb file
|
||||
// @Note: do NOT call it every time you create a searcher since this will slow down the search response.
|
||||
// @see the util.Verify function for details.
|
||||
err = xdb.Verify(handle)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("xdb verify: %w", err)
|
||||
}
|
||||
|
||||
// auto-detect the ip version from the xdb header
|
||||
header, err := xdb.LoadHeader(handle)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load header from `%s`: %s", dbPath, err)
|
||||
}
|
||||
|
||||
version, err := xdb.VersionFromHeader(header)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to detect IP version from `%s`: %s", dbPath, err)
|
||||
}
|
||||
|
||||
switch cachePolicy {
|
||||
case "nil", "file":
|
||||
return xdb.NewWithFileOnly(version, dbPath)
|
||||
case "vectorIndex":
|
||||
vIndex, err := xdb.LoadVectorIndexFromFile(dbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load vector index from `%s`: %w", dbPath, err)
|
||||
}
|
||||
|
||||
return xdb.NewWithVectorIndex(version, dbPath, vIndex)
|
||||
case "content":
|
||||
cBuff, err := xdb.LoadContentFromFile(dbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load content from '%s': %w", dbPath, err)
|
||||
}
|
||||
|
||||
return xdb.NewWithBuffer(version, cBuff)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid cache policy `%s`, options: file/vectorIndex/content", cachePolicy)
|
||||
}
|
||||
}
|
||||
|
||||
func printHelp() {
|
||||
fmt.Printf("ip2region xdb searcher\n")
|
||||
fmt.Printf("%s [command] [command options]\n", os.Args[0])
|
||||
@ -30,7 +131,9 @@ func printHelp() {
|
||||
|
||||
func testSearch() {
|
||||
var err error
|
||||
var dbFile, cachePolicy = "", "vectorIndex"
|
||||
var help = ""
|
||||
var v4DbPath, v4CachePolicy = "", "vectorIndex"
|
||||
var v6DbPath, v6CachePolicy = "", "vectorIndex"
|
||||
for i := 2; i < len(os.Args); i++ {
|
||||
r := os.Args[i]
|
||||
if len(r) < 5 {
|
||||
@ -41,52 +144,83 @@ func testSearch() {
|
||||
continue
|
||||
}
|
||||
|
||||
var key, val = "", ""
|
||||
var sIdx = strings.Index(r, "=")
|
||||
if sIdx < 0 {
|
||||
fmt.Printf("missing = for args pair '%s'\n", r)
|
||||
return
|
||||
// fmt.Printf("missing = for args pair '%s'\n", r)
|
||||
// return
|
||||
key = r[2:]
|
||||
} else {
|
||||
key = r[2:sIdx]
|
||||
val = r[sIdx+1:]
|
||||
}
|
||||
|
||||
switch r[2:sIdx] {
|
||||
case "db":
|
||||
dbFile = r[sIdx+1:]
|
||||
case "cache-policy":
|
||||
cachePolicy = r[sIdx+1:]
|
||||
switch key {
|
||||
case "help":
|
||||
if val == "" {
|
||||
help = "true"
|
||||
} else {
|
||||
help = val
|
||||
}
|
||||
case "v4-db":
|
||||
v4DbPath = val
|
||||
case "v4-cache-policy":
|
||||
v4CachePolicy = val
|
||||
case "v6-db":
|
||||
v6DbPath = val
|
||||
case "v6-cache-policy":
|
||||
v6CachePolicy = val
|
||||
default:
|
||||
fmt.Printf("undefined option `%s`\n", r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if dbFile == "" {
|
||||
// check and get the get the default v4 xdb path
|
||||
if v4DbPath == "" {
|
||||
v4DbPath, err = getXdbPath("ip2region_v4.xdb")
|
||||
if err != nil {
|
||||
fmt.Printf("failed to get v4 xdb path: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// check and get the get the default v6 xdb path
|
||||
if v6DbPath == "" {
|
||||
v6DbPath, err = getXdbPath("ip2region_v6.xdb")
|
||||
if err != nil {
|
||||
fmt.Printf("failed to get v6 xdb path: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if v4DbPath == "" || v6DbPath == "" || help == "true" {
|
||||
fmt.Printf("%s search [command options]\n", os.Args[0])
|
||||
fmt.Printf("options:\n")
|
||||
fmt.Printf(" --db string ip2region binary xdb file path\n")
|
||||
fmt.Printf(" --cache-policy string cache policy: file/vectorIndex/content\n")
|
||||
fmt.Printf(" --v4-db string ip2region v4 binary xdb file path\n")
|
||||
fmt.Printf(" --v4-cache-policy string v4 cache policy, default vectorIndex, options: file/vectorIndex/content\n")
|
||||
fmt.Printf(" --v6-db string ip2region v6 binary xdb file path\n")
|
||||
fmt.Printf(" --v6-cache-policy string v6 cache policy, default vectorIndex, options: file/vectorIndex/content\n")
|
||||
fmt.Printf(" --help print this help menu\n")
|
||||
return
|
||||
}
|
||||
|
||||
dbPath, err := homedir.Expand(dbFile)
|
||||
// create the search service with the xdb paths and cache policies
|
||||
ip2region, err := createService(v4DbPath, v4CachePolicy, v6DbPath, v6CachePolicy)
|
||||
if err != nil {
|
||||
fmt.Printf("invalid xdb file path `%s`: %s", dbFile, err)
|
||||
return
|
||||
}
|
||||
|
||||
// create the searcher with the cache policy setting
|
||||
searcher, err := createSearcher(dbPath, cachePolicy)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to create searcher: %s\n", err.Error())
|
||||
fmt.Printf("failed to create ip2region service: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
searcher.Close()
|
||||
ip2region.Close()
|
||||
fmt.Printf("searcher test program exited, thanks for trying\n")
|
||||
}()
|
||||
|
||||
fmt.Printf(`ip2region xdb searcher test program
|
||||
source xdb: %s (%s, %s)
|
||||
fmt.Printf(`ip2region search service test program
|
||||
+-v4 db: %s (%s)
|
||||
+-v6 db: %s (%s)
|
||||
type 'quit' to exit
|
||||
`, dbPath, searcher.IPVersion().Name, cachePolicy)
|
||||
`, v4DbPath, v4CachePolicy, v6DbPath, v6CachePolicy)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
fmt.Print("ip2region>> ")
|
||||
@ -105,11 +239,11 @@ type 'quit' to exit
|
||||
}
|
||||
|
||||
tStart := time.Now()
|
||||
region, err := searcher.SearchByStr(line)
|
||||
region, err := ip2region.SearchByStr(line)
|
||||
if err != nil {
|
||||
fmt.Printf("\x1b[0;31m{err: %s, ioCount: %d}\x1b[0m\n", err.Error(), searcher.GetIOCount())
|
||||
fmt.Printf("\x1b[0;31m{err: %s}\x1b[0m\n", err.Error())
|
||||
} else {
|
||||
fmt.Printf("\x1b[0;32m{region: %s, ioCount: %d, took: %s}\x1b[0m\n", region, searcher.GetIOCount(), time.Since(tStart))
|
||||
fmt.Printf("\x1b[0;32m{region: %s, took: %s}\x1b[0m\n", region, time.Since(tStart))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,55 +364,6 @@ func testBench() {
|
||||
cachePolicy, count, cost, costs/count/1000)
|
||||
}
|
||||
|
||||
func createSearcher(dbPath string, cachePolicy string) (*xdb.Searcher, error) {
|
||||
handle, err := os.OpenFile(dbPath, os.O_RDONLY, 0600)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open xdb file `%s`: %w", dbPath, err)
|
||||
}
|
||||
|
||||
defer handle.Close()
|
||||
|
||||
// verify the xdb file
|
||||
// @Note: do NOT call it every time you create a searcher since this will slow down the search response.
|
||||
// @see the util.Verify function for details.
|
||||
err = xdb.Verify(handle)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("xdb verify: %w", err)
|
||||
}
|
||||
|
||||
// auto-detect the ip version from the xdb header
|
||||
header, err := xdb.LoadHeader(handle)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load header from `%s`: %s", dbPath, err)
|
||||
}
|
||||
|
||||
version, err := xdb.VersionFromHeader(header)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to detect IP version from `%s`: %s", dbPath, err)
|
||||
}
|
||||
|
||||
switch cachePolicy {
|
||||
case "nil", "file":
|
||||
return xdb.NewWithFileOnly(version, dbPath)
|
||||
case "vectorIndex":
|
||||
vIndex, err := xdb.LoadVectorIndexFromFile(dbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load vector index from `%s`: %w", dbPath, err)
|
||||
}
|
||||
|
||||
return xdb.NewWithVectorIndex(version, dbPath, vIndex)
|
||||
case "content":
|
||||
cBuff, err := xdb.LoadContentFromFile(dbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load content from '%s': %w", dbPath, err)
|
||||
}
|
||||
|
||||
return xdb.NewWithBuffer(version, cBuff)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid cache policy `%s`, options: file/vectorIndex/content", cachePolicy)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
printHelp()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user