glob/match/segments.go

71 lines
1.1 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
)
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
}