restic/internal/archiver/buffer.go

48 lines
1.1 KiB
Go
Raw Normal View History

2018-03-30 22:43:18 +02:00
package archiver
import "sync"
2024-08-27 11:26:52 +02:00
// buffer is a reusable buffer. After the buffer has been used, Release should
2018-03-30 22:43:18 +02:00
// be called so the underlying slice is put back into the pool.
2024-08-27 11:26:52 +02:00
type buffer struct {
2018-03-30 22:43:18 +02:00
Data []byte
2024-08-27 11:26:52 +02:00
pool *bufferPool
2018-03-30 22:43:18 +02:00
}
// Release puts the buffer back into the pool it came from.
2024-08-27 11:26:52 +02:00
func (b *buffer) Release() {
pool := b.pool
if pool == nil || cap(b.Data) > pool.defaultSize {
return
}
pool.pool.Put(b)
2018-03-30 22:43:18 +02:00
}
2024-08-27 11:26:52 +02:00
// bufferPool implements a limited set of reusable buffers.
type bufferPool struct {
pool sync.Pool
2018-03-30 22:43:18 +02:00
defaultSize int
}
2024-08-27 11:26:52 +02:00
// newBufferPool initializes a new buffer pool. The pool stores at most max
// items. New buffers are created with defaultSize. Buffers that have grown
// larger are not put back.
func newBufferPool(defaultSize int) *bufferPool {
2024-08-27 11:26:52 +02:00
b := &bufferPool{
2018-03-30 22:43:18 +02:00
defaultSize: defaultSize,
}
b.pool = sync.Pool{New: func() any {
return &buffer{
Data: make([]byte, defaultSize),
pool: b,
}
}}
2018-03-30 22:43:18 +02:00
return b
}
// Get returns a new buffer, either from the pool or newly allocated.
2024-08-27 11:26:52 +02:00
func (pool *bufferPool) Get() *buffer {
return pool.pool.Get().(*buffer)
2018-03-30 22:43:18 +02:00
}