mirror of
https://github.com/lionsoul2014/ip2region.git
synced 2026-01-25 17:16:11 +00:00
126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/lionsoul2014/ip2region/maker/golang/xdb"
|
|
)
|
|
|
|
func Bench() {
|
|
var err error
|
|
var dbFile, srcFile, ipVersion, logLevel = "", "", "", ""
|
|
var ignoreError = false
|
|
var fErr = iterateFlags(func(key string, val string) error {
|
|
switch key {
|
|
case "db":
|
|
dbFile = val
|
|
case "src":
|
|
srcFile = val
|
|
case "version":
|
|
ipVersion = val
|
|
case "log-level":
|
|
logLevel = val
|
|
case "ignore-error":
|
|
if val == "true" || val == "1" {
|
|
ignoreError = true
|
|
} else if val == "false" || val == "0" {
|
|
ignoreError = false
|
|
} else {
|
|
return fmt.Errorf("invalid value for ignore-error option, could be false/0 or true/1")
|
|
}
|
|
default:
|
|
return fmt.Errorf("undefined option '%s=%s'", key, val)
|
|
}
|
|
return nil
|
|
})
|
|
if fErr != nil {
|
|
fmt.Printf("failed to parse flags: %s", fErr)
|
|
return
|
|
}
|
|
|
|
if dbFile == "" || srcFile == "" {
|
|
fmt.Printf("%s bench [command options]\n", os.Args[0])
|
|
fmt.Printf("options:\n")
|
|
fmt.Printf(" --db string ip2region binary xdb file path\n")
|
|
fmt.Printf(" --src string source ip text file path\n")
|
|
fmt.Printf(" --version string IP version, options: ipv4/ipv6, specify this flag so you don't get confused \n")
|
|
fmt.Printf(" --log-level string set the log level, options: debug/info/warn/error\n")
|
|
fmt.Printf(" --ignore-error bool keep going if bench failed\n")
|
|
return
|
|
}
|
|
|
|
// check and define the IP version
|
|
var version *xdb.Version = nil
|
|
if len(ipVersion) < 2 {
|
|
slog.Error("please specify the ip version with flag --version, ipv4 or ipv6 ?")
|
|
return
|
|
} else if v, err := xdb.VersionFromName(ipVersion); err != nil {
|
|
slog.Error("failed to parse version name", "error", err)
|
|
return
|
|
} else {
|
|
version = v
|
|
}
|
|
|
|
// check and apply the log level
|
|
err = applyLogLevel(logLevel)
|
|
if err != nil {
|
|
slog.Error("failed to apply log level", "error", err)
|
|
return
|
|
}
|
|
|
|
searcher, err := xdb.NewSearcher(version, dbFile)
|
|
if err != nil {
|
|
fmt.Printf("failed to create searcher with `%s`: %s\n", dbFile, err)
|
|
return
|
|
}
|
|
defer func() {
|
|
searcher.Close()
|
|
}()
|
|
|
|
handle, err := os.OpenFile(srcFile, os.O_RDONLY, 0600)
|
|
if err != nil {
|
|
fmt.Printf("failed to open source text file: %s\n", err)
|
|
return
|
|
}
|
|
|
|
defer handle.Close()
|
|
|
|
var count, errCount, tStart = 0, 0, time.Now()
|
|
slog.Info("Bench start", "xdbPath", dbFile, "srcPath", srcFile)
|
|
var iErr = xdb.IterateSegments(handle, nil, nil, func(seg *xdb.Segment) error {
|
|
var l = fmt.Sprintf("%d|%d|%s", seg.StartIP, seg.EndIP, seg.Region)
|
|
slog.Debug("try to bench", "segment", l)
|
|
// mip := xdb.IPMiddle(seg.StartIP, seg.EndIP)
|
|
// for _, ip := range [][]byte{seg.StartIP, xdb.IPMiddle(seg.EndIP, mip), mip, xdb.IPMiddle(mip, seg.EndIP), seg.EndIP} {
|
|
for _, ip := range [][]byte{seg.StartIP, seg.EndIP} {
|
|
slog.Debug("|-try to bench", "ip", xdb.IP2String(ip))
|
|
r, _, err := searcher.Search(ip)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to search ip '%s': %s", xdb.IP2Long(ip), err)
|
|
}
|
|
|
|
// check the region info
|
|
count++
|
|
if r != seg.Region {
|
|
errCount++
|
|
slog.Error(" --[Failed] region not match", "src", r, "dst", seg.Region)
|
|
if !ignoreError {
|
|
return fmt.Errorf("")
|
|
}
|
|
} else {
|
|
slog.Debug(" --[Ok]")
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
if iErr != nil {
|
|
fmt.Printf("%s", err)
|
|
return
|
|
}
|
|
|
|
slog.Info("Bench finished", "count", count, "failed", errCount, "elapsed", time.Since(tStart))
|
|
}
|