summaryrefslogtreecommitdiff
path: root/vendor/google.golang.org/grpc/mem/buffers.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/google.golang.org/grpc/mem/buffers.go')
-rw-r--r--vendor/google.golang.org/grpc/mem/buffers.go268
1 files changed, 0 insertions, 268 deletions
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:]
-}