优化IP库内存

This commit is contained in:
GoEdgeLab
2022-08-22 08:31:53 +08:00
parent 2dbc6e53d5
commit 6abdf13e2e
5 changed files with 86 additions and 43 deletions

View File

@@ -12,6 +12,15 @@ import (
"time"
)
func TestIPLibrary_Init(t *testing.T) {
var lib = iplibrary.NewIPLibrary()
err := lib.Init()
if err != nil {
t.Fatal(err)
}
}
func TestIPLibrary_Lookup(t *testing.T) {
var stat1 = &runtime.MemStats{}
runtime.ReadMemStats(stat1)

View File

@@ -5,16 +5,22 @@ package iplibrary
import (
"bytes"
"encoding/binary"
"github.com/iwind/TeaGo/types"
)
type ipItem struct {
IPFrom uint64
IPTo uint64
Region *ipRegion
}
type ipRegion struct {
CountryId uint32
ProvinceId uint32
CityId uint32
TownId uint32
ProviderId uint32
IPFrom uint64
IPTo uint64
}
func (this *ipItem) AsBinary() ([]byte, error) {
@@ -25,3 +31,21 @@ func (this *ipItem) AsBinary() ([]byte, error) {
}
return buf.Bytes(), nil
}
func HashRegion(countryId uint32, provinceId uint32, cityId uint32, townId uint32, providerId uint32) string {
var providerHash = ""
if providerId > 0 {
providerHash = "_" + types.String(providerId)
}
if townId > 0 {
return "t" + types.String(townId) + providerHash
}
if cityId > 0 {
return "c" + types.String(cityId) + providerHash
}
if provinceId > 0 {
return "p" + types.String(provinceId) + providerHash
}
return "a" + types.String(countryId) + providerHash
}

View File

@@ -12,11 +12,6 @@ func TestIpItem_AsBinary(t *testing.T) {
var item = &ipItem{
IPFrom: 123456789,
IPTo: 123456790,
CountryId: 1,
ProvinceId: 2,
CityId: 3,
TownId: 4,
ProviderId: 5,
}
b, err := item.AsBinary()
if err != nil {

View File

@@ -17,12 +17,16 @@ import (
type Reader struct {
meta *Meta
regionMap map[string]*ipRegion
ipV4Items []*ipItem
ipV6Items []*ipItem
}
func NewReader(reader io.Reader) (*Reader, error) {
var libReader = &Reader{}
var libReader = &Reader{
regionMap: map[string]*ipRegion{},
}
err := libReader.load(reader)
if err != nil {
return nil, err
@@ -186,25 +190,36 @@ func (this *Reader) parse(data []byte) (left []byte, err error) {
ipTo = types.Uint64(pieces[2]) + ipFrom
}
var countryId = types.Uint32(pieces[3])
var provinceId = types.Uint32(pieces[4])
var cityId = types.Uint32(pieces[5])
var townId = types.Uint32(pieces[6])
var providerId = types.Uint32(pieces[7])
var hash = HashRegion(countryId, provinceId, cityId, townId, providerId)
region, ok := this.regionMap[hash]
if !ok {
region = &ipRegion{
CountryId: countryId,
ProvinceId: provinceId,
CityId: cityId,
TownId: townId,
ProviderId: providerId,
}
this.regionMap[hash] = region
}
if version == "4" {
this.ipV4Items = append(this.ipV4Items, &ipItem{
IPFrom: ipFrom,
IPTo: ipTo,
CountryId: types.Uint32(pieces[3]),
ProvinceId: types.Uint32(pieces[4]),
CityId: types.Uint32(pieces[5]),
TownId: types.Uint32(pieces[6]),
ProviderId: types.Uint32(pieces[7]),
IPFrom: ipFrom,
IPTo: ipTo,
Region: region,
})
} else {
this.ipV6Items = append(this.ipV6Items, &ipItem{
IPFrom: ipFrom,
IPTo: ipTo,
CountryId: types.Uint32(pieces[3]),
ProvinceId: types.Uint32(pieces[4]),
CityId: types.Uint32(pieces[5]),
TownId: types.Uint32(pieces[6]),
ProviderId: types.Uint32(pieces[7]),
IPFrom: ipFrom,
IPTo: ipTo,
Region: region,
})
}

View File

@@ -18,7 +18,7 @@ func (this *QueryResult) IsOk() bool {
func (this *QueryResult) CountryId() int64 {
if this.item != nil {
return int64(this.item.CountryId)
return int64(this.item.Region.CountryId)
}
return 0
}
@@ -27,8 +27,8 @@ func (this *QueryResult) CountryName() string {
if this.item == nil {
return ""
}
if this.item.CountryId > 0 {
var country = this.meta.CountryWithId(this.item.CountryId)
if this.item.Region.CountryId > 0 {
var country = this.meta.CountryWithId(this.item.Region.CountryId)
if country != nil {
return country.Name
}
@@ -40,8 +40,8 @@ func (this *QueryResult) CountryCodes() []string {
if this.item == nil {
return nil
}
if this.item.CountryId > 0 {
var country = this.meta.CountryWithId(this.item.CountryId)
if this.item.Region.CountryId > 0 {
var country = this.meta.CountryWithId(this.item.Region.CountryId)
if country != nil {
return country.Codes
}
@@ -51,7 +51,7 @@ func (this *QueryResult) CountryCodes() []string {
func (this *QueryResult) ProvinceId() int64 {
if this.item != nil {
return int64(this.item.ProvinceId)
return int64(this.item.Region.ProvinceId)
}
return 0
}
@@ -60,8 +60,8 @@ func (this *QueryResult) ProvinceName() string {
if this.item == nil {
return ""
}
if this.item.ProvinceId > 0 {
var province = this.meta.ProvinceWithId(this.item.ProvinceId)
if this.item.Region.ProvinceId > 0 {
var province = this.meta.ProvinceWithId(this.item.Region.ProvinceId)
if province != nil {
return province.Name
}
@@ -73,8 +73,8 @@ func (this *QueryResult) ProvinceCodes() []string {
if this.item == nil {
return nil
}
if this.item.ProvinceId > 0 {
var province = this.meta.ProvinceWithId(this.item.ProvinceId)
if this.item.Region.ProvinceId > 0 {
var province = this.meta.ProvinceWithId(this.item.Region.ProvinceId)
if province != nil {
return province.Codes
}
@@ -84,7 +84,7 @@ func (this *QueryResult) ProvinceCodes() []string {
func (this *QueryResult) CityId() int64 {
if this.item != nil {
return int64(this.item.CityId)
return int64(this.item.Region.CityId)
}
return 0
}
@@ -93,8 +93,8 @@ func (this *QueryResult) CityName() string {
if this.item == nil {
return ""
}
if this.item.CityId > 0 {
var city = this.meta.CityWithId(this.item.CityId)
if this.item.Region.CityId > 0 {
var city = this.meta.CityWithId(this.item.Region.CityId)
if city != nil {
return city.Name
}
@@ -104,7 +104,7 @@ func (this *QueryResult) CityName() string {
func (this *QueryResult) TownId() int64 {
if this.item != nil {
return int64(this.item.TownId)
return int64(this.item.Region.TownId)
}
return 0
}
@@ -113,8 +113,8 @@ func (this *QueryResult) TownName() string {
if this.item == nil {
return ""
}
if this.item.TownId > 0 {
var town = this.meta.TownWithId(this.item.TownId)
if this.item.Region.TownId > 0 {
var town = this.meta.TownWithId(this.item.Region.TownId)
if town != nil {
return town.Name
}
@@ -124,7 +124,7 @@ func (this *QueryResult) TownName() string {
func (this *QueryResult) ProviderId() int64 {
if this.item != nil {
return int64(this.item.ProviderId)
return int64(this.item.Region.ProviderId)
}
return 0
}
@@ -133,8 +133,8 @@ func (this *QueryResult) ProviderName() string {
if this.item == nil {
return ""
}
if this.item.ProviderId > 0 {
var provider = this.meta.ProviderWithId(this.item.ProviderId)
if this.item.Region.ProviderId > 0 {
var provider = this.meta.ProviderWithId(this.item.Region.ProviderId)
if provider != nil {
return provider.Name
}
@@ -146,8 +146,8 @@ func (this *QueryResult) ProviderCodes() []string {
if this.item == nil {
return nil
}
if this.item.ProviderId > 0 {
var provider = this.meta.ProviderWithId(this.item.ProviderId)
if this.item.Region.ProviderId > 0 {
var provider = this.meta.ProviderWithId(this.item.Region.ProviderId)
if provider != nil {
return provider.Codes
}