Skip to content

Commit 5825bea

Browse files
j67678renzhn
authored and
renzhn
committedNov 22, 2015
Performance improvement for cn ip search.
The mask len for cn route bigger than 8, we can use the first byte as the key.
1 parent b732527 commit 5825bea

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed
 

‎cnipdata.go

+21
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ package main
33
var CNIPDataStart []uint32
44
var CNIPDataNum []uint
55

6+
//data range by first byte
7+
var CNIPDataRange [256]struct {
8+
start int
9+
end int
10+
}
11+
612
func initCNIPData() {
713
CNIPDataStart = []uint32{
814
16777472,
@@ -9738,4 +9744,19 @@ func initCNIPData() {
97389744
512,
97399745
}
97409746

9747+
n := len(CNIPDataStart)
9748+
var curr uint32 = 0
9749+
var preFirstByte uint32 = 0
9750+
for i := 0; i < n; i++ {
9751+
firstByte := CNIPDataStart[i] >> 24
9752+
if curr != firstByte {
9753+
curr = firstByte
9754+
if preFirstByte != 0 {
9755+
CNIPDataRange[preFirstByte].end = i - 1
9756+
}
9757+
CNIPDataRange[firstByte].start = i
9758+
preFirstByte = firstByte
9759+
}
9760+
}
9761+
CNIPDataRange[preFirstByte].end = n - 1
97419762
}

‎directip.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package main
22

3-
import (
4-
"sort"
5-
)
6-
73
func ipShouldDirect(ip string) (direct bool) {
84
direct = false
95
defer func() {
@@ -22,7 +18,11 @@ func ipShouldDirect(ip string) (direct bool) {
2218
if ipLong == 0 {
2319
return true
2420
}
25-
ipIndex := sort.Search(len(CNIPDataStart), func(i int) bool {
21+
firstByte := ipLong >> 24
22+
if CNIPDataRange[firstByte].end == 0 {
23+
return false
24+
}
25+
ipIndex := searchRange(CNIPDataRange[firstByte].start, CNIPDataRange[firstByte].end, func(i int) bool {
2626
return CNIPDataStart[i] > ipLong
2727
})
2828
ipIndex--

‎util.go

+15
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,18 @@ func ip2long(ipstr string) (uint32, error) {
416416
}
417417
return binary.BigEndian.Uint32(ip), nil
418418
}
419+
420+
// search between [start, end]
421+
func searchRange(start, end int, f func(int) bool) int {
422+
i, j := start, end+1
423+
for i < j {
424+
h := i + (j-i)/2 // avoid overflow when computing h
425+
// i ≤ h < j
426+
if !f(h) {
427+
i = h + 1 // preserves f(i-1) == false
428+
} else {
429+
j = h // preserves f(j) == true
430+
}
431+
}
432+
return i
433+
}

0 commit comments

Comments
 (0)
Please sign in to comment.