Documentation ¶
Overview ¶
Package iobuf performs explicit memory management for data buffers used to perform network IO. The intent is that it is more efficient to perform manual allocation than to rely on the Go garbage collector to manage large chunks of frequently recycled memory.
In this model, a Pool is a collection of contiguous memory area (of type <buf>) used for memory allocation. The bufs are subdivided into slices of type Slice.
Pool: a source of memory areas. Slice: a contiguous region of allocated memory. Allocator: a Slice allocator. Reader: an IO reader that reads into Slices.
There is an analogy with sbrk/malloc: the Pool is the source of memory (like sbrk), and the Allocator hands out small areas (like malloc). Allocations are mostly sequential within a buf, allowing sequentially-allocated Slices to be coalesced at some later point.
For efficiency, Slice values hold reference counts to the underlying buf. When all references are to a buf released, the buf is recycled into its Pool. This does not happen automatically. The caller is responsible for calling slice.Release() when finished using a slice.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Allocator ¶
type Allocator struct {
// contains filtered or unexported fields
}
Allocator is an allocator for Slices that tries to allocate contiguously. That is, sequential allocations will tend to be contiguous, which means that Coalesce() will usually be able to perform coalescing (without copying the data).
calloc := iobuf.Allocator(...) slice1 := calloc.Alloc(10) slice2 := calloc.Alloc(20) slices := iobuf.Coalesce([]*iobuf.Slice{slice1, slice2}) // slices should contain 1 element with length 30.
func NewAllocator ¶
NewAllocator returns a new Slice allocator.
<reserve> is the number of spare bytes to reserve at the beginning of each allocated Slice. This can be used to reserve space for a header, for example.
NOTE: It's a bit weird to set the number of reserve bytes in the NewAllocator call; it seems more natural in the Alloc call. But it's convenient to set it in NewAllocator, because in our use-cases, the code that calls Alloc doesn't know the number of reserve bytes.
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool manages a pool of iobufs. The size of the pool is not fixed, it can grow without bound.
The implementation here allocates a new iobuf whenever there is an allocation request and the pool is empty. For iobufs to be recycled, explicit Release() calls are required. However, if these Release() calls are missing, the program will continue to function, recycling the buffers through the gc. Therefore, if you forget Release() calls, you will be putting pressure on gc to recycle the iobufs. You can examine the <allocated> field to check how many iobufs have been allocated during the lifetime of the Pool.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader wraps an io.Reader to provide a buffered Read() operation.
type Slice ¶
type Slice struct { Contents []byte // iobuf.Contents[base:bound] // contains filtered or unexported fields }
Slice refers to an iobuf and the byte slice for the actual data.
func Coalesce ¶
Coalesce a sequence of slices. If two slices are adjacent, they are combined. Takes ownership of the slices, caller takes ownership of the result.
func NewSlice ¶
NewSlice creates a Slice from a byte array. The value is not copied into an iobuf, it continues to refer to the buffer that was passed in.
func (*Slice) ExpandFront ¶
ExpandFront tries to expand the Slice by <bytes> before the front of the Slice. Returns true if the Slice was expanded.
func (*Slice) FreeEntirePrefix ¶
func (slice *Slice) FreeEntirePrefix()
FreeEntirePrefix sets the free index to zero. Be careful when using this, you should ensure that no Slices are using the free region.
func (*Slice) Release ¶
func (slice *Slice) Release()
Release releases the slice, decrementing the reference count on the iobuf and destroying the slice.
func (*Slice) ReleasePrevious ¶
ReleasePrevious releases the <prev> slice, extending the free prefix of the target slice if possible.
func (*Slice) TruncateFront ¶
TruncateFront removes <bytes> from the front of the Slice.