|
|
// Copyright 2019, Chef. All rights reserved.
|
|
|
// https://github.com/q191201771/naza
|
|
|
//
|
|
|
// Use of this source code is governed by a MIT-style license
|
|
|
// that can be found in the License file.
|
|
|
//
|
|
|
// Author: Chef (191201771@qq.com)
|
|
|
|
|
|
package slicebytepool
|
|
|
|
|
|
import "github.com/q191201771/naza/pkg/nazaatomic"
|
|
|
|
|
|
var (
|
|
|
minSize = 1024
|
|
|
maxSize = 1073741824
|
|
|
)
|
|
|
|
|
|
type sliceBytePool struct {
|
|
|
strategy Strategy
|
|
|
capToFreeBucket map[int]Bucket
|
|
|
status statusAtomic
|
|
|
}
|
|
|
|
|
|
type statusAtomic struct {
|
|
|
getCount nazaatomic.Int64
|
|
|
putCount nazaatomic.Int64
|
|
|
hitCount nazaatomic.Int64
|
|
|
sizeBytes nazaatomic.Int64
|
|
|
}
|
|
|
|
|
|
func (bp *sliceBytePool) Get(size int) []byte {
|
|
|
bp.status.getCount.Increment()
|
|
|
|
|
|
ss := up2power(size)
|
|
|
if ss < minSize {
|
|
|
ss = minSize
|
|
|
}
|
|
|
bucket := bp.capToFreeBucket[ss]
|
|
|
|
|
|
buf := bucket.Get(size)
|
|
|
if buf == nil {
|
|
|
buf = make([]byte, size, ss)
|
|
|
return buf
|
|
|
}
|
|
|
|
|
|
bp.status.hitCount.Increment()
|
|
|
bp.status.sizeBytes.Sub(int64(cap(buf)))
|
|
|
return buf
|
|
|
}
|
|
|
|
|
|
func (bp *sliceBytePool) Put(buf []byte) {
|
|
|
c := cap(buf)
|
|
|
bp.status.putCount.Increment()
|
|
|
bp.status.sizeBytes.Add(int64(c))
|
|
|
|
|
|
size := down2power(c)
|
|
|
if size < minSize {
|
|
|
size = minSize
|
|
|
}
|
|
|
|
|
|
bucket := bp.capToFreeBucket[size]
|
|
|
|
|
|
bucket.Put(buf)
|
|
|
}
|
|
|
|
|
|
func (bp *sliceBytePool) RetrieveStatus() Status {
|
|
|
return Status{
|
|
|
getCount: bp.status.getCount.Load(),
|
|
|
putCount: bp.status.putCount.Load(),
|
|
|
hitCount: bp.status.hitCount.Load(),
|
|
|
sizeBytes: bp.status.sizeBytes.Load(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// @return 范围为 [2, 4, 8, 16, ..., 1073741824],如果大于等于1073741824,则直接返回n
|
|
|
func up2power(n int) int {
|
|
|
if n >= maxSize {
|
|
|
return n
|
|
|
}
|
|
|
|
|
|
var i uint32
|
|
|
for ; n > (2 << i); i++ {
|
|
|
}
|
|
|
return 2 << i
|
|
|
}
|
|
|
|
|
|
// @return 范围为 [2, 4, 8, 16, ..., 1073741824]
|
|
|
func down2power(n int) int {
|
|
|
if n < 2 {
|
|
|
return 2
|
|
|
} else if n >= maxSize {
|
|
|
return maxSize
|
|
|
}
|
|
|
|
|
|
var i uint32
|
|
|
for {
|
|
|
nn := 2 << i
|
|
|
if n > nn {
|
|
|
i++
|
|
|
} else if n == nn {
|
|
|
return n
|
|
|
} else if n < nn {
|
|
|
return 2 << (i - 1)
|
|
|
}
|
|
|
}
|
|
|
}
|