Documentation
¶
Overview ¶
Package bufpool provides pooled, reusable byte buffers that reduce allocations and garbage-collector pressure in code handling many short-lived buffers.
A Buffer implements io.Reader, io.Writer, io.StringWriter, io.ReaderFrom, io.WriterTo, io.Closer and fmt.Stringer. Writes append to the buffer; reads consume it from the front, tracked by an internal read position. Buffers obtained from a Pool (whose zero value is ready to use) are returned to it with Release (or Close), after which they must not be used.
Releasing transfers the backing array back to the pool, so slices obtained through Bytes or ReadAllBytes are invalidated by Release, Close and Reset; conversely, slices handed to NewBuffer or SetBytes are adopted as the buffer's backing array (and follow it into the pool when it is released), so the caller must not use them afterwards.
To keep pooled memory bounded, an adaptive strike heuristic decides on each Release or Reset whether a buffer's backing array is worth keeping: arrays of at most 64 KiB, or at least 50% utilized, are always kept; an oversized, under-utilized array survives up to four consecutive strikes before it is discarded. This prevents a single large usage from pinning memory through a continuous stream of small ones.
Adapted from https://github.com/golang/go/issues/27735#issuecomment-739169121.
Index ¶
- func ReadAllBytes(r io.Reader) ([]byte, error)
- type Buffer
- func (b *Buffer) Bytes() []byte
- func (b *Buffer) Cap() int
- func (b *Buffer) Close() error
- func (b *Buffer) Detach()
- func (b *Buffer) Grow(n int)
- func (b *Buffer) Len() int
- func (b *Buffer) Read(p []byte) (int, error)
- func (b *Buffer) ReadFrom(r io.Reader) (int64, error)
- func (b *Buffer) Release()
- func (b *Buffer) Reset()
- func (b *Buffer) Rewind()
- func (b *Buffer) SetBytes(p []byte)
- func (b *Buffer) Size() int
- func (b *Buffer) String() string
- func (b *Buffer) Write(p []byte) (int, error)
- func (b *Buffer) WriteString(s string) (int, error)
- func (b *Buffer) WriteTo(w io.Writer) (int64, error)
- type Pool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ReadAllBytes ¶
ReadAllBytes reads all remaining bytes from r. If r is a *Buffer, it returns the buffer's unread bytes directly without copying and advances the buffer to EOF; otherwise it falls back to io.ReadAll. The error is nil on success, mirroring io.ReadAll.
Regardless of r's dynamic type, treat the returned slice as aliasing r's internal storage: it is only valid until r is next written to, reset, released or closed. Copy it if it must outlive r.
Types ¶
type Buffer ¶
type Buffer struct {
// contains filtered or unexported fields
}
Buffer is a byte buffer that may be attached to a Pool. It implements io.Reader, io.Writer, io.StringWriter, io.ReaderFrom, io.WriterTo, io.Closer and fmt.Stringer. Writes append to the buffer; reads consume it from the front, tracked by an internal read position. The zero value is a usable, detached buffer.
A Buffer must not be copied after first use (go vet reports such copies), and must not be used after Release or Close.
func NewBuffer ¶
NewBuffer creates a new detached buffer whose initial contents are data. The slice becomes the buffer's backing array; it is not copied, and the caller should not use data after this call. NewBuffer(nil) creates an empty buffer.
func (*Buffer) Bytes ¶
Bytes returns the unread portion of the buffer. The slice aliases the buffer's backing array and is only valid until the next mutating call; Release, Close and Reset invalidate it. Copy the bytes (or use String) if they must outlive the buffer.
func (*Buffer) Cap ¶
Cap returns the capacity of the buffer's backing array: the total space, including the already-written portion, that can be used before another allocation.
func (*Buffer) Close ¶
Close returns the buffer to its pool and always returns a nil error. It implements io.Closer and is equivalent to Release, so a pooled *Buffer can be handed off as an io.ReadCloser and is returned to the pool at the release site without a pool reference in scope.
func (*Buffer) Detach ¶
func (b *Buffer) Detach()
Detach detaches the buffer from its pool, making Release and Close no-ops. Use it to let a buffer's contents safely outlive a consumer that closes it.
func (*Buffer) Grow ¶
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 without another allocation. Grow panics if n is negative or if the buffer would grow beyond the maximum slice length.
func (*Buffer) Len ¶
Len returns the number of unread bytes in the buffer, matching the semantics of bytes.Buffer.Len. Use Size for the total written length.
func (*Buffer) Read ¶
Read consumes up to len(p) unread bytes into p, advancing the read position. It returns io.EOF once the buffer is fully consumed. Read implements io.Reader.
func (*Buffer) ReadFrom ¶
ReadFrom reads from r until EOF, appending to the buffer and growing it as needed. It returns the number of bytes read and any error except io.EOF encountered during the read. ReadFrom implements io.ReaderFrom, so io.Copy into a Buffer needs no intermediate copy buffer.
func (*Buffer) Release ¶
func (b *Buffer) Release()
Release returns the buffer to its pool and resets it to the zero value. Releasing invalidates all slices previously returned by Bytes or ReadAllBytes: the backing array re-enters the pool and the next Get may overwrite it, so copy such slices first if they must outlive the buffer. After Release the buffer is a detached zero buffer — further calls operate on that empty buffer instead of panicking, but are programming errors. If the buffer is detached, Release is a no-op. The cost of a Get/Release round-trip is the single small allocation of the Buffer handle in Get.
func (*Buffer) Reset ¶
func (b *Buffer) Reset()
Reset rewinds the read position and truncates the buffer for in-place reuse, applying the same keep-or-discard heuristic the pool uses on Release: an oversized, repeatedly under-utilized backing array is dropped (replaced with a fresh nil buffer) instead of kept, so a single large use does not pin memory across resets. Unlike Release, the buffer stays usable and attached to its pool.
func (*Buffer) Rewind ¶
func (b *Buffer) Rewind()
Rewind resets the read position to zero so the buffer's full contents can be read again. It does not modify the contents.
func (*Buffer) SetBytes ¶
SetBytes replaces the buffer's contents with p and rewinds the read position. The slice becomes the new backing array; it is not copied, so ownership of p transfers to the buffer (and, once released, to its pool) and the caller must not use p after this call.
func (*Buffer) Size ¶
Size returns the total length of the buffer, including any portion already consumed by Read.
func (*Buffer) String ¶
String returns a copy of the unread portion of the buffer as a string, implementing fmt.Stringer. If b is nil, it returns "<nil>".
func (*Buffer) Write ¶
Write appends p to the buffer, growing the backing array as needed. It always returns len(p) and a nil error. Write implements io.Writer.
func (*Buffer) WriteString ¶
WriteString appends s to the buffer without copying it into a temporary []byte first. It always returns len(s) and a nil error. WriteString implements io.StringWriter.