mirror of
https://github.com/valyala/bytebufferpool.git
synced 2026-06-14 13:26:35 +03:00
Return back pools segementation by size
This commit is contained in:
@@ -18,28 +18,36 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type byteBufferPool struct {
|
type byteBufferPool struct {
|
||||||
calls [steps]uint64
|
|
||||||
calibrating uint64
|
calibrating uint64
|
||||||
|
|
||||||
defaultSize uint64
|
defaultSize uint64
|
||||||
maxSize uint64
|
maxSize uint64
|
||||||
|
|
||||||
pool sync.Pool
|
calls [steps]uint64
|
||||||
|
idxs [steps]uint64
|
||||||
|
pools [steps]sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *byteBufferPool) Acquire() *ByteBuffer {
|
func (p *byteBufferPool) Acquire() *ByteBuffer {
|
||||||
v := p.pool.Get()
|
for i := 0; i < steps; i++ {
|
||||||
if v != nil {
|
idx := atomic.LoadUint64(&p.idxs[i])
|
||||||
return v.(*ByteBuffer)
|
if idx >= steps {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v := p.pools[idx].Get()
|
||||||
|
if v != nil {
|
||||||
|
return v.(*ByteBuffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ByteBuffer{
|
return &ByteBuffer{
|
||||||
B: make([]byte, 0, atomic.LoadUint64(&p.defaultSize)),
|
B: make([]byte, 0, atomic.LoadUint64(&p.defaultSize)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *byteBufferPool) Release(b *ByteBuffer) {
|
func (p *byteBufferPool) Release(b *ByteBuffer) {
|
||||||
bSize := len(b.B)
|
bLen := uint64(len(b.B))
|
||||||
idx := bitSize(bSize-1) - minBitSize
|
idx := index(bLen)
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
idx = 0
|
idx = 0
|
||||||
} else if idx >= steps {
|
} else if idx >= steps {
|
||||||
@@ -50,10 +58,12 @@ func (p *byteBufferPool) Release(b *ByteBuffer) {
|
|||||||
p.calibrate()
|
p.calibrate()
|
||||||
}
|
}
|
||||||
|
|
||||||
maxSize := int(atomic.LoadUint64(&p.maxSize))
|
maxSize := atomic.LoadUint64(&p.maxSize)
|
||||||
if maxSize > 0 && bSize <= maxSize {
|
bCap := uint64(cap(b.B))
|
||||||
|
if maxSize > 0 && bCap <= maxSize {
|
||||||
|
idx = index(bCap)
|
||||||
b.B = b.B[:0]
|
b.B = b.B[:0]
|
||||||
p.pool.Put(b)
|
p.pools[idx].Put(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,14 +90,16 @@ func (p *byteBufferPool) calibrate() {
|
|||||||
maxSum := uint64(float64(callsSum) * maxPercentile)
|
maxSum := uint64(float64(callsSum) * maxPercentile)
|
||||||
callsSum = 0
|
callsSum = 0
|
||||||
for i := 0; i < steps; i++ {
|
for i := 0; i < steps; i++ {
|
||||||
if callsSum > maxSum {
|
idx := uint64(steps)
|
||||||
break
|
if callsSum <= maxSum {
|
||||||
}
|
callsSum += a[i].calls
|
||||||
callsSum += a[i].calls
|
size := a[i].size
|
||||||
size := a[i].size
|
if size > maxSize {
|
||||||
if size > maxSize {
|
maxSize = size
|
||||||
maxSize = size
|
}
|
||||||
|
idx = index(size)
|
||||||
}
|
}
|
||||||
|
atomic.StoreUint64(&p.idxs[i], idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic.StoreUint64(&p.defaultSize, defaultSize)
|
atomic.StoreUint64(&p.defaultSize, defaultSize)
|
||||||
@@ -115,8 +127,12 @@ func (ci callSizes) Swap(i, j int) {
|
|||||||
ci[i], ci[j] = ci[j], ci[i]
|
ci[i], ci[j] = ci[j], ci[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func bitSize(n int) int {
|
func index(n uint64) uint64 {
|
||||||
s := 0
|
return bitSize(n-1) - minBitSize
|
||||||
|
}
|
||||||
|
|
||||||
|
func bitSize(n uint64) uint64 {
|
||||||
|
s := uint64(0)
|
||||||
for n > 0 {
|
for n > 0 {
|
||||||
n >>= 1
|
n >>= 1
|
||||||
s++
|
s++
|
||||||
|
|||||||
Reference in New Issue
Block a user