glob/match/segments.go

92 lines
1.4 KiB
Go
Raw Normal View History

2016-02-22 23:47:31 +03:00
package match
import (
"sync"
)
var segmentsPools [1024]*sync.Pool
2016-02-22 23:47:31 +03:00
func toPowerOfTwo(v int) int {
v--
v |= v >> 1
v |= v >> 2
v |= v >> 4
v |= v >> 8
v |= v >> 16
v++
return v
}
const (
cacheFrom = 16
cacheToAndHigher = 1024
cacheFromIndex = 15
cacheToAndHigherIndex = 1023
2016-02-22 23:47:31 +03:00
)
2016-02-23 14:46:20 +03:00
var (
segments0 = []int{0}
segments1 = []int{1}
segments2 = []int{2}
segments3 = []int{3}
segments4 = []int{4}
)
2016-02-24 11:19:54 +03:00
var segmentsByRuneLength [5][]int = [5][]int{
0: segments0,
1: segments1,
2: segments2,
3: segments3,
4: segments4,
}
2016-02-23 14:46:20 +03:00
const (
asciiLo = 0
asciiHi = 127
)
2016-02-22 23:47:31 +03:00
func init() {
for i := cacheToAndHigher; i >= cacheFrom; i >>= 1 {
2016-02-22 23:47:31 +03:00
func(i int) {
segmentsPools[i-1] = &sync.Pool{New: func() interface{} {
2016-02-22 23:47:31 +03:00
return make([]int, 0, i)
}}
2016-02-22 23:47:31 +03:00
}(i)
}
}
func getTableIndex(c int) int {
2016-02-22 23:47:31 +03:00
p := toPowerOfTwo(c)
switch {
case p >= cacheToAndHigher:
return cacheToAndHigherIndex
case p <= cacheFrom:
return cacheFromIndex
2016-02-22 23:47:31 +03:00
default:
return p - 1
}
}
func acquireSegments(c int) []int {
// make []int with less capacity than cacheFrom
// is faster than acquiring it from pool
if c < cacheFrom {
return make([]int, 0, c)
2016-02-22 23:47:31 +03:00
}
return segmentsPools[getTableIndex(c)].Get().([]int)[:0]
2016-02-22 23:47:31 +03:00
}
func releaseSegments(s []int) {
c := cap(s)
2016-02-22 23:47:31 +03:00
// make []int with less capacity than cacheFrom
// is faster than acquiring it from pool
if c < cacheFrom {
2016-02-22 23:47:31 +03:00
return
}
segmentsPools[getTableIndex(cap(s))].Put(s)
2016-02-22 23:47:31 +03:00
}