bbp

package
v2.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 21, 2023 License: MIT Imports: 13 Imported by: 0

README

Package bbp provides efficient byte buffer pools with anti-memory-waste protection.

Byte buffers acquired from this package may be put back to the pool, but they do not need to; if they are returned, they will be recycled and reused, otherwise they will be garbage collected as usual.

The methods within this package and all Pool instances share the same underlying sized byte slice pools. The byte buffers provided by this package has a minimum limit of 64B and a maximum limit of 32MB, byte slice with size not in the range will be allocated directly from Go runtime, and won't be recycled for reuse.

Documentation

Overview

Package bbp provides efficient byte buffer pools with anti-memory-waste protection.

Byte buffers acquired from this package may be put back to the pool, but they do not need to; if they are returned, they will be recycled and reused, otherwise they will be garbage collected as usual.

The methods within this package and all `Pool` instances share the same underlying sized byte slice pools. The byte buffers provided by this package has a minimum limit of 64B and a maximum limit of 32MB, byte slice with size not in the range will be allocated directly from Go runtime, and won't be recycled for reuse.

Index

Constants

View Source
const MinRead = 512

MinRead is the minimum slice size passed to a Read call by Buffer.ReadFrom.

Variables

This section is empty.

Functions

func Get

func Get(length, capacity int) []byte

Get returns a byte slice from the pool with specified length and capacity. When you finish the work with the buffer, you may call Put to put it back to the pool for reusing.

func Grow

func Grow(buf []byte, n int, reuseBuf bool) []byte

Grow checks capacity of buf, it returns a new byte buffer from the pool, if necessary, to guarantee space for another n bytes. After Grow(n), at least n bytes can be appended to the returned buffer without another allocation. If n is negative, Grow will panic.

Note that if reuseBuf is true and a new slice is returned, the old buf will be put back to the pool, the caller must not retain reference to the old buf and must not access it again, else data race happens.

func Put

func Put(buf []byte)

Put puts back a byte slice to the pool for reusing.

The byte slice mustn't be touched after returning it to the pool, otherwise data races will occur.

func PutBuffer

func PutBuffer(buf *Buffer)

PutBuffer puts back a Buffer to the pool for reusing.

The buffer mustn't be touched after returning it to the pool, otherwise data races will occur.

Types

type Arena added in v2.6.1

type Arena struct {
	// contains filtered or unexported fields
}

Arena allocates memory in chunk mode, and serves requests to allocate small byte slices, after working with the memory chunks, user should call Free to release the allocated memory together. It's efficient for memory allocation-heavy workloads.

func NewArena added in v2.6.1

func NewArena(chunkSize int) *Arena

NewArena creates an Arena object, it allocates memory from the sized buffer pools. The method Free returns memory chunks to the pool for reusing, after which both the arena and the byte slices allocated from the arena **MUST NOT** be touched again. chunkSize will be round up to the next power of two that is greater than or equal to the system's PAGE_SIZE.

func (*Arena) Alloc added in v2.6.1

func (a *Arena) Alloc(length, capacity int) []byte

Alloc allocates small byte slice from the arena.

func (*Arena) Free added in v2.6.1

func (a *Arena) Free()

Free releases all memory chunks managed by the arena. It returns the memory chunks to pool for reusing.

type Buffer

type Buffer struct {
	// contains filtered or unexported fields
}

Buffer provides byte buffer, which can be used for minimizing memory allocations.

Buffer may be used with functions appending data to the underlying []byte slice. See example code for details.

Use NewBuffer for obtaining a buffer with specified capacity. The zero value for Buffer is an empty buffer ready to use.

func NewBuffer

func NewBuffer(capacity int) *Buffer

NewBuffer creates a new Buffer with specified capacity. When you finish the work with the buffer, you may call PutBuffer to put it back to the pool for reusing.

func (*Buffer) Append added in v2.5.0

func (b *Buffer) Append(f func([]byte) []byte)

Append accepts a function which append data to the underlying byte slice.

func (*Buffer) Bytes

func (b *Buffer) Bytes() []byte

Bytes returns the underlying byte slice, i.e. all the bytes accumulated in the buffer.

Note that this method doesn't copy the underlying byte slice, the caller should either copy the byte slice explicitly or don't return the Buffer back to the pool, otherwise data race will occur. You may use Buffer.Copy to get a copy of the underlying byte slice.

func (*Buffer) Clone added in v2.5.0

func (b *Buffer) Clone() *Buffer

Clone returns a new copy of the buffer, including the underlying byte slice.

func (*Buffer) Copy

func (b *Buffer) Copy() []byte

Copy returns a copy of the underlying byte slice.

func (*Buffer) Grow

func (b *Buffer) Grow(n int)

Grow grows the buffer's capacity, if necessary, to guarantee space for another n bytes. After Grow(n), at least n bytes can be written to the buffer without another allocation. If n is negative, Grow will panic.

func (*Buffer) Len

func (b *Buffer) Len() int

Len returns the size of the byte buffer.

func (*Buffer) ReadFrom

func (b *Buffer) ReadFrom(r io.Reader) (int64, error)

ReadFrom implements io.ReaderFrom.

The function appends all the data read from r to b.

func (*Buffer) Reset

func (b *Buffer) Reset()

Reset re-slice the underlying byte slice to empty.

func (*Buffer) Set

func (b *Buffer) Set(p []byte)

Set first re-slice the underlying byte slice to empty, then write p to the buffer.

func (*Buffer) SetString

func (b *Buffer) SetString(s string)

SetString first re-slice the underlying byte slice to empty, then write s to the buffer.

func (*Buffer) String

func (b *Buffer) String() string

String returns a string copy of the underlying byte slice.

func (*Buffer) StringUnsafe

func (b *Buffer) StringUnsafe() string

StringUnsafe is equivalent to String, but the string that it returns is _NOT_ copied, so modifying this buffer after calling StringUnsafe will lead to undefined behavior.

func (*Buffer) Write

func (b *Buffer) Write(p []byte) (int, error)

Write implements io.Writer - it appends p to the underlying byte buffer.

func (*Buffer) WriteByte

func (b *Buffer) WriteByte(c byte) error

WriteByte appends the byte c to the buffer. The purpose of this function is bytes.Buffer compatibility.

func (*Buffer) WriteRune

func (b *Buffer) WriteRune(r rune) (n int, err error)

WriteRune appends the UTF-8 encoding of Unicode code point r to the buffer. The purpose of this function is bytes.Buffer compatibility.

func (*Buffer) WriteString

func (b *Buffer) WriteString(s string) (int, error)

WriteString appends s to the underlying byte slice.

func (*Buffer) WriteStrings

func (b *Buffer) WriteStrings(s []string) (int, error)

WriteStrings appends a slice of strings to the underlying byte slice.

func (*Buffer) WriteTo

func (b *Buffer) WriteTo(w io.Writer) (int64, error)

WriteTo implements io.WriterTo.

type OffHeapArena added in v2.6.1

type OffHeapArena Arena

OffHeapArena is similar to Arena, except that it allocates memory directly from operating system instead of Go's runtime.

Note that after working with the memory chunks, user **MUST** call Free to return the memory to operating system, else memory leaks.

func NewCgoArena added in v2.6.1

func NewCgoArena(chunkSize int) *OffHeapArena

NewCgoArena creates an OffHeapArena which allocates memory by calling cgo `C.malloc`. cgo must be enabled to use this. The method Free frees allocated memory chunks. Free must be called after working with the arena to avoid memory leaks. After Free being called, both the arena and the byte slices allocated from the arena **MUST NOT** be touched again. chunkSize will be round up to the next power of two that is greater than or equal to the system's PAGE_SIZE.

func NewOffHeapArena added in v2.6.1

func NewOffHeapArena(chunkSize int) *OffHeapArena

NewOffHeapArena creates an OffHeapArena which allocates memory directly from operating system (without cgo). The method Free frees allocated memory chunks. Free must be called after working with the arena to avoid memory leaks. After Free being called, both the arena and the byte slices allocated from the arena **MUST NOT** be touched again. chunkSize will be round up to the next power of two that is greater than or equal to the system's PAGE_SIZE.

func (*OffHeapArena) Alloc added in v2.6.1

func (a *OffHeapArena) Alloc(length, capacity int) []byte

Alloc allocates small byte slice from the arena.

func (*OffHeapArena) Free added in v2.6.1

func (a *OffHeapArena) Free()

Free returns all memory chunks managed by the arena to the operating system.

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool is a byte buffer pool which reuses byte slice. It uses dynamic calibrating (which is a little atomic operations) to try best to match the workload.

Generally, if the size and capacity is known in advance, you may use the exported function Get(length, capacity) to get a properly sized byte buffer. However, if the buffer size is uncertain in advance, you may want to use this Pool. For different workloads, dedicated Pool instances are recommended, the dynamic calibrating will help to reduce memory waste.

All Pool instances share the same underlying sized byte slice pools. The byte buffers provided by Pool has a minimum limit of 64B and a maximum limit of 32MB, byte slice with size not in the range will be allocated directly from the operating system, and won't be recycled for reuse.

The zero value for Pool is ready to use. A Pool value shall not be copied after initialized.

func NewPool

func NewPool(r Recorder) *Pool

NewPool creates a new Pool instance using given Recorder.

In most cases, declaring a Pool variable is sufficient to initialize a Pool.

func (*Pool) Get

func (p *Pool) Get() []byte

Get returns a byte slice buffer from the pool. The returned buffer may be put back to the pool for reusing.

func (*Pool) GetBuffer

func (p *Pool) GetBuffer() *Buffer

GetBuffer returns a Buffer from the pool with dynamic calibrated default capacity. The returned Buffer may be put back to the pool for reusing.

func (*Pool) Put

func (p *Pool) Put(buf []byte)

Put puts back a byte slice buffer to the pool for reusing.

The buf mustn't be touched after returning it to the pool, otherwise data races will occur.

func (*Pool) PutBuffer

func (p *Pool) PutBuffer(buf *Buffer)

PutBuffer puts back a Buffer to the pool for reusing.

The buf mustn't be touched after returning it to the pool, otherwise, data races will occur.

type Recorder

type Recorder struct {

	// DefaultSize optionally configs the initial default size to be used.
	// Default is 1024 bytes.
	DefaultSize int

	// CalibrateInterval optionally configs the interval to do calibrating.
	// Default is 3 minutes.
	CalibrateInterval time.Duration

	// ResizePercentile optionally configs the percentile to reset the
	// default size when doing calibrating, the value should be in range
	// [50, 100). Default is 95.
	ResizePercentile int
	// contains filtered or unexported fields
}

Recorder helps to record most frequently used buffer size. It calibrates the recorded size data in running, thus it can dynamically adjust according to recent workload.

func (*Recorder) Record

func (p *Recorder) Record(n int)

Record records a used buffer size n.

The max recordable size is 32MB, if n is larger than 32MB, it records 32MB.

func (*Recorder) Size

func (p *Recorder) Size() int

Size returns the current most frequently used buffer size.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL