mirror of
				https://github.com/TeaOSLab/EdgeCommon.git
				synced 2025-11-04 13:10:24 +08:00 
			
		
		
		
	优化IP库内存
This commit is contained in:
		@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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]),
 | 
			
		||||
					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]),
 | 
			
		||||
					Region: region,
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user