diff --git a/ipquery.go b/ipquery.go index c91faa7..39bf989 100644 --- a/ipquery.go +++ b/ipquery.go @@ -92,10 +92,37 @@ func (this *QueryServer) FindIp(ipstr string) (string, bool) { iplong := ip2long(ip) itemsCount := len(this.items) - for i := 0; i < itemsCount; i++ { - item := &this.items[i] - if iplong < item.Ip { - return item.Country, true + + low := 0 + high := itemsCount - 1 + + if iplong == this.items[low].Ip { + return this.items[low].Country, true + } + + if iplong == this.items[high].Ip { + return this.items[high].Country, true + } + + for low <= high { + mid := low + ((high - low) / 2) + + //log.Printf("[FindIp2]low:%d,high:%d,mid:%d,midip:%d,findip:%d", low, high, mid, this.items[mid].Ip, iplong) + + if this.items[mid].Ip >= iplong { + if mid >= 1 { + if this.items[mid-1].Ip <= iplong { + return this.items[mid].Country, true + } + } else { + return this.items[mid].Country, true + } + } + + if this.items[mid].Ip > iplong { + high = mid - 1 + } else { + low = mid + 1 } } diff --git a/ipquery_test.go b/ipquery_test.go index 3840d63..8c464f4 100644 --- a/ipquery_test.go +++ b/ipquery_test.go @@ -7,28 +7,38 @@ import ( "time" ) -func TestParseData(t *testing.T) { +const DATA_FILE = "./data/17monipdb.dat" + +func TestLoad(t *testing.T) { s := new(QueryServer) - err := s.Load("./data/17monipdb.dat") + var err error + err = s.Load(DATA_FILE) if nil != err { t.Errorf("Load Error:%s", err.Error()) } - s.ParseData() + err = s.Load("NOT_EXIST_FILE") + if nil == err { + t.Errorf("Load Error should be error because of not exist file") + } } func TestFindIp(t *testing.T) { s := new(QueryServer) - err := s.Load("./data/17monipdb.dat") + err := s.Load(DATA_FILE) if nil != err { t.Errorf("Load Error:%s", err.Error()) } - ipstr := getRandomIpStr() - address, ok := s.FindIp(ipstr) + var ipstr string + var address string + var ok bool + + ipstr = getRandomIpStr() + address, ok = s.FindIp(ipstr) if !ok { t.Errorf("FindIp Failed") } @@ -41,6 +51,13 @@ func TestFindIp(t *testing.T) { } t.Logf("ipstr:%s,address:%s", ipstr, address) + ipstr = "0.0.0.1" + address, ok = s.FindIp(ipstr) + if !ok { + t.Errorf("FindIp Failed") + } + t.Logf("ipstr:%s,address:%s", ipstr, address) + ipstr = "202.194.34.229" address, ok = s.FindIp(ipstr) if !ok { @@ -54,7 +71,7 @@ func BenchmarkLoad(b *testing.B) { s := new(QueryServer) for i := 0; i < b.N; i++ { - err := s.Load("./data/17monipdb.dat") + err := s.Load(DATA_FILE) if nil != err { b.Errorf("Load Error:%s", err.Error()) } @@ -63,46 +80,41 @@ func BenchmarkLoad(b *testing.B) { func BenchmarkFindIp(b *testing.B) { s := new(QueryServer) - err := s.Load("./data/17monipdb.dat") + err := s.Load(DATA_FILE) if nil != err { b.Errorf("Load Error:%s", err.Error()) } - rndInit() ipstr := getRandomIpStr() for i := 0; i < b.N; i++ { - address, ok := s.FindIp(ipstr) + _, ok := s.FindIp(ipstr) if !ok { - b.Errorf("FindIp Failed") + b.Errorf(DATA_FILE) } - b.Logf("ipstr:%s,address:%s", ipstr, address) } } func BenchmarkFindIpRandom(b *testing.B) { s := new(QueryServer) - err := s.Load("./data/17monipdb.dat") + err := s.Load(DATA_FILE) if nil != err { b.Errorf("Load Error:%s", err.Error()) } - rndInit() for i := 0; i < b.N; i++ { ipstr := getRandomIpStr() - address, ok := s.FindIp(ipstr) + _, ok := s.FindIp(ipstr) if !ok { b.Errorf("FindIp Failed") } - b.Logf("ipstr:%s,address:%s", ipstr, address) } } func getRandomIpStr() string { return fmt.Sprintf("%d.%d.%d.%d", rnd(0, 254), rnd(0, 254), rnd(0, 254), rnd(0, 254)) } -func rndInit() { - rand.Seed(time.Now().UnixNano()) -} + func rnd(from, to int) int { + rand.Seed(time.Now().UnixNano()) return rand.Intn(to+1-from) + from }