mirror of
https://github.com/valyala/bytebufferpool.git
synced 2026-06-14 13:26:35 +03:00
Renaming: Acquire->Get, Release->Put for the sake of the consistency with standard package
This commit is contained in:
+9
-9
@@ -6,7 +6,7 @@ package bytebufferpool
|
||||
// ByteBuffer may be used with functions appending data to the given []byte
|
||||
// slice. See example code for details.
|
||||
//
|
||||
// Use Acquire for obtaining an empty byte buffer.
|
||||
// Use Get for obtaining an empty byte buffer.
|
||||
type ByteBuffer struct {
|
||||
|
||||
// B is a byte buffer to use in append-like workloads.
|
||||
@@ -41,21 +41,21 @@ func (b *ByteBuffer) Reset() {
|
||||
b.B = b.B[:0]
|
||||
}
|
||||
|
||||
// Acquire returns an empty byte buffer from the pool.
|
||||
// Get returns an empty byte buffer from the pool.
|
||||
//
|
||||
// Acquired byte buffer may be returned to the pool via Release call.
|
||||
// Getd byte buffer may be returned to the pool via Put call.
|
||||
// This reduces the number of memory allocations required for byte buffer
|
||||
// management.
|
||||
func Acquire() *ByteBuffer {
|
||||
return defaultByteBufferPool.Acquire()
|
||||
func Get() *ByteBuffer {
|
||||
return defaultPool.Get()
|
||||
}
|
||||
|
||||
// Release returns byte buffer to the pool.
|
||||
// Put returns byte buffer to the pool.
|
||||
//
|
||||
// ByteBuffer.B mustn't be touched after returning it to the pool.
|
||||
// Otherwise data races will occur.
|
||||
func Release(b *ByteBuffer) {
|
||||
defaultByteBufferPool.Release(b)
|
||||
func Put(b *ByteBuffer) {
|
||||
defaultPool.Put(b)
|
||||
}
|
||||
|
||||
var defaultByteBufferPool byteBufferPool
|
||||
var defaultPool Pool
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func ExampleByteBuffer() {
|
||||
bb := bytebufferpool.Acquire()
|
||||
bb := bytebufferpool.Get()
|
||||
|
||||
bb.WriteString("first line\n")
|
||||
bb.Write([]byte("second line\n"))
|
||||
@@ -17,5 +17,5 @@ func ExampleByteBuffer() {
|
||||
|
||||
// It is safe to release byte buffer now, since it is
|
||||
// no longer used.
|
||||
bytebufferpool.Release(bb)
|
||||
bytebufferpool.Put(bb)
|
||||
}
|
||||
|
||||
+7
-7
@@ -6,16 +6,16 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestByteBufferAcquireReleaseSerial(t *testing.T) {
|
||||
testByteBufferAcquireRelease(t)
|
||||
func TestByteBufferGetPutSerial(t *testing.T) {
|
||||
testByteBufferGetPut(t)
|
||||
}
|
||||
|
||||
func TestByteBufferAcquireReleaseConcurrent(t *testing.T) {
|
||||
func TestByteBufferGetPutConcurrent(t *testing.T) {
|
||||
concurrency := 10
|
||||
ch := make(chan struct{}, concurrency)
|
||||
for i := 0; i < concurrency; i++ {
|
||||
go func() {
|
||||
testByteBufferAcquireRelease(t)
|
||||
testByteBufferGetPut(t)
|
||||
ch <- struct{}{}
|
||||
}()
|
||||
}
|
||||
@@ -29,15 +29,15 @@ func TestByteBufferAcquireReleaseConcurrent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testByteBufferAcquireRelease(t *testing.T) {
|
||||
func testByteBufferGetPut(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
expectedS := fmt.Sprintf("num %d", i)
|
||||
b := Acquire()
|
||||
b := Get()
|
||||
b.B = append(b.B, "num "...)
|
||||
b.B = append(b.B, fmt.Sprintf("%d", i)...)
|
||||
if string(b.B) != expectedS {
|
||||
t.Fatalf("unexpected result: %q. Expecting %q", b.B, expectedS)
|
||||
}
|
||||
Release(b)
|
||||
Put(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,12 @@ const (
|
||||
maxPercentile = 0.95
|
||||
)
|
||||
|
||||
type byteBufferPool struct {
|
||||
// Pool represents byte buffer pool.
|
||||
//
|
||||
// Distinct pools may be used for distinct types of byte buffers.
|
||||
// Properly determined byte buffer types with their own pools may help reducing
|
||||
// memory waste.
|
||||
type Pool struct {
|
||||
calls [steps]uint64
|
||||
calibrating uint64
|
||||
|
||||
@@ -27,7 +32,11 @@ type byteBufferPool struct {
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
func (p *byteBufferPool) Acquire() *ByteBuffer {
|
||||
// Get returns new byte buffer with zero length.
|
||||
//
|
||||
// The byte buffer may be returned to the pool via Put after the use
|
||||
// in order to minimize GC overhead.
|
||||
func (p *Pool) Get() *ByteBuffer {
|
||||
v := p.pool.Get()
|
||||
if v != nil {
|
||||
return v.(*ByteBuffer)
|
||||
@@ -37,7 +46,10 @@ func (p *byteBufferPool) Acquire() *ByteBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *byteBufferPool) Release(b *ByteBuffer) {
|
||||
// Put releases byte buffer obtained via Get to the pool.
|
||||
//
|
||||
// The bufer mustn't be accessed after returning to the pool.
|
||||
func (p *Pool) Put(b *ByteBuffer) {
|
||||
idx := index(len(b.B))
|
||||
|
||||
if atomic.AddUint64(&p.calls[idx], 1) > calibrateCallsThreshold {
|
||||
@@ -51,7 +63,7 @@ func (p *byteBufferPool) Release(b *ByteBuffer) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *byteBufferPool) calibrate() {
|
||||
func (p *Pool) calibrate() {
|
||||
if !atomic.CompareAndSwapUint64(&p.calibrating, 0, 1) {
|
||||
return
|
||||
}
|
||||
|
||||
+8
-8
@@ -36,7 +36,7 @@ func TestPoolCalibrate(t *testing.T) {
|
||||
if i%15 == 0 {
|
||||
n = rand.Intn(15234)
|
||||
}
|
||||
testAcquireRelease(t, n)
|
||||
testGetPut(t, n)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,23 +66,23 @@ func testPoolVariousSizes(t *testing.T) {
|
||||
for i := 0; i < steps+1; i++ {
|
||||
n := (1 << uint32(i))
|
||||
|
||||
testAcquireRelease(t, n)
|
||||
testAcquireRelease(t, n+1)
|
||||
testAcquireRelease(t, n-1)
|
||||
testGetPut(t, n)
|
||||
testGetPut(t, n+1)
|
||||
testGetPut(t, n-1)
|
||||
|
||||
for j := 0; j < 10; j++ {
|
||||
testAcquireRelease(t, j+n)
|
||||
testGetPut(t, j+n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testAcquireRelease(t *testing.T, n int) {
|
||||
bb := Acquire()
|
||||
func testGetPut(t *testing.T, n int) {
|
||||
bb := Get()
|
||||
if len(bb.B) > 0 {
|
||||
t.Fatalf("non-empty byte buffer returned from acquire")
|
||||
}
|
||||
bb.B = allocNBytes(bb.B, n)
|
||||
Release(bb)
|
||||
Put(bb)
|
||||
}
|
||||
|
||||
func allocNBytes(dst []byte, n int) []byte {
|
||||
|
||||
Reference in New Issue
Block a user