pool

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: May 21, 2019 License: MIT Imports: 5 Imported by: 321

README

go-buffer-pool

codecov Travis CI Discourse posts

A variable size buffer pool for go.

Table of Contents

Use Case

Use this when you need to repeatedly allocate and free a bunch of temporary buffers of approximately the same size.

Advantages over GC
  • Reduces Memory Usage:

    • We don't have to wait for a GC to run before we can reuse memory. This is essential if you're repeatedly allocating large short-lived buffers.
  • Reduces CPU usage:

    • It takes some load off of the GC (due to buffer reuse).
    • We don't have to zero buffers (fewer wasteful memory writes).
Disadvantages over GC:
  • Can leak memory contents. Unlike the go GC, we don't zero memory.
  • All buffers have a capacity of a power of 2. This is fine if you either (a) actually need buffers with this size or (b) expect these buffers to be temporary.
  • Requires that buffers be returned explicitly. This can lead to race conditions and memory corruption if the buffer is released while it's still in use.

Contribute

PRs are welcome!

Small note: If editing the Readme, please conform to the standard-readme specification.

License

MIT © Protocol Labs BSD © The Go Authors


The last gx published version of this module was: 0.1.3: QmQDvJoB6aJWN3sjr3xsgXqKCXf4jU5zdMXpDMsBkYVNqa

Documentation

Overview

Package pool provides a sync.Pool equivalent that buckets incoming requests to one of 32 sub-pools, one for each power of 2, 0-32.

import (pool "github.com/libp2p/go-buffer-pool")
var p pool.BufferPool

small := make([]byte, 1024)
large := make([]byte, 4194304)
p.Put(small)
p.Put(large)

small2 := p.Get(1024)
large2 := p.Get(4194304)
fmt.Println("small2 len:", len(small2))
fmt.Println("large2 len:", len(large2))

// Output:
// small2 len: 1024
// large2 len: 4194304

Index

Examples

Constants

View Source
const MaxLength = math.MaxInt32

MaxLength is the maximum length of an element that can be added to the Pool.

View Source
const MinRead = 512

MinRead is the minimum slice size passed to a Read call by Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond what is required to hold the contents of r, ReadFrom will not grow the underlying buffer.

View Source
const WriterBufferSize = 4096

Variables

View Source
var GlobalPool = new(BufferPool)

GlobalPool is a static Pool for reusing byteslices of various sizes.

Functions

func Get

func Get(length int) []byte

Get retrieves a buffer of the appropriate length from the global buffer pool (or allocates a new one).

Example
buf := Get(100)
fmt.Println("length", len(buf))
fmt.Println("capacity", cap(buf))
Put(buf)
Output:

length 100
capacity 128

func Put

func Put(slice []byte)

Put returns a buffer to the global buffer pool.

Types

type Buffer

type Buffer struct {
	// Pool is the buffer pool to use. If nil, this Buffer will use the
	// global buffer pool.
	Pool *BufferPool
	// contains filtered or unexported fields
}

Buffer is a buffer like bytes.Buffer that:

1. Uses a buffer pool. 2. Frees memory on read.

If you only have a few buffers and read/write at a steady rate, *don't* use this package, it'll be slower.

However:

  1. If you frequently create/destroy buffers, this implementation will be significantly nicer to the allocator.
  2. If you have many buffers with bursty traffic, this implementation will use significantly less memory.

func NewBuffer

func NewBuffer(buf []byte) *Buffer

NewBuffer constructs a new buffer initialized to `buf`. Unlike `bytes.Buffer`, we *copy* the buffer but don't reuse it (to ensure that we *only* use buffers from the pool).

func NewBufferString

func NewBufferString(buf string) *Buffer

NewBufferString is identical to NewBuffer *except* that it allows one to initialize the buffer from a string (without having to allocate an intermediate bytes slice).

func (*Buffer) Bytes

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

Bytes returns the slice of bytes currently buffered in the Buffer.

The buffer returned by Bytes is valid until the next call grow, truncate, read, or write. Really, just don't touch the Buffer until you're done with the return value of this function.

func (*Buffer) Cap

func (b *Buffer) Cap() int

Cap returns the current capacity of the buffer.

Note: Buffer *may* re-allocate when writing (or growing by) `n` bytes even if `Cap() < Len() + n` to avoid excessive copying.

func (*Buffer) Grow

func (b *Buffer) Grow(n int)

Grow grows the internal buffer such that `n` bytes can be written without reallocating.

func (*Buffer) Len

func (b *Buffer) Len() int

Len returns the number of bytes that can be read from this buffer.

func (*Buffer) Next

func (b *Buffer) Next(n int) []byte

Next is an alternative to `Read` that returns a byte slice instead of taking one.

The returned byte slice is valid until the next read, write, grow, or truncate.

func (*Buffer) Read

func (b *Buffer) Read(buf []byte) (int, error)

Read reads at most `len(buf)` bytes from the internal buffer into the given buffer.

func (*Buffer) ReadByte

func (b *Buffer) ReadByte() (byte, error)

ReadByte reads a single byte from the Buffer.

func (*Buffer) ReadFrom

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

ReadFrom reads from the given reader into the buffer.

func (*Buffer) Reset

func (b *Buffer) Reset()

Reset is equivalent to Truncate(0).

func (*Buffer) String

func (b *Buffer) String() string

String returns the string representation of the buffer.

It returns `<nil>` the buffer is a nil pointer.

func (*Buffer) Truncate

func (b *Buffer) Truncate(n int)

Truncate truncates the Buffer.

Panics if `n > b.Len()`.

This function may free memory by shrinking the internal buffer.

func (*Buffer) Write

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

Write writes the byte slice to the buffer.

func (*Buffer) WriteByte

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

WriteByte writes a single byte to the Buffer.

func (*Buffer) WriteString

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

WriteString writes a string to the buffer.

This function is identical to Write except that it allows one to write a string directly without allocating an intermediate byte slice.

func (*Buffer) WriteTo

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

WriteTo copies from the buffer into the given writer until the buffer is empty.

type BufferPool

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

BufferPool is a pool to handle cases of reusing elements of varying sizes. It maintains 32 internal pools, for each power of 2 in 0-32.

You should generally just call the package level Get and Put methods or use the GlobalPool BufferPool instead of constructing your own.

You MUST NOT copy Pool after using.

func (*BufferPool) Get

func (p *BufferPool) Get(length int) []byte

Get retrieves a buffer of the appropriate length from the buffer pool or allocates a new one. Get may choose to ignore the pool and treat it as empty. Callers should not assume any relation between values passed to Put and the values returned by Get.

If no suitable buffer exists in the pool, Get creates one.

func (*BufferPool) Put

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

Put adds x to the pool.

type Writer added in v0.0.2

type Writer struct {
	W io.Writer
	// contains filtered or unexported fields
}

Writer is a buffered writer that returns its internal buffer in a pool when not in use.

func (*Writer) Available added in v0.0.2

func (w *Writer) Available() int

Available returns the amount buffer space available.

func (*Writer) Buffered added in v0.0.2

func (w *Writer) Buffered() int

Buffered returns the amount of data buffered.

func (*Writer) Close added in v0.0.2

func (w *Writer) Close() error

Close flushes the underlying writer and closes it if it implements the io.Closer interface.

Note: Close() closes the writer even if Flush() fails to avoid leaking system resources. If you want to make sure Flush() succeeds, call it first.

func (*Writer) Flush added in v0.0.2

func (w *Writer) Flush() error

Flush flushes the write buffer, if any, and returns it to the pool.

func (*Writer) Size added in v0.0.2

func (w *Writer) Size() int

Size returns the size of the underlying buffer.

func (*Writer) Write added in v0.0.2

func (w *Writer) Write(b []byte) (int, error)

Write writes the given byte slice to the underlying connection.

Note: Write won't return the write buffer to the pool even if it ends up being empty after the write. You must call Flush() to do that.

func (*Writer) WriteByte added in v0.0.2

func (w *Writer) WriteByte(b byte) error

WriteByte writes a single byte.

func (*Writer) WriteRune added in v0.0.2

func (w *Writer) WriteRune(r rune) (int, error)

WriteRune writes a single rune, returning the number of bytes written.

func (*Writer) WriteString added in v0.0.2

func (w *Writer) WriteString(s string) (int, error)

WriteString writes a string, returning the number of bytes written.

Jump to

Keyboard shortcuts

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