summaryrefslogtreecommitdiff
path: root/vendor/google.golang.org/grpc/mem
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/google.golang.org/grpc/mem')
-rw-r--r--vendor/google.golang.org/grpc/mem/buffer_pool.go194
-rw-r--r--vendor/google.golang.org/grpc/mem/buffer_slice.go281
-rw-r--r--vendor/google.golang.org/grpc/mem/buffers.go268
3 files changed, 0 insertions, 743 deletions
diff --git a/vendor/google.golang.org/grpc/mem/buffer_pool.go b/vendor/google.golang.org/grpc/mem/buffer_pool.go
deleted file mode 100644
index c37c58c02..000000000
--- a/vendor/google.golang.org/grpc/mem/buffer_pool.go
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- *
- * Copyright 2024 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package mem
-
-import (
- "sort"
- "sync"
-
- "google.golang.org/grpc/internal"
-)
-
-// BufferPool is a pool of buffers that can be shared and reused, resulting in
-// decreased memory allocation.
-type BufferPool interface {
- // Get returns a buffer with specified length from the pool.
- Get(length int) *[]byte
-
- // Put returns a buffer to the pool.
- Put(*[]byte)
-}
-
-var defaultBufferPoolSizes = []int{
- 256,
- 4 << 10, // 4KB (go page size)
- 16 << 10, // 16KB (max HTTP/2 frame size used by gRPC)
- 32 << 10, // 32KB (default buffer size for io.Copy)
- 1 << 20, // 1MB
-}
-
-var defaultBufferPool BufferPool
-
-func init() {
- defaultBufferPool = NewTieredBufferPool(defaultBufferPoolSizes...)
-
- internal.SetDefaultBufferPoolForTesting = func(pool BufferPool) {
- defaultBufferPool = pool
- }
-
- internal.SetBufferPoolingThresholdForTesting = func(threshold int) {
- bufferPoolingThreshold = threshold
- }
-}
-
-// DefaultBufferPool returns the current default buffer pool. It is a BufferPool
-// created with NewBufferPool that uses a set of default sizes optimized for
-// expected workflows.
-func DefaultBufferPool() BufferPool {
- return defaultBufferPool
-}
-
-// NewTieredBufferPool returns a BufferPool implementation that uses multiple
-// underlying pools of the given pool sizes.
-func NewTieredBufferPool(poolSizes ...int) BufferPool {
- sort.Ints(poolSizes)
- pools := make([]*sizedBufferPool, len(poolSizes))
- for i, s := range poolSizes {
- pools[i] = newSizedBufferPool(s)
- }
- return &tieredBufferPool{
- sizedPools: pools,
- }
-}
-
-// tieredBufferPool implements the BufferPool interface with multiple tiers of
-// buffer pools for different sizes of buffers.
-type tieredBufferPool struct {
- sizedPools []*sizedBufferPool
- fallbackPool simpleBufferPool
-}
-
-func (p *tieredBufferPool) Get(size int) *[]byte {
- return p.getPool(size).Get(size)
-}
-
-func (p *tieredBufferPool) Put(buf *[]byte) {
- p.getPool(cap(*buf)).Put(buf)
-}
-
-func (p *tieredBufferPool) getPool(size int) BufferPool {
- poolIdx := sort.Search(len(p.sizedPools), func(i int) bool {
- return p.sizedPools[i].defaultSize >= size
- })
-
- if poolIdx == len(p.sizedPools) {
- return &p.fallbackPool
- }
-
- return p.sizedPools[poolIdx]
-}
-
-// sizedBufferPool is a BufferPool implementation that is optimized for specific
-// buffer sizes. For example, HTTP/2 frames within gRPC have a default max size
-// of 16kb and a sizedBufferPool can be configured to only return buffers with a
-// capacity of 16kb. Note that however it does not support returning larger
-// buffers and in fact panics if such a buffer is requested. Because of this,
-// this BufferPool implementation is not meant to be used on its own and rather
-// is intended to be embedded in a tieredBufferPool such that Get is only
-// invoked when the required size is smaller than or equal to defaultSize.
-type sizedBufferPool struct {
- pool sync.Pool
- defaultSize int
-}
-
-func (p *sizedBufferPool) Get(size int) *[]byte {
- buf := p.pool.Get().(*[]byte)
- b := *buf
- clear(b[:cap(b)])
- *buf = b[:size]
- return buf
-}
-
-func (p *sizedBufferPool) Put(buf *[]byte) {
- if cap(*buf) < p.defaultSize {
- // Ignore buffers that are too small to fit in the pool. Otherwise, when
- // Get is called it will panic as it tries to index outside the bounds
- // of the buffer.
- return
- }
- p.pool.Put(buf)
-}
-
-func newSizedBufferPool(size int) *sizedBufferPool {
- return &sizedBufferPool{
- pool: sync.Pool{
- New: func() any {
- buf := make([]byte, size)
- return &buf
- },
- },
- defaultSize: size,
- }
-}
-
-var _ BufferPool = (*simpleBufferPool)(nil)
-
-// simpleBufferPool is an implementation of the BufferPool interface that
-// attempts to pool buffers with a sync.Pool. When Get is invoked, it tries to
-// acquire a buffer from the pool but if that buffer is too small, it returns it
-// to the pool and creates a new one.
-type simpleBufferPool struct {
- pool sync.Pool
-}
-
-func (p *simpleBufferPool) Get(size int) *[]byte {
- bs, ok := p.pool.Get().(*[]byte)
- if ok && cap(*bs) >= size {
- *bs = (*bs)[:size]
- return bs
- }
-
- // A buffer was pulled from the pool, but it is too small. Put it back in
- // the pool and create one large enough.
- if ok {
- p.pool.Put(bs)
- }
-
- b := make([]byte, size)
- return &b
-}
-
-func (p *simpleBufferPool) Put(buf *[]byte) {
- p.pool.Put(buf)
-}
-
-var _ BufferPool = NopBufferPool{}
-
-// NopBufferPool is a buffer pool that returns new buffers without pooling.
-type NopBufferPool struct{}
-
-// Get returns a buffer with specified length from the pool.
-func (NopBufferPool) Get(length int) *[]byte {
- b := make([]byte, length)
- return &b
-}
-
-// Put returns a buffer to the pool.
-func (NopBufferPool) Put(*[]byte) {
-}
diff --git a/vendor/google.golang.org/grpc/mem/buffer_slice.go b/vendor/google.golang.org/grpc/mem/buffer_slice.go
deleted file mode 100644
index 65002e2cc..000000000
--- a/vendor/google.golang.org/grpc/mem/buffer_slice.go
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *
- * Copyright 2024 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package mem
-
-import (
- "io"
-)
-
-const (
- // 32 KiB is what io.Copy uses.
- readAllBufSize = 32 * 1024
-)
-
-// BufferSlice offers a means to represent data that spans one or more Buffer
-// instances. A BufferSlice is meant to be immutable after creation, and methods
-// like Ref create and return copies of the slice. This is why all methods have
-// value receivers rather than pointer receivers.
-//
-// Note that any of the methods that read the underlying buffers such as Ref,
-// Len or CopyTo etc., will panic if any underlying buffers have already been
-// freed. It is recommended to not directly interact with any of the underlying
-// buffers directly, rather such interactions should be mediated through the
-// various methods on this type.
-//
-// By convention, any APIs that return (mem.BufferSlice, error) should reduce
-// the burden on the caller by never returning a mem.BufferSlice that needs to
-// be freed if the error is non-nil, unless explicitly stated.
-type BufferSlice []Buffer
-
-// Len returns the sum of the length of all the Buffers in this slice.
-//
-// # Warning
-//
-// Invoking the built-in len on a BufferSlice will return the number of buffers
-// in the slice, and *not* the value returned by this function.
-func (s BufferSlice) Len() int {
- var length int
- for _, b := range s {
- length += b.Len()
- }
- return length
-}
-
-// Ref invokes Ref on each buffer in the slice.
-func (s BufferSlice) Ref() {
- for _, b := range s {
- b.Ref()
- }
-}
-
-// Free invokes Buffer.Free() on each Buffer in the slice.
-func (s BufferSlice) Free() {
- for _, b := range s {
- b.Free()
- }
-}
-
-// CopyTo copies each of the underlying Buffer's data into the given buffer,
-// returning the number of bytes copied. Has the same semantics as the copy
-// builtin in that it will copy as many bytes as it can, stopping when either dst
-// is full or s runs out of data, returning the minimum of s.Len() and len(dst).
-func (s BufferSlice) CopyTo(dst []byte) int {
- off := 0
- for _, b := range s {
- off += copy(dst[off:], b.ReadOnlyData())
- }
- return off
-}
-
-// Materialize concatenates all the underlying Buffer's data into a single
-// contiguous buffer using CopyTo.
-func (s BufferSlice) Materialize() []byte {
- l := s.Len()
- if l == 0 {
- return nil
- }
- out := make([]byte, l)
- s.CopyTo(out)
- return out
-}
-
-// MaterializeToBuffer functions like Materialize except that it writes the data
-// to a single Buffer pulled from the given BufferPool.
-//
-// As a special case, if the input BufferSlice only actually has one Buffer, this
-// function simply increases the refcount before returning said Buffer. Freeing this
-// buffer won't release it until the BufferSlice is itself released.
-func (s BufferSlice) MaterializeToBuffer(pool BufferPool) Buffer {
- if len(s) == 1 {
- s[0].Ref()
- return s[0]
- }
- sLen := s.Len()
- if sLen == 0 {
- return emptyBuffer{}
- }
- buf := pool.Get(sLen)
- s.CopyTo(*buf)
- return NewBuffer(buf, pool)
-}
-
-// Reader returns a new Reader for the input slice after taking references to
-// each underlying buffer.
-func (s BufferSlice) Reader() Reader {
- s.Ref()
- return &sliceReader{
- data: s,
- len: s.Len(),
- }
-}
-
-// Reader exposes a BufferSlice's data as an io.Reader, allowing it to interface
-// with other parts systems. It also provides an additional convenience method
-// Remaining(), which returns the number of unread bytes remaining in the slice.
-// Buffers will be freed as they are read.
-type Reader interface {
- io.Reader
- io.ByteReader
- // Close frees the underlying BufferSlice and never returns an error. Subsequent
- // calls to Read will return (0, io.EOF).
- Close() error
- // Remaining returns the number of unread bytes remaining in the slice.
- Remaining() int
-}
-
-type sliceReader struct {
- data BufferSlice
- len int
- // The index into data[0].ReadOnlyData().
- bufferIdx int
-}
-
-func (r *sliceReader) Remaining() int {
- return r.len
-}
-
-func (r *sliceReader) Close() error {
- r.data.Free()
- r.data = nil
- r.len = 0
- return nil
-}
-
-func (r *sliceReader) freeFirstBufferIfEmpty() bool {
- if len(r.data) == 0 || r.bufferIdx != len(r.data[0].ReadOnlyData()) {
- return false
- }
-
- r.data[0].Free()
- r.data = r.data[1:]
- r.bufferIdx = 0
- return true
-}
-
-func (r *sliceReader) Read(buf []byte) (n int, _ error) {
- if r.len == 0 {
- return 0, io.EOF
- }
-
- for len(buf) != 0 && r.len != 0 {
- // Copy as much as possible from the first Buffer in the slice into the
- // given byte slice.
- data := r.data[0].ReadOnlyData()
- copied := copy(buf, data[r.bufferIdx:])
- r.len -= copied // Reduce len by the number of bytes copied.
- r.bufferIdx += copied // Increment the buffer index.
- n += copied // Increment the total number of bytes read.
- buf = buf[copied:] // Shrink the given byte slice.
-
- // If we have copied all the data from the first Buffer, free it and advance to
- // the next in the slice.
- r.freeFirstBufferIfEmpty()
- }
-
- return n, nil
-}
-
-func (r *sliceReader) ReadByte() (byte, error) {
- if r.len == 0 {
- return 0, io.EOF
- }
-
- // There may be any number of empty buffers in the slice, clear them all until a
- // non-empty buffer is reached. This is guaranteed to exit since r.len is not 0.
- for r.freeFirstBufferIfEmpty() {
- }
-
- b := r.data[0].ReadOnlyData()[r.bufferIdx]
- r.len--
- r.bufferIdx++
- // Free the first buffer in the slice if the last byte was read
- r.freeFirstBufferIfEmpty()
- return b, nil
-}
-
-var _ io.Writer = (*writer)(nil)
-
-type writer struct {
- buffers *BufferSlice
- pool BufferPool
-}
-
-func (w *writer) Write(p []byte) (n int, err error) {
- b := Copy(p, w.pool)
- *w.buffers = append(*w.buffers, b)
- return b.Len(), nil
-}
-
-// NewWriter wraps the given BufferSlice and BufferPool to implement the
-// io.Writer interface. Every call to Write copies the contents of the given
-// buffer into a new Buffer pulled from the given pool and the Buffer is
-// added to the given BufferSlice.
-func NewWriter(buffers *BufferSlice, pool BufferPool) io.Writer {
- return &writer{buffers: buffers, pool: pool}
-}
-
-// ReadAll reads from r until an error or EOF and returns the data it read.
-// A successful call returns err == nil, not err == EOF. Because ReadAll is
-// defined to read from src until EOF, it does not treat an EOF from Read
-// as an error to be reported.
-//
-// Important: A failed call returns a non-nil error and may also return
-// partially read buffers. It is the responsibility of the caller to free the
-// BufferSlice returned, or its memory will not be reused.
-func ReadAll(r io.Reader, pool BufferPool) (BufferSlice, error) {
- var result BufferSlice
- if wt, ok := r.(io.WriterTo); ok {
- // This is more optimal since wt knows the size of chunks it wants to
- // write and, hence, we can allocate buffers of an optimal size to fit
- // them. E.g. might be a single big chunk, and we wouldn't chop it
- // into pieces.
- w := NewWriter(&result, pool)
- _, err := wt.WriteTo(w)
- return result, err
- }
-nextBuffer:
- for {
- buf := pool.Get(readAllBufSize)
- // We asked for 32KiB but may have been given a bigger buffer.
- // Use all of it if that's the case.
- *buf = (*buf)[:cap(*buf)]
- usedCap := 0
- for {
- n, err := r.Read((*buf)[usedCap:])
- usedCap += n
- if err != nil {
- if usedCap == 0 {
- // Nothing in this buf, put it back
- pool.Put(buf)
- } else {
- *buf = (*buf)[:usedCap]
- result = append(result, NewBuffer(buf, pool))
- }
- if err == io.EOF {
- err = nil
- }
- return result, err
- }
- if len(*buf) == usedCap {
- result = append(result, NewBuffer(buf, pool))
- continue nextBuffer
- }
- }
- }
-}
diff --git a/vendor/google.golang.org/grpc/mem/buffers.go b/vendor/google.golang.org/grpc/mem/buffers.go
deleted file mode 100644
index ecbf0b9a7..000000000
--- a/vendor/google.golang.org/grpc/mem/buffers.go
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- *
- * Copyright 2024 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// Package mem provides utilities that facilitate memory reuse in byte slices
-// that are used as buffers.
-//
-// # Experimental
-//
-// Notice: All APIs in this package are EXPERIMENTAL and may be changed or
-// removed in a later release.
-package mem
-
-import (
- "fmt"
- "sync"
- "sync/atomic"
-)
-
-// A Buffer represents a reference counted piece of data (in bytes) that can be
-// acquired by a call to NewBuffer() or Copy(). A reference to a Buffer may be
-// released by calling Free(), which invokes the free function given at creation
-// only after all references are released.
-//
-// Note that a Buffer is not safe for concurrent access and instead each
-// goroutine should use its own reference to the data, which can be acquired via
-// a call to Ref().
-//
-// Attempts to access the underlying data after releasing the reference to the
-// Buffer will panic.
-type Buffer interface {
- // ReadOnlyData returns the underlying byte slice. Note that it is undefined
- // behavior to modify the contents of this slice in any way.
- ReadOnlyData() []byte
- // Ref increases the reference counter for this Buffer.
- Ref()
- // Free decrements this Buffer's reference counter and frees the underlying
- // byte slice if the counter reaches 0 as a result of this call.
- Free()
- // Len returns the Buffer's size.
- Len() int
-
- split(n int) (left, right Buffer)
- read(buf []byte) (int, Buffer)
-}
-
-var (
- bufferPoolingThreshold = 1 << 10
-
- bufferObjectPool = sync.Pool{New: func() any { return new(buffer) }}
- refObjectPool = sync.Pool{New: func() any { return new(atomic.Int32) }}
-)
-
-// IsBelowBufferPoolingThreshold returns true if the given size is less than or
-// equal to the threshold for buffer pooling. This is used to determine whether
-// to pool buffers or allocate them directly.
-func IsBelowBufferPoolingThreshold(size int) bool {
- return size <= bufferPoolingThreshold
-}
-
-type buffer struct {
- origData *[]byte
- data []byte
- refs *atomic.Int32
- pool BufferPool
-}
-
-func newBuffer() *buffer {
- return bufferObjectPool.Get().(*buffer)
-}
-
-// NewBuffer creates a new Buffer from the given data, initializing the reference
-// counter to 1. The data will then be returned to the given pool when all
-// references to the returned Buffer are released. As a special case to avoid
-// additional allocations, if the given buffer pool is nil, the returned buffer
-// will be a "no-op" Buffer where invoking Buffer.Free() does nothing and the
-// underlying data is never freed.
-//
-// Note that the backing array of the given data is not copied.
-func NewBuffer(data *[]byte, pool BufferPool) Buffer {
- // Use the buffer's capacity instead of the length, otherwise buffers may
- // not be reused under certain conditions. For example, if a large buffer
- // is acquired from the pool, but fewer bytes than the buffering threshold
- // are written to it, the buffer will not be returned to the pool.
- if pool == nil || IsBelowBufferPoolingThreshold(cap(*data)) {
- return (SliceBuffer)(*data)
- }
- b := newBuffer()
- b.origData = data
- b.data = *data
- b.pool = pool
- b.refs = refObjectPool.Get().(*atomic.Int32)
- b.refs.Add(1)
- return b
-}
-
-// Copy creates a new Buffer from the given data, initializing the reference
-// counter to 1.
-//
-// It acquires a []byte from the given pool and copies over the backing array
-// of the given data. The []byte acquired from the pool is returned to the
-// pool when all references to the returned Buffer are released.
-func Copy(data []byte, pool BufferPool) Buffer {
- if IsBelowBufferPoolingThreshold(len(data)) {
- buf := make(SliceBuffer, len(data))
- copy(buf, data)
- return buf
- }
-
- buf := pool.Get(len(data))
- copy(*buf, data)
- return NewBuffer(buf, pool)
-}
-
-func (b *buffer) ReadOnlyData() []byte {
- if b.refs == nil {
- panic("Cannot read freed buffer")
- }
- return b.data
-}
-
-func (b *buffer) Ref() {
- if b.refs == nil {
- panic("Cannot ref freed buffer")
- }
- b.refs.Add(1)
-}
-
-func (b *buffer) Free() {
- if b.refs == nil {
- panic("Cannot free freed buffer")
- }
-
- refs := b.refs.Add(-1)
- switch {
- case refs > 0:
- return
- case refs == 0:
- if b.pool != nil {
- b.pool.Put(b.origData)
- }
-
- refObjectPool.Put(b.refs)
- b.origData = nil
- b.data = nil
- b.refs = nil
- b.pool = nil
- bufferObjectPool.Put(b)
- default:
- panic("Cannot free freed buffer")
- }
-}
-
-func (b *buffer) Len() int {
- return len(b.ReadOnlyData())
-}
-
-func (b *buffer) split(n int) (Buffer, Buffer) {
- if b.refs == nil {
- panic("Cannot split freed buffer")
- }
-
- b.refs.Add(1)
- split := newBuffer()
- split.origData = b.origData
- split.data = b.data[n:]
- split.refs = b.refs
- split.pool = b.pool
-
- b.data = b.data[:n]
-
- return b, split
-}
-
-func (b *buffer) read(buf []byte) (int, Buffer) {
- if b.refs == nil {
- panic("Cannot read freed buffer")
- }
-
- n := copy(buf, b.data)
- if n == len(b.data) {
- b.Free()
- return n, nil
- }
-
- b.data = b.data[n:]
- return n, b
-}
-
-func (b *buffer) String() string {
- return fmt.Sprintf("mem.Buffer(%p, data: %p, length: %d)", b, b.ReadOnlyData(), len(b.ReadOnlyData()))
-}
-
-// ReadUnsafe reads bytes from the given Buffer into the provided slice.
-// It does not perform safety checks.
-func ReadUnsafe(dst []byte, buf Buffer) (int, Buffer) {
- return buf.read(dst)
-}
-
-// SplitUnsafe modifies the receiver to point to the first n bytes while it
-// returns a new reference to the remaining bytes. The returned Buffer
-// functions just like a normal reference acquired using Ref().
-func SplitUnsafe(buf Buffer, n int) (left, right Buffer) {
- return buf.split(n)
-}
-
-type emptyBuffer struct{}
-
-func (e emptyBuffer) ReadOnlyData() []byte {
- return nil
-}
-
-func (e emptyBuffer) Ref() {}
-func (e emptyBuffer) Free() {}
-
-func (e emptyBuffer) Len() int {
- return 0
-}
-
-func (e emptyBuffer) split(int) (left, right Buffer) {
- return e, e
-}
-
-func (e emptyBuffer) read([]byte) (int, Buffer) {
- return 0, e
-}
-
-// SliceBuffer is a Buffer implementation that wraps a byte slice. It provides
-// methods for reading, splitting, and managing the byte slice.
-type SliceBuffer []byte
-
-// ReadOnlyData returns the byte slice.
-func (s SliceBuffer) ReadOnlyData() []byte { return s }
-
-// Ref is a noop implementation of Ref.
-func (s SliceBuffer) Ref() {}
-
-// Free is a noop implementation of Free.
-func (s SliceBuffer) Free() {}
-
-// Len is a noop implementation of Len.
-func (s SliceBuffer) Len() int { return len(s) }
-
-func (s SliceBuffer) split(n int) (left, right Buffer) {
- return s[:n], s[n:]
-}
-
-func (s SliceBuffer) read(buf []byte) (int, Buffer) {
- n := copy(buf, s)
- if n == len(s) {
- return n, nil
- }
- return n, s[n:]
-}