Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
Testing / vet-proto (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s
131 lines
3.4 KiB
Go
131 lines
3.4 KiB
Go
/*
|
|
*
|
|
* Copyright 2026 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 "testing"
|
|
|
|
var defaultBufferPoolSizeExponents = []uint8{
|
|
8,
|
|
12,
|
|
14, // 16KB (max HTTP/2 frame size used by gRPC)
|
|
15, // 32KB (default buffer size for io.Copy)
|
|
20, // 1MB
|
|
}
|
|
|
|
func TestNewBinaryTieredBufferPool_WordSize(t *testing.T) {
|
|
origUintSize := uintSize
|
|
defer func() { uintSize = origUintSize }()
|
|
|
|
tests := []struct {
|
|
name string
|
|
wordSize int
|
|
exponents []uint8
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "32-bit_valid_exponent",
|
|
wordSize: 32,
|
|
exponents: []uint8{30},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "32-bit_invalid_exponent",
|
|
wordSize: 32,
|
|
exponents: []uint8{31},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "64-bit_valid_exponent",
|
|
wordSize: 64,
|
|
exponents: []uint8{62},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "64-bit_invalid_exponent",
|
|
wordSize: 64,
|
|
exponents: []uint8{63},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
uintSize = tt.wordSize
|
|
pool, err := NewBinaryTieredBufferPool(tt.exponents...)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Fatalf("NewBinaryTieredBufferPool() error = %t, wantErr %t", err, tt.wantErr)
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
if len(pool.exponentToNextLargestPoolMap) != tt.wordSize-1 {
|
|
t.Errorf("exponentToNextLargestPoolMap length = %d, want %d", len(pool.exponentToNextLargestPoolMap), tt.wordSize)
|
|
}
|
|
if len(pool.exponentToPreviousLargestPoolMap) != tt.wordSize-1 {
|
|
t.Errorf("exponentToPreviousLargestPoolMap length = %d, want %d", len(pool.exponentToPreviousLargestPoolMap), tt.wordSize)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// BenchmarkTieredPool benchmarks the performance of the tiered buffer pool
|
|
// implementations, specifically focusing on the overhead of selecting the
|
|
// correct bucket for a given size.
|
|
func BenchmarkTieredPool(b *testing.B) {
|
|
defaultBufferPoolSizes := make([]int, len(defaultBufferPoolSizeExponents))
|
|
for i, exp := range defaultBufferPoolSizeExponents {
|
|
defaultBufferPoolSizes[i] = 1 << exp
|
|
}
|
|
|
|
b.Run("pool=Tiered", func(b *testing.B) {
|
|
p := NewTieredBufferPool(defaultBufferPoolSizes...)
|
|
for b.Loop() {
|
|
for size := range 1 << 19 {
|
|
// One for get, one for put.
|
|
_ = p.getPool(size)
|
|
_ = p.getPool(size)
|
|
}
|
|
}
|
|
})
|
|
|
|
b.Run("pool=BinaryTiered", func(b *testing.B) {
|
|
pool, err := NewBinaryTieredBufferPool(defaultBufferPoolSizeExponents...)
|
|
if err != nil {
|
|
b.Fatalf("Failed to create buffer pool: %v", err)
|
|
}
|
|
for b.Loop() {
|
|
for size := range 1 << 19 {
|
|
_ = pool.poolForGet(size)
|
|
_ = pool.poolForPut(size)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestNewBinaryTieredBufferPool_Duplicates(t *testing.T) {
|
|
exponents := []uint8{1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1}
|
|
pool, err := NewBinaryTieredBufferPool(exponents...)
|
|
if err != nil {
|
|
t.Fatalf("NewBinaryTieredBufferPool() error = %v", err)
|
|
}
|
|
if len(pool.sizedPools) != 6 {
|
|
t.Errorf("sized buffer pool count = %d, want %d", len(pool.sizedPools), 6)
|
|
}
|
|
}
|